external/boringssl: Sync to d18cb77.

This includes the following changes which are far too many to list here:

https://boringssl.googlesource.com/boringssl/+log/7b8b9c17db93ea5287575b437c77fb36eeb81b31..d18cb77864dcc4b5c7cb08c2331008c01165f34f

This also retires one function from android_compat_hacks.c which is no longer
necessary.

Change-Id: Ie00536d7ad815464b2b031f7bcd1b683e12c1623
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 6e9fe82..87ea6cc 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-7b8b9c17db93ea5287575b437c77fb36eeb81b31
+d18cb77864dcc4b5c7cb08c2331008c01165f34f
diff --git a/android_compat_hacks.c b/android_compat_hacks.c
index cf4863d..a3f032e 100644
--- a/android_compat_hacks.c
+++ b/android_compat_hacks.c
@@ -18,40 +18,10 @@
  * The declarations for these functions are in the main BoringSSL headers but
  * the only definitions are here, in Android land. */
 
-#include <openssl/base.h>
-
-#include <assert.h>
-
-#include <openssl/bn.h>
-#include <openssl/cipher.h>
-#include <openssl/err.h>
 #include <openssl/ssl.h>
 
+#include <stdlib.h>
 
-BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) {
-  assert(bn == NULL);
-
-  static const uint8_t data[] = {
-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
-      0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-      0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
-      0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-      0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
-      0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-      0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
-      0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-      0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
-      0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-      0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
-      0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-      0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
-      0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-      0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
-      0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  };
-
-  return BN_bin2bn(data, sizeof(data), 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 fe7979b..f66cb28 100644
--- a/err_data.c
+++ b/err_data.c
@@ -54,178 +54,163 @@
 OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
 
 const uint32_t kOpenSSLReasonValues[] = {
-    0xc3207ab,
-    0xc3287c5,
-    0xc3307d4,
-    0xc3387e4,
-    0xc3407f3,
-    0xc34880c,
-    0xc350818,
-    0xc358835,
-    0xc360847,
-    0xc368855,
-    0xc370865,
-    0xc378872,
-    0xc380882,
-    0xc38888d,
-    0xc3908a3,
-    0xc3988b2,
-    0xc3a08c6,
-    0xc3a87b8,
-    0xc3b00b0,
-    0x10321469,
-    0x10329475,
-    0x1033148e,
-    0x103394a1,
-    0x10340dd2,
-    0x103494c0,
-    0x103514d5,
-    0x10359507,
-    0x10361520,
-    0x10369535,
-    0x10371553,
-    0x10379562,
-    0x1038157e,
-    0x10389599,
-    0x103915a8,
-    0x103995c4,
-    0x103a15df,
-    0x103a95f6,
-    0x103b1607,
-    0x103b961b,
-    0x103c163a,
-    0x103c9649,
-    0x103d1660,
-    0x103d9673,
-    0x103e0b5d,
-    0x103e96a4,
-    0x103f16b7,
-    0x103f96d1,
-    0x104016e1,
-    0x104096f5,
-    0x1041170b,
-    0x10419723,
-    0x10421738,
-    0x1042974c,
-    0x1043175e,
-    0x104385c1,
-    0x104408b2,
-    0x10449773,
-    0x1045178a,
-    0x1045979f,
-    0x104617ad,
-    0x10469686,
-    0x104714e8,
-    0x104787b8,
-    0x104800b0,
-    0x104894b4,
-    0x14320b40,
-    0x14328b4e,
-    0x14330b5d,
-    0x14338b6f,
+    0xc320838,
+    0xc328852,
+    0xc330861,
+    0xc338871,
+    0xc340880,
+    0xc348899,
+    0xc3508a5,
+    0xc3588c2,
+    0xc3608d4,
+    0xc3688e2,
+    0xc3708f2,
+    0xc3788ff,
+    0xc38090f,
+    0xc38891a,
+    0xc390930,
+    0xc39893f,
+    0xc3a0953,
+    0xc3a8845,
+    0xc3b00ea,
+    0x10320845,
+    0x1032939a,
+    0x103313a6,
+    0x103393bf,
+    0x103413d2,
+    0x10348e7a,
+    0x10350c19,
+    0x103593e5,
+    0x103613fa,
+    0x1036940d,
+    0x1037142c,
+    0x10379445,
+    0x1038145a,
+    0x10389478,
+    0x10391487,
+    0x103994a3,
+    0x103a14be,
+    0x103a94cd,
+    0x103b14e9,
+    0x103b9504,
+    0x103c151b,
+    0x103c80ea,
+    0x103d152c,
+    0x103d9540,
+    0x103e155f,
+    0x103e956e,
+    0x103f1585,
+    0x103f9598,
+    0x10400bea,
+    0x104095ab,
+    0x104115c9,
+    0x104195dc,
+    0x104215f6,
+    0x10429606,
+    0x1043161a,
+    0x10439630,
+    0x10441648,
+    0x1044965d,
+    0x10451671,
+    0x10459683,
+    0x104605fb,
+    0x1046893f,
+    0x10471698,
+    0x104796af,
+    0x104816c4,
+    0x104896d2,
+    0x14320bcd,
+    0x14328bdb,
+    0x14330bea,
+    0x14338bfc,
     0x18320083,
-    0x18328e38,
-    0x18340e66,
-    0x18348e7a,
-    0x18358eb1,
-    0x18368ede,
-    0x18370ef1,
-    0x18378f05,
-    0x18380f29,
-    0x18388f37,
-    0x18390f4d,
-    0x18398f61,
-    0x183a0f71,
-    0x183b0f81,
-    0x183b8f96,
-    0x183c8fc1,
-    0x183d0fd5,
-    0x183d8fe5,
-    0x183e0b8c,
-    0x183e8ff2,
-    0x183f1004,
-    0x183f900f,
-    0x1840101f,
-    0x18409030,
-    0x18411041,
-    0x18419053,
-    0x1842107c,
-    0x184290ae,
-    0x184310bd,
-    0x18451126,
-    0x1845913c,
-    0x18461157,
-    0x18468ec9,
-    0x184709ca,
-    0x18478094,
-    0x18480fad,
-    0x184890f2,
-    0x18490e4e,
-    0x18498e8f,
-    0x184a118d,
-    0x184a910a,
-    0x184b10d1,
-    0x184b8e28,
-    0x184c1095,
-    0x184c865c,
-    0x184d1172,
-    0x203211b4,
-    0x243211c0,
-    0x243288f8,
-    0x243311d2,
-    0x243391df,
-    0x243411ec,
-    0x243491fe,
-    0x2435120d,
-    0x2435922a,
-    0x24361237,
-    0x24369245,
-    0x24371253,
-    0x24379261,
-    0x2438126a,
-    0x24389277,
-    0x2439128a,
-    0x28320b80,
-    0x28328b8c,
-    0x28330b5d,
-    0x28338b9f,
-    0x2c32280e,
-    0x2c32a81c,
-    0x2c33282e,
-    0x2c33a840,
-    0x2c342854,
-    0x2c34a866,
-    0x2c352881,
-    0x2c35a893,
-    0x2c3628a6,
-    0x2c3682f3,
-    0x2c3728b3,
-    0x2c37a8c5,
-    0x2c3828d8,
-    0x2c38a8e6,
-    0x2c3928f6,
-    0x2c39a908,
-    0x2c3a291c,
-    0x2c3aa92d,
-    0x2c3b134a,
-    0x2c3ba93e,
-    0x2c3c2952,
-    0x2c3ca968,
-    0x2c3d2981,
-    0x2c3da9af,
-    0x2c3e29bd,
-    0x2c3ea9d5,
-    0x2c3f29ed,
-    0x2c3fa9fa,
-    0x2c402a1d,
-    0x2c40aa3c,
-    0x2c4111b4,
-    0x2c41aa4d,
-    0x2c422a60,
-    0x2c429126,
-    0x2c432a71,
-    0x2c438693,
-    0x2c44299e,
+    0x18328ed0,
+    0x183300ac,
+    0x18338ee6,
+    0x18340efa,
+    0x183480ea,
+    0x18350f0f,
+    0x18358f27,
+    0x18360f3c,
+    0x18368f50,
+    0x18370f74,
+    0x18378f8a,
+    0x18380f9e,
+    0x18388fae,
+    0x18390a57,
+    0x18398fbe,
+    0x183a0fd3,
+    0x183a8fe7,
+    0x183b0c25,
+    0x183b8ff4,
+    0x183c1006,
+    0x183c9011,
+    0x183d1021,
+    0x183d9032,
+    0x183e1043,
+    0x183e9055,
+    0x183f107e,
+    0x183f9097,
+    0x184010af,
+    0x184086d3,
+    0x203210d6,
+    0x243210e2,
+    0x24328985,
+    0x243310f4,
+    0x24339101,
+    0x2434110e,
+    0x24349120,
+    0x2435112f,
+    0x2435914c,
+    0x24361159,
+    0x24369167,
+    0x24371175,
+    0x24379183,
+    0x2438118c,
+    0x24389199,
+    0x243911ac,
+    0x28320c0d,
+    0x28328c25,
+    0x28330bea,
+    0x28338c38,
+    0x28340c19,
+    0x283480ac,
+    0x283500ea,
+    0x2c32274a,
+    0x2c32a758,
+    0x2c33276a,
+    0x2c33a77c,
+    0x2c342790,
+    0x2c34a7a2,
+    0x2c3527bd,
+    0x2c35a7cf,
+    0x2c3627e2,
+    0x2c36832d,
+    0x2c3727ef,
+    0x2c37a801,
+    0x2c382814,
+    0x2c38a82b,
+    0x2c392839,
+    0x2c39a849,
+    0x2c3a285b,
+    0x2c3aa86f,
+    0x2c3b2880,
+    0x2c3ba891,
+    0x2c3c28a5,
+    0x2c3ca8bb,
+    0x2c3d28d4,
+    0x2c3da8f1,
+    0x2c3e2902,
+    0x2c3ea910,
+    0x2c3f2928,
+    0x2c3fa940,
+    0x2c40294d,
+    0x2c4090d6,
+    0x2c41295e,
+    0x2c41a971,
+    0x2c4210af,
+    0x2c42a982,
+    0x2c430720,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -235,440 +220,449 @@
     0x3035006b,
     0x30358083,
     0x30360094,
-    0x303680a1,
-    0x303700b0,
-    0x303780bd,
-    0x303800d0,
-    0x303880eb,
-    0x30390100,
-    0x30398114,
-    0x303a0128,
-    0x303a8139,
-    0x303b0152,
-    0x303b816f,
-    0x303c017d,
-    0x303c8191,
-    0x303d01a1,
-    0x303d81ba,
-    0x303e01ca,
-    0x303e81dd,
-    0x303f01ec,
-    0x303f81f8,
-    0x3040020d,
-    0x3040821d,
-    0x30410234,
-    0x30418241,
-    0x30420254,
-    0x30428263,
-    0x30430278,
-    0x30438299,
-    0x304402ac,
-    0x304482bf,
-    0x304502d8,
-    0x304582f3,
-    0x30460310,
-    0x30468329,
-    0x30470337,
-    0x30478348,
-    0x30480357,
-    0x3048836f,
-    0x30490381,
-    0x30498395,
-    0x304a03b4,
-    0x304a83c7,
-    0x304b03d2,
-    0x304b83e3,
-    0x304c03ef,
-    0x304c8405,
-    0x304d0413,
-    0x304d8429,
-    0x304e043b,
-    0x304e844d,
-    0x304f0460,
-    0x304f8473,
-    0x30500484,
-    0x30508494,
-    0x305104ac,
-    0x305184c1,
-    0x305204d9,
-    0x305284ed,
-    0x30530505,
-    0x3053851e,
-    0x30540537,
-    0x30548554,
-    0x3055055f,
-    0x30558577,
-    0x30560587,
-    0x30568598,
-    0x305705ab,
-    0x305785c1,
-    0x305805ca,
-    0x305885df,
-    0x305905f2,
-    0x30598601,
-    0x305a0621,
-    0x305a8630,
-    0x305b063c,
-    0x305b865c,
-    0x305c0678,
-    0x305c8689,
-    0x305d0693,
-    0x34320aba,
-    0x34328ace,
-    0x34330aeb,
-    0x34338afe,
-    0x34340b0d,
-    0x34348b2a,
+    0x303680ac,
+    0x303700b9,
+    0x303780c8,
+    0x303800ea,
+    0x303880f7,
+    0x3039010a,
+    0x30398125,
+    0x303a013a,
+    0x303a814e,
+    0x303b0162,
+    0x303b8173,
+    0x303c018c,
+    0x303c81a9,
+    0x303d01b7,
+    0x303d81cb,
+    0x303e01db,
+    0x303e81f4,
+    0x303f0204,
+    0x303f8217,
+    0x30400226,
+    0x30408232,
+    0x30410247,
+    0x30418257,
+    0x3042026e,
+    0x3042827b,
+    0x3043028e,
+    0x3043829d,
+    0x304402b2,
+    0x304482d3,
+    0x304502e6,
+    0x304582f9,
+    0x30460312,
+    0x3046832d,
+    0x3047034a,
+    0x30478363,
+    0x30480371,
+    0x30488382,
+    0x30490391,
+    0x304983a9,
+    0x304a03bb,
+    0x304a83cf,
+    0x304b03ee,
+    0x304b8401,
+    0x304c040c,
+    0x304c841d,
+    0x304d0429,
+    0x304d843f,
+    0x304e044d,
+    0x304e8463,
+    0x304f0475,
+    0x304f8487,
+    0x3050049a,
+    0x305084ad,
+    0x305104be,
+    0x305184ce,
+    0x305204e6,
+    0x305284fb,
+    0x30530513,
+    0x30538527,
+    0x3054053f,
+    0x30548558,
+    0x30550571,
+    0x3055858e,
+    0x30560599,
+    0x305685b1,
+    0x305705c1,
+    0x305785d2,
+    0x305805e5,
+    0x305885fb,
+    0x30590604,
+    0x30598619,
+    0x305a062c,
+    0x305a863b,
+    0x305b065b,
+    0x305b866a,
+    0x305c068b,
+    0x305c86a7,
+    0x305d06b3,
+    0x305d86d3,
+    0x305e06ef,
+    0x305e8700,
+    0x305f0716,
+    0x305f8720,
+    0x34320b47,
+    0x34328b5b,
+    0x34330b78,
+    0x34338b8b,
+    0x34340b9a,
+    0x34348bb7,
     0x3c320083,
-    0x3c328bc9,
-    0x3c330be2,
-    0x3c338bfd,
-    0x3c340c1a,
-    0x3c348c35,
-    0x3c350c50,
-    0x3c358c65,
-    0x3c360c7e,
-    0x3c368c96,
-    0x3c370ca7,
-    0x3c378cb5,
-    0x3c380cc2,
-    0x3c388cd6,
-    0x3c390b8c,
-    0x3c398cea,
-    0x3c3a0cfe,
-    0x3c3a8872,
-    0x3c3b0d0e,
-    0x3c3b8d29,
-    0x3c3c0d3b,
-    0x3c3c8d51,
-    0x3c3d0d5b,
-    0x3c3d8d6f,
-    0x3c3e0d7d,
-    0x3c3e8da2,
-    0x3c3f0bb5,
-    0x3c3f8d8b,
-    0x403217c4,
-    0x403297da,
-    0x40331808,
-    0x40339812,
-    0x40341829,
-    0x40349847,
-    0x40351857,
-    0x40359869,
-    0x40361876,
-    0x40369882,
-    0x40371897,
-    0x403798a9,
-    0x403818b4,
-    0x403898c6,
-    0x40390dd2,
-    0x403998d6,
-    0x403a18e9,
-    0x403a990a,
-    0x403b191b,
-    0x403b992b,
+    0x3c328c62,
+    0x3c330c7b,
+    0x3c338c96,
+    0x3c340cb3,
+    0x3c348cdd,
+    0x3c350cf8,
+    0x3c358d0d,
+    0x3c360d26,
+    0x3c368d3e,
+    0x3c370d4f,
+    0x3c378d5d,
+    0x3c380d6a,
+    0x3c388d7e,
+    0x3c390c25,
+    0x3c398d92,
+    0x3c3a0da6,
+    0x3c3a88ff,
+    0x3c3b0db6,
+    0x3c3b8dd1,
+    0x3c3c0de3,
+    0x3c3c8df9,
+    0x3c3d0e03,
+    0x3c3d8e17,
+    0x3c3e0e25,
+    0x3c3e8e4a,
+    0x3c3f0c4e,
+    0x3c3f8e33,
+    0x3c4000ac,
+    0x3c4080ea,
+    0x3c410cce,
+    0x403216e9,
+    0x403296ff,
+    0x4033172d,
+    0x40339737,
+    0x4034174e,
+    0x4034976c,
+    0x4035177c,
+    0x4035978e,
+    0x4036179b,
+    0x403697a7,
+    0x403717bc,
+    0x403797ce,
+    0x403817d9,
+    0x403897eb,
+    0x40390e7a,
+    0x403997fb,
+    0x403a180e,
+    0x403a982f,
+    0x403b1840,
+    0x403b9850,
     0x403c0064,
     0x403c8083,
-    0x403d1937,
-    0x403d994d,
-    0x403e195c,
-    0x403e996f,
-    0x403f1989,
-    0x403f9997,
-    0x404019ac,
-    0x404099c0,
-    0x404119dd,
-    0x404199f8,
-    0x40421a11,
-    0x40429a24,
-    0x40431a38,
-    0x40439a50,
-    0x40441a67,
-    0x40448094,
-    0x40451a7c,
-    0x40459a8e,
-    0x40461ab2,
-    0x40469ad2,
-    0x40471ae0,
-    0x40479af4,
-    0x40481b09,
-    0x40489b22,
-    0x40491b39,
-    0x40499b53,
-    0x404a1b6a,
-    0x404a9b88,
-    0x404b1ba0,
-    0x404b9bb7,
-    0x404c1bcd,
-    0x404c9bdf,
-    0x404d1c00,
-    0x404d9c22,
-    0x404e1c36,
-    0x404e9c43,
-    0x404f1c5a,
-    0x404f9c6a,
-    0x40501c7a,
-    0x40509c8e,
-    0x40511ca9,
-    0x40519cb9,
-    0x40521cd0,
-    0x40529ce2,
-    0x40531cfa,
-    0x40539d0d,
-    0x40541d22,
-    0x40549d45,
-    0x40551d53,
-    0x40559d70,
-    0x40561d7d,
-    0x40569d96,
-    0x40571dae,
-    0x40579dc1,
-    0x40581dd6,
-    0x40589de8,
-    0x40591df8,
-    0x40599e11,
-    0x405a1e25,
-    0x405a9e35,
-    0x405b1e4d,
-    0x405b9e5e,
-    0x405c1e71,
-    0x405c9e82,
-    0x405d1e8f,
-    0x405d9ea6,
-    0x405e1ec6,
-    0x405e8a08,
-    0x405f1ee7,
-    0x405f9ef4,
-    0x40601f02,
-    0x40609f24,
-    0x40611f4c,
-    0x40619f61,
-    0x40621f78,
-    0x40629f89,
-    0x40631f9a,
-    0x40639faf,
-    0x40641fc6,
-    0x40649fd7,
-    0x40651ff2,
-    0x4065a009,
-    0x40662021,
-    0x4066a04b,
-    0x40672076,
-    0x4067a097,
-    0x406820aa,
-    0x4068a0cb,
-    0x406920e6,
-    0x4069a114,
-    0x406a2135,
-    0x406aa155,
-    0x406b22dd,
-    0x406ba300,
-    0x406c2316,
-    0x406ca542,
-    0x406d2571,
-    0x406da599,
-    0x406e25b2,
-    0x406ea5ca,
-    0x406f25e9,
-    0x406fa5fe,
-    0x40702611,
-    0x4070a62e,
-    0x40710773,
-    0x4071a640,
-    0x40722653,
-    0x4072a66c,
-    0x40732684,
-    0x407390ae,
-    0x40742698,
-    0x4074a6b2,
-    0x407526c3,
-    0x4075a6d7,
-    0x407626e5,
-    0x40769277,
-    0x4077270a,
-    0x4077a72c,
-    0x40782747,
-    0x4078a75c,
-    0x40792773,
-    0x4079a789,
-    0x407a2795,
-    0x407aa7a8,
-    0x407b27bd,
-    0x407ba7cf,
-    0x407c27e4,
-    0x407ca7ed,
-    0x41f42208,
-    0x41f9229a,
-    0x41fe218d,
-    0x41fea369,
-    0x41ff245a,
-    0x42032221,
-    0x42082243,
-    0x4208a27f,
-    0x42092171,
-    0x4209a2b9,
-    0x420a21c8,
-    0x420aa1a8,
-    0x420b21e8,
-    0x420ba261,
-    0x420c2476,
-    0x420ca336,
-    0x420d2350,
-    0x420da387,
-    0x421223a1,
-    0x4217243d,
-    0x4217a3e3,
-    0x421c2405,
-    0x421f23c0,
-    0x4221248d,
-    0x42262420,
-    0x422b2526,
-    0x422ba4ef,
-    0x422c250e,
-    0x422ca4c9,
-    0x422d24a8,
-    0x4432069e,
-    0x443286ad,
-    0x443306b9,
-    0x443386c7,
-    0x443406da,
-    0x443486eb,
-    0x443506f2,
-    0x443586fc,
-    0x4436070f,
-    0x44368725,
-    0x44370737,
-    0x44378744,
-    0x44380753,
-    0x4438875b,
-    0x44390773,
-    0x44398781,
-    0x443a0794,
-    0x4c3212a1,
-    0x4c3292b1,
-    0x4c3312c4,
-    0x4c3392e4,
-    0x4c340094,
-    0x4c3480b0,
-    0x4c3512f0,
-    0x4c3592fe,
-    0x4c36131a,
-    0x4c36932d,
-    0x4c37133c,
-    0x4c37934a,
-    0x4c38135f,
-    0x4c38936b,
-    0x4c39138b,
-    0x4c3993b5,
-    0x4c3a13ce,
-    0x4c3a93e7,
-    0x4c3b05c1,
-    0x4c3b9400,
-    0x4c3c1412,
-    0x4c3c9421,
-    0x4c3d10ae,
-    0x4c3d943a,
-    0x4c3e1447,
-    0x50322a83,
-    0x5032aa92,
-    0x50332a9d,
-    0x5033aaad,
-    0x50342ac6,
-    0x5034aae0,
-    0x50352aee,
-    0x5035ab04,
-    0x50362b16,
-    0x5036ab2c,
-    0x50372b45,
-    0x5037ab58,
-    0x50382b70,
-    0x5038ab81,
-    0x50392b96,
-    0x5039abaa,
-    0x503a2bca,
-    0x503aabe0,
-    0x503b2bf8,
-    0x503bac0a,
-    0x503c2c26,
-    0x503cac3d,
-    0x503d2c56,
-    0x503dac6c,
-    0x503e2c79,
-    0x503eac8f,
-    0x503f2ca1,
-    0x503f8348,
-    0x50402cb4,
-    0x5040acc4,
-    0x50412cde,
-    0x5041aced,
-    0x50422d07,
-    0x5042ad24,
-    0x50432d34,
-    0x5043ad44,
-    0x50442d53,
-    0x50448405,
-    0x50452d67,
-    0x5045ad85,
-    0x50462d98,
-    0x5046adae,
-    0x50472dc0,
-    0x5047add5,
-    0x50482dfb,
-    0x5048ae09,
-    0x50492e1c,
-    0x5049ae31,
-    0x504a2e47,
-    0x504aae57,
-    0x504b2e77,
-    0x504bae8a,
-    0x504c2ead,
-    0x504caedb,
-    0x504d2eed,
-    0x504daf0a,
-    0x504e2f25,
-    0x504eaf41,
-    0x504f2f53,
-    0x504faf6a,
-    0x50502f79,
-    0x50508678,
-    0x50512f8c,
-    0x58320e10,
-    0x68320dd2,
-    0x68328b8c,
-    0x68330b9f,
-    0x68338de0,
-    0x68340df0,
-    0x683480b0,
-    0x6c320dae,
-    0x6c328b6f,
-    0x6c330db9,
-    0x7432097e,
-    0x783208e3,
-    0x783288f8,
-    0x78330904,
+    0x403d185c,
+    0x403d9872,
+    0x403e1881,
+    0x403e9894,
+    0x403f18ae,
+    0x403f98bc,
+    0x404018d1,
+    0x404098e5,
+    0x40411902,
+    0x4041991d,
+    0x40421936,
+    0x40429949,
+    0x4043195d,
+    0x40439975,
+    0x4044198c,
+    0x404480ac,
+    0x404519a1,
+    0x404599b3,
+    0x404619d7,
+    0x404699f7,
+    0x40471a05,
+    0x40479a19,
+    0x40481a2e,
+    0x40489a47,
+    0x40491a5e,
+    0x40499a78,
+    0x404a1a8f,
+    0x404a9aad,
+    0x404b1ac5,
+    0x404b9adc,
+    0x404c1af2,
+    0x404c9b04,
+    0x404d1b25,
+    0x404d9b47,
+    0x404e1b5b,
+    0x404e9b68,
+    0x404f1b7f,
+    0x404f9b8f,
+    0x40501b9f,
+    0x40509bb3,
+    0x40511bce,
+    0x40519bde,
+    0x40521bf5,
+    0x40529c07,
+    0x40531c1f,
+    0x40539c32,
+    0x40541c47,
+    0x40549c6a,
+    0x40551c78,
+    0x40559c95,
+    0x40561ca2,
+    0x40569cbb,
+    0x40571cd3,
+    0x40579ce6,
+    0x40581cfb,
+    0x40589d0d,
+    0x40591d1d,
+    0x40599d36,
+    0x405a1d4a,
+    0x405a9d5a,
+    0x405b1d72,
+    0x405b9d83,
+    0x405c1d96,
+    0x405c9da7,
+    0x405d1db4,
+    0x405d9dcb,
+    0x405e1deb,
+    0x405e8a95,
+    0x405f1e0c,
+    0x405f9e19,
+    0x40601e27,
+    0x40609e49,
+    0x40611e71,
+    0x40619e86,
+    0x40621e9d,
+    0x40629eae,
+    0x40631ebf,
+    0x40639ed4,
+    0x40641eeb,
+    0x40649efc,
+    0x40651f17,
+    0x40659f2e,
+    0x40661f46,
+    0x40669f70,
+    0x40671f9b,
+    0x40679fbc,
+    0x40681fcf,
+    0x40689ff0,
+    0x40692022,
+    0x4069a050,
+    0x406a2071,
+    0x406aa091,
+    0x406b2219,
+    0x406ba23c,
+    0x406c2252,
+    0x406ca47e,
+    0x406d24ad,
+    0x406da4d5,
+    0x406e24ee,
+    0x406ea506,
+    0x406f2525,
+    0x406fa53a,
+    0x4070254d,
+    0x4070a56a,
+    0x40710800,
+    0x4071a57c,
+    0x4072258f,
+    0x4072a5a8,
+    0x407325c0,
+    0x4073935c,
+    0x407425d4,
+    0x4074a5ee,
+    0x407525ff,
+    0x4075a613,
+    0x40762621,
+    0x40769199,
+    0x40772646,
+    0x4077a668,
+    0x40782683,
+    0x4078a698,
+    0x407926af,
+    0x4079a6c5,
+    0x407a26d1,
+    0x407aa6e4,
+    0x407b26f9,
+    0x407ba70b,
+    0x407c2720,
+    0x407ca729,
+    0x407d200b,
+    0x41f42144,
+    0x41f921d6,
+    0x41fe20c9,
+    0x41fea2a5,
+    0x41ff2396,
+    0x4203215d,
+    0x4208217f,
+    0x4208a1bb,
+    0x420920ad,
+    0x4209a1f5,
+    0x420a2104,
+    0x420aa0e4,
+    0x420b2124,
+    0x420ba19d,
+    0x420c23b2,
+    0x420ca272,
+    0x420d228c,
+    0x420da2c3,
+    0x421222dd,
+    0x42172379,
+    0x4217a31f,
+    0x421c2341,
+    0x421f22fc,
+    0x422123c9,
+    0x4226235c,
+    0x422b2462,
+    0x422ba42b,
+    0x422c244a,
+    0x422ca405,
+    0x422d23e4,
+    0x4432072b,
+    0x4432873a,
+    0x44330746,
+    0x44338754,
+    0x44340767,
+    0x44348778,
+    0x4435077f,
+    0x44358789,
+    0x4436079c,
+    0x443687b2,
+    0x443707c4,
+    0x443787d1,
+    0x443807e0,
+    0x443887e8,
+    0x44390800,
+    0x4439880e,
+    0x443a0821,
+    0x4c3211c3,
+    0x4c3291d3,
+    0x4c3311e6,
+    0x4c339206,
+    0x4c3400ac,
+    0x4c3480ea,
+    0x4c351212,
+    0x4c359220,
+    0x4c36123c,
+    0x4c36924f,
+    0x4c37125e,
+    0x4c37926c,
+    0x4c381281,
+    0x4c38928d,
+    0x4c3912ad,
+    0x4c3992d7,
+    0x4c3a12f0,
+    0x4c3a9309,
+    0x4c3b05fb,
+    0x4c3b9322,
+    0x4c3c1334,
+    0x4c3c9343,
+    0x4c3d135c,
+    0x4c3d936b,
+    0x4c3e1378,
+    0x50322994,
+    0x5032a9a3,
+    0x503329ae,
+    0x5033a9be,
+    0x503429d7,
+    0x5034a9f1,
+    0x503529ff,
+    0x5035aa15,
+    0x50362a27,
+    0x5036aa3d,
+    0x50372a56,
+    0x5037aa69,
+    0x50382a81,
+    0x5038aa92,
+    0x50392aa7,
+    0x5039aabb,
+    0x503a2adb,
+    0x503aaaf1,
+    0x503b2b09,
+    0x503bab1b,
+    0x503c2b37,
+    0x503cab4e,
+    0x503d2b67,
+    0x503dab7d,
+    0x503e2b8a,
+    0x503eaba0,
+    0x503f2bb2,
+    0x503f8382,
+    0x50402bc5,
+    0x5040abd5,
+    0x50412bef,
+    0x5041abfe,
+    0x50422c18,
+    0x5042ac35,
+    0x50432c45,
+    0x5043ac55,
+    0x50442c64,
+    0x5044843f,
+    0x50452c78,
+    0x5045ac96,
+    0x50462ca9,
+    0x5046acbf,
+    0x50472cd1,
+    0x5047ace6,
+    0x50482d0c,
+    0x5048ad1a,
+    0x50492d2d,
+    0x5049ad42,
+    0x504a2d58,
+    0x504aad68,
+    0x504b2d88,
+    0x504bad9b,
+    0x504c2dbe,
+    0x504cadec,
+    0x504d2dfe,
+    0x504dae1b,
+    0x504e2e36,
+    0x504eae52,
+    0x504f2e64,
+    0x504fae7b,
+    0x50502e8a,
+    0x505086ef,
+    0x50512e9d,
+    0x58320eb8,
+    0x68320e7a,
+    0x68328c25,
+    0x68330c38,
+    0x68338e88,
+    0x68340e98,
+    0x683480ea,
+    0x6c320e56,
+    0x6c328bfc,
+    0x6c330e61,
+    0x74320a0b,
+    0x78320970,
+    0x78328985,
+    0x78330991,
     0x78338083,
-    0x78340913,
-    0x78348928,
-    0x78350947,
-    0x78358969,
-    0x7836097e,
-    0x78368994,
-    0x783709a4,
-    0x783789b7,
-    0x783809ca,
-    0x783889dc,
-    0x783909e9,
-    0x78398a08,
-    0x783a0a1d,
-    0x783a8a2b,
-    0x783b0a35,
-    0x783b8a49,
-    0x783c0a60,
-    0x783c8a75,
-    0x783d0a8c,
-    0x783d8aa1,
-    0x783e09f7,
-    0x7c3211a3,
+    0x783409a0,
+    0x783489b5,
+    0x783509d4,
+    0x783589f6,
+    0x78360a0b,
+    0x78368a21,
+    0x78370a31,
+    0x78378a44,
+    0x78380a57,
+    0x78388a69,
+    0x78390a76,
+    0x78398a95,
+    0x783a0aaa,
+    0x783a8ab8,
+    0x783b0ac2,
+    0x783b8ad6,
+    0x783c0aed,
+    0x783c8b02,
+    0x783d0b19,
+    0x783d8b2e,
+    0x783e0a84,
+    0x7c3210c5,
 };
 
 const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -682,8 +676,10 @@
     "BN_LIB\0"
     "BOOLEAN_IS_WRONG_LENGTH\0"
     "BUFFER_TOO_SMALL\0"
+    "CONTEXT_NOT_INITIALISED\0"
     "DECODE_ERROR\0"
     "DEPTH_EXCEEDED\0"
+    "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
     "ENCODE_ERROR\0"
     "ERROR_GETTING_TIME\0"
     "EXPECTING_AN_ASN1_SEQUENCE\0"
@@ -755,10 +751,13 @@
     "UNEXPECTED_EOC\0"
     "UNIVERSALSTRING_IS_WRONG_LENGTH\0"
     "UNKNOWN_FORMAT\0"
+    "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
+    "UNKNOWN_SIGNATURE_ALGORITHM\0"
     "UNKNOWN_TAG\0"
     "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0"
     "UNSUPPORTED_PUBLIC_KEY_TYPE\0"
     "UNSUPPORTED_TYPE\0"
+    "WRONG_PUBLIC_KEY_TYPE\0"
     "WRONG_TAG\0"
     "WRONG_TYPE\0"
     "BAD_FOPEN_MODE\0"
@@ -831,6 +830,7 @@
     "MODULUS_TOO_LARGE\0"
     "NO_PRIVATE_VALUE\0"
     "BAD_Q_VALUE\0"
+    "BAD_VERSION\0"
     "MISSING_PARAMETERS\0"
     "NEED_NEW_SETUP_VALUES\0"
     "BIGNUM_OUT_OF_RANGE\0"
@@ -838,6 +838,7 @@
     "D2I_ECPKPARAMETERS_FAILURE\0"
     "EC_GROUP_NEW_BY_NAME_FAILURE\0"
     "GROUP2PKPARAMETERS_FAILURE\0"
+    "GROUP_MISMATCH\0"
     "I2D_ECPKPARAMETERS_FAILURE\0"
     "INCOMPATIBLE_OBJECTS\0"
     "INVALID_COMPRESSED_POINT\0"
@@ -864,27 +865,19 @@
     "NOT_IMPLEMENTED\0"
     "RANDOM_NUMBER_GENERATION_FAILED\0"
     "OPERATION_NOT_SUPPORTED\0"
-    "BN_DECODE_ERROR\0"
     "COMMAND_NOT_SUPPORTED\0"
-    "CONTEXT_NOT_INITIALISED\0"
     "DIFFERENT_KEY_TYPES\0"
     "DIFFERENT_PARAMETERS\0"
-    "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
     "EXPECTING_AN_EC_KEY_KEY\0"
     "EXPECTING_AN_RSA_KEY\0"
-    "EXPECTING_A_DH_KEY\0"
     "EXPECTING_A_DSA_KEY\0"
     "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0"
-    "INVALID_CURVE\0"
     "INVALID_DIGEST_LENGTH\0"
     "INVALID_DIGEST_TYPE\0"
     "INVALID_KEYBITS\0"
     "INVALID_MGF1_MD\0"
     "INVALID_PADDING_MODE\0"
-    "INVALID_PSS_PARAMETERS\0"
     "INVALID_PSS_SALTLEN\0"
-    "INVALID_SALT_LENGTH\0"
-    "INVALID_TRAILER\0"
     "KEYS_NOT_SET\0"
     "NO_DEFAULT_DIGEST\0"
     "NO_KEY_SET\0"
@@ -894,17 +887,8 @@
     "NO_PARAMETERS_SET\0"
     "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0"
     "OPERATON_NOT_INITIALIZED\0"
-    "PARAMETER_ENCODING_ERROR\0"
-    "UNKNOWN_DIGEST\0"
-    "UNKNOWN_MASK_DIGEST\0"
-    "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
     "UNKNOWN_PUBLIC_KEY_TYPE\0"
-    "UNKNOWN_SIGNATURE_ALGORITHM\0"
     "UNSUPPORTED_ALGORITHM\0"
-    "UNSUPPORTED_MASK_ALGORITHM\0"
-    "UNSUPPORTED_MASK_PARAMETER\0"
-    "UNSUPPORTED_SIGNATURE_TYPE\0"
-    "WRONG_PUBLIC_KEY_TYPE\0"
     "OUTPUT_TOO_LARGE\0"
     "UNKNOWN_NID\0"
     "BAD_BASE64_DECODE\0"
@@ -940,13 +924,13 @@
     "UNKNOWN_ALGORITHM\0"
     "UNKNOWN_CIPHER\0"
     "UNKNOWN_CIPHER_ALGORITHM\0"
+    "UNKNOWN_DIGEST\0"
     "UNKNOWN_HASH\0"
     "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0"
     "BAD_E_VALUE\0"
     "BAD_FIXED_HEADER_DECRYPT\0"
     "BAD_PAD_BYTE_COUNT\0"
     "BAD_RSA_PARAMETERS\0"
-    "BAD_VERSION\0"
     "BLOCK_TYPE_IS_NOT_01\0"
     "BN_NOT_INITIALIZED\0"
     "CANNOT_RECOVER_MULTI_PRIME_KEY\0"
@@ -1087,6 +1071,7 @@
     "SERVERHELLO_TLSEXT\0"
     "SESSION_ID_CONTEXT_UNINITIALIZED\0"
     "SESSION_MAY_NOT_BE_CREATED\0"
+    "SHUTDOWN_WHILE_IN_INIT\0"
     "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0"
     "SRTP_COULD_NOT_ALLOCATE_PROFILES\0"
     "SRTP_UNKNOWN_PROTECTION_PROFILE\0"
@@ -1165,6 +1150,7 @@
     "IDP_MISMATCH\0"
     "INVALID_DIRECTORY\0"
     "INVALID_FIELD_NAME\0"
+    "INVALID_PSS_PARAMETERS\0"
     "INVALID_TRUST\0"
     "ISSUER_MISMATCH\0"
     "KEY_TYPE_MISMATCH\0"
@@ -1180,8 +1166,6 @@
     "PUBLIC_KEY_DECODE_ERROR\0"
     "PUBLIC_KEY_ENCODE_ERROR\0"
     "SHOULD_RETRY\0"
-    "UNABLE_TO_FIND_PARAMETERS_IN_CHAIN\0"
-    "UNABLE_TO_GET_CERTS_PUBLIC_KEY\0"
     "UNKNOWN_KEY_TYPE\0"
     "UNKNOWN_PURPOSE_ID\0"
     "UNKNOWN_TRUST_ID\0"
diff --git a/linux-aarch64/crypto/aes/aesv8-armx64.S b/linux-aarch64/crypto/aes/aesv8-armx64.S
index fa2abbc..3e8cb16 100644
--- a/linux-aarch64/crypto/aes/aesv8-armx64.S
+++ b/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -13,6 +13,7 @@
 .long	0x1b,0x1b,0x1b,0x1b
 
 .globl	aes_v8_set_encrypt_key
+.hidden	aes_v8_set_encrypt_key
 .type	aes_v8_set_encrypt_key,%function
 .align	5
 aes_v8_set_encrypt_key:
@@ -180,6 +181,7 @@
 .size	aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
 
 .globl	aes_v8_set_decrypt_key
+.hidden	aes_v8_set_decrypt_key
 .type	aes_v8_set_decrypt_key,%function
 .align	5
 aes_v8_set_decrypt_key:
@@ -219,6 +221,7 @@
 	ret
 .size	aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
 .globl	aes_v8_encrypt
+.hidden	aes_v8_encrypt
 .type	aes_v8_encrypt,%function
 .align	5
 aes_v8_encrypt:
@@ -248,6 +251,7 @@
 	ret
 .size	aes_v8_encrypt,.-aes_v8_encrypt
 .globl	aes_v8_decrypt
+.hidden	aes_v8_decrypt
 .type	aes_v8_decrypt,%function
 .align	5
 aes_v8_decrypt:
@@ -277,6 +281,7 @@
 	ret
 .size	aes_v8_decrypt,.-aes_v8_decrypt
 .globl	aes_v8_cbc_encrypt
+.hidden	aes_v8_cbc_encrypt
 .type	aes_v8_cbc_encrypt,%function
 .align	5
 aes_v8_cbc_encrypt:
@@ -567,6 +572,7 @@
 	ret
 .size	aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
 .globl	aes_v8_ctr32_encrypt_blocks
+.hidden	aes_v8_ctr32_encrypt_blocks
 .type	aes_v8_ctr32_encrypt_blocks,%function
 .align	5
 aes_v8_ctr32_encrypt_blocks:
@@ -748,4 +754,4 @@
 	ret
 .size	aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/bn/armv8-mont.S b/linux-aarch64/crypto/bn/armv8-mont.S
index 9355ce7..74702db 100644
--- a/linux-aarch64/crypto/bn/armv8-mont.S
+++ b/linux-aarch64/crypto/bn/armv8-mont.S
@@ -2,6 +2,7 @@
 .text
 
 .globl	bn_mul_mont
+.hidden	bn_mul_mont
 .type	bn_mul_mont,%function
 .align	5
 bn_mul_mont:
@@ -1403,4 +1404,4 @@
 .byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	4
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/chacha/chacha-armv8.S b/linux-aarch64/crypto/chacha/chacha-armv8.S
new file mode 100644
index 0000000..6ff6bff
--- /dev/null
+++ b/linux-aarch64/crypto/chacha/chacha-armv8.S
@@ -0,0 +1,1971 @@
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
+
+.text
+
+
+
+.align	5
+.Lsigma:
+.quad	0x3320646e61707865,0x6b20657479622d32		// endian-neutral
+.Lone:
+.long	1,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef	__ILP32__
+.long	OPENSSL_armcap_P-.
+#else
+.quad	OPENSSL_armcap_P-.
+#endif
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	2
+
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+	cbz	x2,.Labort
+	adr	x5,.LOPENSSL_armcap_P
+	cmp	x2,#192
+	b.lo	.Lshort
+#ifdef	__ILP32__
+	ldrsw	x6,[x5]
+#else
+	ldr	x6,[x5]
+#endif
+	ldr	w17,[x6,x5]
+	tst	w17,#ARMV7_NEON
+	b.ne	ChaCha20_neon
+
+.Lshort:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	sub	sp,sp,#64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ldp	x28,x30,[x4]		// load counter
+#ifdef	__ARMEB__
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+
+.Loop_outer:
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	mov	w7,w23
+	lsr	x8,x23,#32
+	mov	w9,w24
+	lsr	x10,x24,#32
+	mov	w11,w25
+	lsr	x12,x25,#32
+	mov	w13,w26
+	lsr	x14,x26,#32
+	mov	w15,w27
+	lsr	x16,x27,#32
+	mov	w17,w28
+	lsr	x19,x28,#32
+	mov	w20,w30
+	lsr	x21,x30,#32
+
+	mov	x4,#10
+	subs	x2,x2,#64
+.Loop:
+	sub	x4,x4,#1
+	add	w5,w5,w9
+	add	w6,w6,w10
+	add	w7,w7,w11
+	add	w8,w8,w12
+	eor	w17,w17,w5
+	eor	w19,w19,w6
+	eor	w20,w20,w7
+	eor	w21,w21,w8
+	ror	w17,w17,#16
+	ror	w19,w19,#16
+	ror	w20,w20,#16
+	ror	w21,w21,#16
+	add	w13,w13,w17
+	add	w14,w14,w19
+	add	w15,w15,w20
+	add	w16,w16,w21
+	eor	w9,w9,w13
+	eor	w10,w10,w14
+	eor	w11,w11,w15
+	eor	w12,w12,w16
+	ror	w9,w9,#20
+	ror	w10,w10,#20
+	ror	w11,w11,#20
+	ror	w12,w12,#20
+	add	w5,w5,w9
+	add	w6,w6,w10
+	add	w7,w7,w11
+	add	w8,w8,w12
+	eor	w17,w17,w5
+	eor	w19,w19,w6
+	eor	w20,w20,w7
+	eor	w21,w21,w8
+	ror	w17,w17,#24
+	ror	w19,w19,#24
+	ror	w20,w20,#24
+	ror	w21,w21,#24
+	add	w13,w13,w17
+	add	w14,w14,w19
+	add	w15,w15,w20
+	add	w16,w16,w21
+	eor	w9,w9,w13
+	eor	w10,w10,w14
+	eor	w11,w11,w15
+	eor	w12,w12,w16
+	ror	w9,w9,#25
+	ror	w10,w10,#25
+	ror	w11,w11,#25
+	ror	w12,w12,#25
+	add	w5,w5,w10
+	add	w6,w6,w11
+	add	w7,w7,w12
+	add	w8,w8,w9
+	eor	w21,w21,w5
+	eor	w17,w17,w6
+	eor	w19,w19,w7
+	eor	w20,w20,w8
+	ror	w21,w21,#16
+	ror	w17,w17,#16
+	ror	w19,w19,#16
+	ror	w20,w20,#16
+	add	w15,w15,w21
+	add	w16,w16,w17
+	add	w13,w13,w19
+	add	w14,w14,w20
+	eor	w10,w10,w15
+	eor	w11,w11,w16
+	eor	w12,w12,w13
+	eor	w9,w9,w14
+	ror	w10,w10,#20
+	ror	w11,w11,#20
+	ror	w12,w12,#20
+	ror	w9,w9,#20
+	add	w5,w5,w10
+	add	w6,w6,w11
+	add	w7,w7,w12
+	add	w8,w8,w9
+	eor	w21,w21,w5
+	eor	w17,w17,w6
+	eor	w19,w19,w7
+	eor	w20,w20,w8
+	ror	w21,w21,#24
+	ror	w17,w17,#24
+	ror	w19,w19,#24
+	ror	w20,w20,#24
+	add	w15,w15,w21
+	add	w16,w16,w17
+	add	w13,w13,w19
+	add	w14,w14,w20
+	eor	w10,w10,w15
+	eor	w11,w11,w16
+	eor	w12,w12,w13
+	eor	w9,w9,w14
+	ror	w10,w10,#25
+	ror	w11,w11,#25
+	ror	w12,w12,#25
+	ror	w9,w9,#25
+	cbnz	x4,.Loop
+
+	add	w5,w5,w22		// accumulate key block
+	add	x6,x6,x22,lsr#32
+	add	w7,w7,w23
+	add	x8,x8,x23,lsr#32
+	add	w9,w9,w24
+	add	x10,x10,x24,lsr#32
+	add	w11,w11,w25
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	x21,x21,x30,lsr#32
+
+	b.lo	.Ltail
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#1			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+
+	b.hi	.Loop_outer
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+.Labort:
+	ret
+
+.align	4
+.Ltail:
+	add	x2,x2,#64
+.Less_than_64:
+	sub	x0,x0,#1
+	add	x1,x1,x2
+	add	x0,x0,x2
+	add	x4,sp,x2
+	neg	x2,x2
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	stp	x5,x7,[sp,#0]
+	stp	x9,x11,[sp,#16]
+	stp	x13,x15,[sp,#32]
+	stp	x17,x20,[sp,#48]
+
+.Loop_tail:
+	ldrb	w10,[x1,x2]
+	ldrb	w11,[x4,x2]
+	add	x2,x2,#1
+	eor	w10,w10,w11
+	strb	w10,[x0,x2]
+	cbnz	x2,.Loop_tail
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	cmp	x2,#512
+	b.hs	.L512_or_more_neon
+
+	sub	sp,sp,#64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ld1	{v24.4s},[x5],#16
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ld1	{v25.4s,v26.4s},[x3]
+	ldp	x28,x30,[x4]		// load counter
+	ld1	{v27.4s},[x4]
+	ld1	{v31.4s},[x5]
+#ifdef	__ARMEB__
+	rev64	v24.4s,v24.4s
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+	add	v27.4s,v27.4s,v31.4s		// += 1
+	add	v28.4s,v27.4s,v31.4s
+	add	v29.4s,v28.4s,v31.4s
+	shl	v31.4s,v31.4s,#2			// 1 -> 4
+
+.Loop_outer_neon:
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	mov	v0.16b,v24.16b
+	mov	w7,w23
+	lsr	x8,x23,#32
+	mov	v4.16b,v24.16b
+	mov	w9,w24
+	lsr	x10,x24,#32
+	mov	v16.16b,v24.16b
+	mov	w11,w25
+	mov	v1.16b,v25.16b
+	lsr	x12,x25,#32
+	mov	v5.16b,v25.16b
+	mov	w13,w26
+	mov	v17.16b,v25.16b
+	lsr	x14,x26,#32
+	mov	v3.16b,v27.16b
+	mov	w15,w27
+	mov	v7.16b,v28.16b
+	lsr	x16,x27,#32
+	mov	v19.16b,v29.16b
+	mov	w17,w28
+	mov	v2.16b,v26.16b
+	lsr	x19,x28,#32
+	mov	v6.16b,v26.16b
+	mov	w20,w30
+	mov	v18.16b,v26.16b
+	lsr	x21,x30,#32
+
+	mov	x4,#10
+	subs	x2,x2,#256
+.Loop_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v16.4s,v16.4s,v17.4s
+	add	w7,w7,w11
+	eor	v3.16b,v3.16b,v0.16b
+	add	w8,w8,w12
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w17,w17,w5
+	eor	v19.16b,v19.16b,v16.16b
+	eor	w19,w19,w6
+	rev32	v3.8h,v3.8h
+	eor	w20,w20,w7
+	rev32	v7.8h,v7.8h
+	eor	w21,w21,w8
+	rev32	v19.8h,v19.8h
+	ror	w17,w17,#16
+	add	v2.4s,v2.4s,v3.4s
+	ror	w19,w19,#16
+	add	v6.4s,v6.4s,v7.4s
+	ror	w20,w20,#16
+	add	v18.4s,v18.4s,v19.4s
+	ror	w21,w21,#16
+	eor	v20.16b,v1.16b,v2.16b
+	add	w13,w13,w17
+	eor	v21.16b,v5.16b,v6.16b
+	add	w14,w14,w19
+	eor	v22.16b,v17.16b,v18.16b
+	add	w15,w15,w20
+	ushr	v1.4s,v20.4s,#20
+	add	w16,w16,w21
+	ushr	v5.4s,v21.4s,#20
+	eor	w9,w9,w13
+	ushr	v17.4s,v22.4s,#20
+	eor	w10,w10,w14
+	sli	v1.4s,v20.4s,#12
+	eor	w11,w11,w15
+	sli	v5.4s,v21.4s,#12
+	eor	w12,w12,w16
+	sli	v17.4s,v22.4s,#12
+	ror	w9,w9,#20
+	add	v0.4s,v0.4s,v1.4s
+	ror	w10,w10,#20
+	add	v4.4s,v4.4s,v5.4s
+	ror	w11,w11,#20
+	add	v16.4s,v16.4s,v17.4s
+	ror	w12,w12,#20
+	eor	v20.16b,v3.16b,v0.16b
+	add	w5,w5,w9
+	eor	v21.16b,v7.16b,v4.16b
+	add	w6,w6,w10
+	eor	v22.16b,v19.16b,v16.16b
+	add	w7,w7,w11
+	ushr	v3.4s,v20.4s,#24
+	add	w8,w8,w12
+	ushr	v7.4s,v21.4s,#24
+	eor	w17,w17,w5
+	ushr	v19.4s,v22.4s,#24
+	eor	w19,w19,w6
+	sli	v3.4s,v20.4s,#8
+	eor	w20,w20,w7
+	sli	v7.4s,v21.4s,#8
+	eor	w21,w21,w8
+	sli	v19.4s,v22.4s,#8
+	ror	w17,w17,#24
+	add	v2.4s,v2.4s,v3.4s
+	ror	w19,w19,#24
+	add	v6.4s,v6.4s,v7.4s
+	ror	w20,w20,#24
+	add	v18.4s,v18.4s,v19.4s
+	ror	w21,w21,#24
+	eor	v20.16b,v1.16b,v2.16b
+	add	w13,w13,w17
+	eor	v21.16b,v5.16b,v6.16b
+	add	w14,w14,w19
+	eor	v22.16b,v17.16b,v18.16b
+	add	w15,w15,w20
+	ushr	v1.4s,v20.4s,#25
+	add	w16,w16,w21
+	ushr	v5.4s,v21.4s,#25
+	eor	w9,w9,w13
+	ushr	v17.4s,v22.4s,#25
+	eor	w10,w10,w14
+	sli	v1.4s,v20.4s,#7
+	eor	w11,w11,w15
+	sli	v5.4s,v21.4s,#7
+	eor	w12,w12,w16
+	sli	v17.4s,v22.4s,#7
+	ror	w9,w9,#25
+	ext	v2.16b,v2.16b,v2.16b,#8
+	ror	w10,w10,#25
+	ext	v6.16b,v6.16b,v6.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w10
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w11
+	add	v16.4s,v16.4s,v17.4s
+	add	w7,w7,w12
+	eor	v3.16b,v3.16b,v0.16b
+	add	w8,w8,w9
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w5
+	eor	v19.16b,v19.16b,v16.16b
+	eor	w17,w17,w6
+	rev32	v3.8h,v3.8h
+	eor	w19,w19,w7
+	rev32	v7.8h,v7.8h
+	eor	w20,w20,w8
+	rev32	v19.8h,v19.8h
+	ror	w21,w21,#16
+	add	v2.4s,v2.4s,v3.4s
+	ror	w17,w17,#16
+	add	v6.4s,v6.4s,v7.4s
+	ror	w19,w19,#16
+	add	v18.4s,v18.4s,v19.4s
+	ror	w20,w20,#16
+	eor	v20.16b,v1.16b,v2.16b
+	add	w15,w15,w21
+	eor	v21.16b,v5.16b,v6.16b
+	add	w16,w16,w17
+	eor	v22.16b,v17.16b,v18.16b
+	add	w13,w13,w19
+	ushr	v1.4s,v20.4s,#20
+	add	w14,w14,w20
+	ushr	v5.4s,v21.4s,#20
+	eor	w10,w10,w15
+	ushr	v17.4s,v22.4s,#20
+	eor	w11,w11,w16
+	sli	v1.4s,v20.4s,#12
+	eor	w12,w12,w13
+	sli	v5.4s,v21.4s,#12
+	eor	w9,w9,w14
+	sli	v17.4s,v22.4s,#12
+	ror	w10,w10,#20
+	add	v0.4s,v0.4s,v1.4s
+	ror	w11,w11,#20
+	add	v4.4s,v4.4s,v5.4s
+	ror	w12,w12,#20
+	add	v16.4s,v16.4s,v17.4s
+	ror	w9,w9,#20
+	eor	v20.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v21.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v22.16b,v19.16b,v16.16b
+	add	w7,w7,w12
+	ushr	v3.4s,v20.4s,#24
+	add	w8,w8,w9
+	ushr	v7.4s,v21.4s,#24
+	eor	w21,w21,w5
+	ushr	v19.4s,v22.4s,#24
+	eor	w17,w17,w6
+	sli	v3.4s,v20.4s,#8
+	eor	w19,w19,w7
+	sli	v7.4s,v21.4s,#8
+	eor	w20,w20,w8
+	sli	v19.4s,v22.4s,#8
+	ror	w21,w21,#24
+	add	v2.4s,v2.4s,v3.4s
+	ror	w17,w17,#24
+	add	v6.4s,v6.4s,v7.4s
+	ror	w19,w19,#24
+	add	v18.4s,v18.4s,v19.4s
+	ror	w20,w20,#24
+	eor	v20.16b,v1.16b,v2.16b
+	add	w15,w15,w21
+	eor	v21.16b,v5.16b,v6.16b
+	add	w16,w16,w17
+	eor	v22.16b,v17.16b,v18.16b
+	add	w13,w13,w19
+	ushr	v1.4s,v20.4s,#25
+	add	w14,w14,w20
+	ushr	v5.4s,v21.4s,#25
+	eor	w10,w10,w15
+	ushr	v17.4s,v22.4s,#25
+	eor	w11,w11,w16
+	sli	v1.4s,v20.4s,#7
+	eor	w12,w12,w13
+	sli	v5.4s,v21.4s,#7
+	eor	w9,w9,w14
+	sli	v17.4s,v22.4s,#7
+	ror	w10,w10,#25
+	ext	v2.16b,v2.16b,v2.16b,#8
+	ror	w11,w11,#25
+	ext	v6.16b,v6.16b,v6.16b,#8
+	ror	w12,w12,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	cbnz	x4,.Loop_neon
+
+	add	w5,w5,w22		// accumulate key block
+	add	v0.4s,v0.4s,v24.4s
+	add	x6,x6,x22,lsr#32
+	add	v4.4s,v4.4s,v24.4s
+	add	w7,w7,w23
+	add	v16.4s,v16.4s,v24.4s
+	add	x8,x8,x23,lsr#32
+	add	v2.4s,v2.4s,v26.4s
+	add	w9,w9,w24
+	add	v6.4s,v6.4s,v26.4s
+	add	x10,x10,x24,lsr#32
+	add	v18.4s,v18.4s,v26.4s
+	add	w11,w11,w25
+	add	v3.4s,v3.4s,v27.4s
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	v7.4s,v7.4s,v28.4s
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	v19.4s,v19.4s,v29.4s
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	v1.4s,v1.4s,v25.4s
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	v5.4s,v5.4s,v25.4s
+	add	x21,x21,x30,lsr#32
+	add	v17.4s,v17.4s,v25.4s
+
+	b.lo	.Ltail_neon
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	v0.16b,v0.16b,v20.16b
+	eor	x15,x15,x16
+	eor	v1.16b,v1.16b,v21.16b
+	eor	x17,x17,x19
+	eor	v2.16b,v2.16b,v22.16b
+	eor	x20,x20,x21
+	eor	v3.16b,v3.16b,v23.16b
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#4			// increment counter
+	stp	x9,x11,[x0,#16]
+	add	v27.4s,v27.4s,v31.4s		// += 4
+	stp	x13,x15,[x0,#32]
+	add	v28.4s,v28.4s,v31.4s
+	stp	x17,x20,[x0,#48]
+	add	v29.4s,v29.4s,v31.4s
+	add	x0,x0,#64
+
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+	ld1	{v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+
+	eor	v4.16b,v4.16b,v20.16b
+	eor	v5.16b,v5.16b,v21.16b
+	eor	v6.16b,v6.16b,v22.16b
+	eor	v7.16b,v7.16b,v23.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+	eor	v16.16b,v16.16b,v0.16b
+	eor	v17.16b,v17.16b,v1.16b
+	eor	v18.16b,v18.16b,v2.16b
+	eor	v19.16b,v19.16b,v3.16b
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+	b.hi	.Loop_outer_neon
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+
+.Ltail_neon:
+	add	x2,x2,#256
+	cmp	x2,#64
+	b.lo	.Less_than_64
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#4			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+	cmp	x2,#64
+	b.lo	.Less_than_128
+
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	v0.16b,v0.16b,v20.16b
+	eor	v1.16b,v1.16b,v21.16b
+	eor	v2.16b,v2.16b,v22.16b
+	eor	v3.16b,v3.16b,v23.16b
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+	cmp	x2,#64
+	b.lo	.Less_than_192
+
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	v4.16b,v4.16b,v20.16b
+	eor	v5.16b,v5.16b,v21.16b
+	eor	v6.16b,v6.16b,v22.16b
+	eor	v7.16b,v7.16b,v23.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[sp]
+	b	.Last_neon
+
+.Less_than_128:
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[sp]
+	b	.Last_neon
+.Less_than_192:
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[sp]
+	b	.Last_neon
+
+.align	4
+.Last_neon:
+	sub	x0,x0,#1
+	add	x1,x1,x2
+	add	x0,x0,x2
+	add	x4,sp,x2
+	neg	x2,x2
+
+.Loop_tail_neon:
+	ldrb	w10,[x1,x2]
+	ldrb	w11,[x4,x2]
+	add	x2,x2,#1
+	eor	w10,w10,w11
+	strb	w10,[x0,x2]
+	cbnz	x2,.Loop_tail_neon
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+.Ldone_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_neon,.-ChaCha20_neon
+.type	ChaCha20_512_neon,%function
+.align	5
+ChaCha20_512_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+
+.L512_or_more_neon:
+	sub	sp,sp,#128+64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ld1	{v24.4s},[x5],#16
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ld1	{v25.4s,v26.4s},[x3]
+	ldp	x28,x30,[x4]		// load counter
+	ld1	{v27.4s},[x4]
+	ld1	{v31.4s},[x5]
+#ifdef	__ARMEB__
+	rev64	v24.4s,v24.4s
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+	add	v27.4s,v27.4s,v31.4s		// += 1
+	stp	q24,q25,[sp,#0]		// off-load key block, invariant part
+	add	v27.4s,v27.4s,v31.4s		// not typo
+	str	q26,[sp,#32]
+	add	v28.4s,v27.4s,v31.4s
+	add	v29.4s,v28.4s,v31.4s
+	add	v30.4s,v29.4s,v31.4s
+	shl	v31.4s,v31.4s,#2			// 1 -> 4
+
+	stp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	stp	d10,d11,[sp,#128+16]
+	stp	d12,d13,[sp,#128+32]
+	stp	d14,d15,[sp,#128+48]
+
+	sub	x2,x2,#512			// not typo
+
+.Loop_outer_512_neon:
+	mov	v0.16b,v24.16b
+	mov	v4.16b,v24.16b
+	mov	v8.16b,v24.16b
+	mov	v12.16b,v24.16b
+	mov	v16.16b,v24.16b
+	mov	v20.16b,v24.16b
+	mov	v1.16b,v25.16b
+	mov	w5,w22			// unpack key block
+	mov	v5.16b,v25.16b
+	lsr	x6,x22,#32
+	mov	v9.16b,v25.16b
+	mov	w7,w23
+	mov	v13.16b,v25.16b
+	lsr	x8,x23,#32
+	mov	v17.16b,v25.16b
+	mov	w9,w24
+	mov	v21.16b,v25.16b
+	lsr	x10,x24,#32
+	mov	v3.16b,v27.16b
+	mov	w11,w25
+	mov	v7.16b,v28.16b
+	lsr	x12,x25,#32
+	mov	v11.16b,v29.16b
+	mov	w13,w26
+	mov	v15.16b,v30.16b
+	lsr	x14,x26,#32
+	mov	v2.16b,v26.16b
+	mov	w15,w27
+	mov	v6.16b,v26.16b
+	lsr	x16,x27,#32
+	add	v19.4s,v3.4s,v31.4s			// +4
+	mov	w17,w28
+	add	v23.4s,v7.4s,v31.4s			// +4
+	lsr	x19,x28,#32
+	mov	v10.16b,v26.16b
+	mov	w20,w30
+	mov	v14.16b,v26.16b
+	lsr	x21,x30,#32
+	mov	v18.16b,v26.16b
+	stp	q27,q28,[sp,#48]		// off-load key block, variable part
+	mov	v22.16b,v26.16b
+	str	q29,[sp,#80]
+
+	mov	x4,#5
+	subs	x2,x2,#512
+.Loop_upper_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v11.16b,v11.16b,v11.16b,#12
+	ext	v15.16b,v15.16b,v15.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v23.16b,v23.16b,v23.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v9.16b,v9.16b,v9.16b,#4
+	ext	v13.16b,v13.16b,v13.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	ext	v21.16b,v21.16b,v21.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v11.16b,v11.16b,v11.16b,#4
+	ext	v15.16b,v15.16b,v15.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v23.16b,v23.16b,v23.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v9.16b,v9.16b,v9.16b,#12
+	ext	v13.16b,v13.16b,v13.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	ext	v21.16b,v21.16b,v21.16b,#12
+	cbnz	x4,.Loop_upper_neon
+
+	add	w5,w5,w22		// accumulate key block
+	add	x6,x6,x22,lsr#32
+	add	w7,w7,w23
+	add	x8,x8,x23,lsr#32
+	add	w9,w9,w24
+	add	x10,x10,x24,lsr#32
+	add	w11,w11,w25
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	x21,x21,x30,lsr#32
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#1			// increment counter
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	stp	x9,x11,[x0,#16]
+	mov	w7,w23
+	lsr	x8,x23,#32
+	stp	x13,x15,[x0,#32]
+	mov	w9,w24
+	lsr	x10,x24,#32
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	mov	w11,w25
+	lsr	x12,x25,#32
+	mov	w13,w26
+	lsr	x14,x26,#32
+	mov	w15,w27
+	lsr	x16,x27,#32
+	mov	w17,w28
+	lsr	x19,x28,#32
+	mov	w20,w30
+	lsr	x21,x30,#32
+
+	mov	x4,#5
+.Loop_lower_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v11.16b,v11.16b,v11.16b,#12
+	ext	v15.16b,v15.16b,v15.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v23.16b,v23.16b,v23.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v9.16b,v9.16b,v9.16b,#4
+	ext	v13.16b,v13.16b,v13.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	ext	v21.16b,v21.16b,v21.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v11.16b,v11.16b,v11.16b,#4
+	ext	v15.16b,v15.16b,v15.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v23.16b,v23.16b,v23.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v9.16b,v9.16b,v9.16b,#12
+	ext	v13.16b,v13.16b,v13.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	ext	v21.16b,v21.16b,v21.16b,#12
+	cbnz	x4,.Loop_lower_neon
+
+	add	w5,w5,w22		// accumulate key block
+	ldp	q24,q25,[sp,#0]
+	add	x6,x6,x22,lsr#32
+	ldp	q26,q27,[sp,#32]
+	add	w7,w7,w23
+	ldp	q28,q29,[sp,#64]
+	add	x8,x8,x23,lsr#32
+	add	v0.4s,v0.4s,v24.4s
+	add	w9,w9,w24
+	add	v4.4s,v4.4s,v24.4s
+	add	x10,x10,x24,lsr#32
+	add	v8.4s,v8.4s,v24.4s
+	add	w11,w11,w25
+	add	v12.4s,v12.4s,v24.4s
+	add	x12,x12,x25,lsr#32
+	add	v16.4s,v16.4s,v24.4s
+	add	w13,w13,w26
+	add	v20.4s,v20.4s,v24.4s
+	add	x14,x14,x26,lsr#32
+	add	v2.4s,v2.4s,v26.4s
+	add	w15,w15,w27
+	add	v6.4s,v6.4s,v26.4s
+	add	x16,x16,x27,lsr#32
+	add	v10.4s,v10.4s,v26.4s
+	add	w17,w17,w28
+	add	v14.4s,v14.4s,v26.4s
+	add	x19,x19,x28,lsr#32
+	add	v18.4s,v18.4s,v26.4s
+	add	w20,w20,w30
+	add	v22.4s,v22.4s,v26.4s
+	add	x21,x21,x30,lsr#32
+	add	v19.4s,v19.4s,v31.4s			// +4
+	add	x5,x5,x6,lsl#32	// pack
+	add	v23.4s,v23.4s,v31.4s			// +4
+	add	x7,x7,x8,lsl#32
+	add	v3.4s,v3.4s,v27.4s
+	ldp	x6,x8,[x1,#0]		// load input
+	add	v7.4s,v7.4s,v28.4s
+	add	x9,x9,x10,lsl#32
+	add	v11.4s,v11.4s,v29.4s
+	add	x11,x11,x12,lsl#32
+	add	v15.4s,v15.4s,v30.4s
+	ldp	x10,x12,[x1,#16]
+	add	v19.4s,v19.4s,v27.4s
+	add	x13,x13,x14,lsl#32
+	add	v23.4s,v23.4s,v28.4s
+	add	x15,x15,x16,lsl#32
+	add	v1.4s,v1.4s,v25.4s
+	ldp	x14,x16,[x1,#32]
+	add	v5.4s,v5.4s,v25.4s
+	add	x17,x17,x19,lsl#32
+	add	v9.4s,v9.4s,v25.4s
+	add	x20,x20,x21,lsl#32
+	add	v13.4s,v13.4s,v25.4s
+	ldp	x19,x21,[x1,#48]
+	add	v17.4s,v17.4s,v25.4s
+	add	x1,x1,#64
+	add	v21.4s,v21.4s,v25.4s
+
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	ld1	{v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	v0.16b,v0.16b,v24.16b
+	eor	x15,x15,x16
+	eor	v1.16b,v1.16b,v25.16b
+	eor	x17,x17,x19
+	eor	v2.16b,v2.16b,v26.16b
+	eor	x20,x20,x21
+	eor	v3.16b,v3.16b,v27.16b
+	ld1	{v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#7			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+
+	ld1	{v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+	eor	v4.16b,v4.16b,v24.16b
+	eor	v5.16b,v5.16b,v25.16b
+	eor	v6.16b,v6.16b,v26.16b
+	eor	v7.16b,v7.16b,v27.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+	ld1	{v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64
+	eor	v8.16b,v8.16b,v0.16b
+	ldp	q24,q25,[sp,#0]
+	eor	v9.16b,v9.16b,v1.16b
+	ldp	q26,q27,[sp,#32]
+	eor	v10.16b,v10.16b,v2.16b
+	eor	v11.16b,v11.16b,v3.16b
+	st1	{v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64
+
+	ld1	{v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64
+	eor	v12.16b,v12.16b,v4.16b
+	eor	v13.16b,v13.16b,v5.16b
+	eor	v14.16b,v14.16b,v6.16b
+	eor	v15.16b,v15.16b,v7.16b
+	st1	{v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64
+
+	ld1	{v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64
+	eor	v16.16b,v16.16b,v8.16b
+	eor	v17.16b,v17.16b,v9.16b
+	eor	v18.16b,v18.16b,v10.16b
+	eor	v19.16b,v19.16b,v11.16b
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+	shl	v0.4s,v31.4s,#1			// 4 -> 8
+	eor	v20.16b,v20.16b,v12.16b
+	eor	v21.16b,v21.16b,v13.16b
+	eor	v22.16b,v22.16b,v14.16b
+	eor	v23.16b,v23.16b,v15.16b
+	st1	{v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64
+
+	add	v27.4s,v27.4s,v0.4s			// += 8
+	add	v28.4s,v28.4s,v0.4s
+	add	v29.4s,v29.4s,v0.4s
+	add	v30.4s,v30.4s,v0.4s
+
+	b.hs	.Loop_outer_512_neon
+
+	adds	x2,x2,#512
+	ushr	v0.4s,v31.4s,#2			// 4 -> 1
+
+	ldp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	ldp	d10,d11,[sp,#128+16]
+	ldp	d12,d13,[sp,#128+32]
+	ldp	d14,d15,[sp,#128+48]
+
+	stp	q24,q31,[sp,#0]		// wipe off-load area
+	stp	q24,q31,[sp,#32]
+	stp	q24,q31,[sp,#64]
+
+	b.eq	.Ldone_512_neon
+
+	cmp	x2,#192
+	sub	v27.4s,v27.4s,v0.4s			// -= 1
+	sub	v28.4s,v28.4s,v0.4s
+	sub	v29.4s,v29.4s,v0.4s
+	add	sp,sp,#128
+	b.hs	.Loop_outer_neon
+
+	eor	v25.16b,v25.16b,v25.16b
+	eor	v26.16b,v26.16b,v26.16b
+	eor	v27.16b,v27.16b,v27.16b
+	eor	v28.16b,v28.16b,v28.16b
+	eor	v29.16b,v29.16b,v29.16b
+	eor	v30.16b,v30.16b,v30.16b
+	b	.Loop_outer
+
+.Ldone_512_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#128+64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_512_neon,.-ChaCha20_512_neon
+#endif
diff --git a/linux-aarch64/crypto/modes/ghashv8-armx64.S b/linux-aarch64/crypto/modes/ghashv8-armx64.S
index 8d44667..f39f3ba 100644
--- a/linux-aarch64/crypto/modes/ghashv8-armx64.S
+++ b/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -6,6 +6,7 @@
 .arch	armv8-a+crypto
 #endif
 .globl	gcm_init_v8
+.hidden	gcm_init_v8
 .type	gcm_init_v8,%function
 .align	4
 gcm_init_v8:
@@ -56,6 +57,7 @@
 	ret
 .size	gcm_init_v8,.-gcm_init_v8
 .globl	gcm_gmult_v8
+.hidden	gcm_gmult_v8
 .type	gcm_gmult_v8,%function
 .align	4
 gcm_gmult_v8:
@@ -97,6 +99,7 @@
 	ret
 .size	gcm_gmult_v8,.-gcm_gmult_v8
 .globl	gcm_ghash_v8
+.hidden	gcm_ghash_v8
 .type	gcm_ghash_v8,%function
 .align	4
 gcm_ghash_v8:
@@ -229,4 +232,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/sha/sha1-armv8.S b/linux-aarch64/crypto/sha/sha1-armv8.S
index 6cf9877..cfb4aa0 100644
--- a/linux-aarch64/crypto/sha/sha1-armv8.S
+++ b/linux-aarch64/crypto/sha/sha1-armv8.S
@@ -5,6 +5,7 @@
 
 
 .globl	sha1_block_data_order
+.hidden	sha1_block_data_order
 .type	sha1_block_data_order,%function
 .align	6
 sha1_block_data_order:
@@ -1212,4 +1213,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/sha/sha256-armv8.S b/linux-aarch64/crypto/sha/sha256-armv8.S
index 0fad009..bfc552c 100644
--- a/linux-aarch64/crypto/sha/sha256-armv8.S
+++ b/linux-aarch64/crypto/sha/sha256-armv8.S
@@ -5,6 +5,7 @@
 
 
 .globl	sha256_block_data_order
+.hidden	sha256_block_data_order
 .type	sha256_block_data_order,%function
 .align	6
 sha256_block_data_order:
@@ -1142,4 +1143,4 @@
 	ret
 .size	sha256_block_armv8,.-sha256_block_armv8
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/sha/sha512-armv8.S b/linux-aarch64/crypto/sha/sha512-armv8.S
index 517c033..4645722 100644
--- a/linux-aarch64/crypto/sha/sha512-armv8.S
+++ b/linux-aarch64/crypto/sha/sha512-armv8.S
@@ -5,6 +5,7 @@
 
 
 .globl	sha512_block_data_order
+.hidden	sha512_block_data_order
 .type	sha512_block_data_order,%function
 .align	6
 sha512_block_data_order:
@@ -1022,4 +1023,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/aes/aes-armv4.S b/linux-arm/crypto/aes/aes-armv4.S
index c4d7065..bc11e3f 100644
--- a/linux-arm/crypto/aes/aes-armv4.S
+++ b/linux-arm/crypto/aes/aes-armv4.S
@@ -1197,4 +1197,4 @@
 .align	2
 
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/aes/aesv8-armx32.S b/linux-arm/crypto/aes/aesv8-armx32.S
index 6012b0c..95a2ea4 100644
--- a/linux-arm/crypto/aes/aesv8-armx32.S
+++ b/linux-arm/crypto/aes/aesv8-armx32.S
@@ -13,6 +13,7 @@
 .long	0x1b,0x1b,0x1b,0x1b
 
 .globl	aes_v8_set_encrypt_key
+.hidden	aes_v8_set_encrypt_key
 .type	aes_v8_set_encrypt_key,%function
 .align	5
 aes_v8_set_encrypt_key:
@@ -183,6 +184,7 @@
 .size	aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
 
 .globl	aes_v8_set_decrypt_key
+.hidden	aes_v8_set_decrypt_key
 .type	aes_v8_set_decrypt_key,%function
 .align	5
 aes_v8_set_decrypt_key:
@@ -220,6 +222,7 @@
 	ldmia	sp!,{r4,pc}
 .size	aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
 .globl	aes_v8_encrypt
+.hidden	aes_v8_encrypt
 .type	aes_v8_encrypt,%function
 .align	5
 aes_v8_encrypt:
@@ -249,6 +252,7 @@
 	bx	lr
 .size	aes_v8_encrypt,.-aes_v8_encrypt
 .globl	aes_v8_decrypt
+.hidden	aes_v8_decrypt
 .type	aes_v8_decrypt,%function
 .align	5
 aes_v8_decrypt:
@@ -278,6 +282,7 @@
 	bx	lr
 .size	aes_v8_decrypt,.-aes_v8_decrypt
 .globl	aes_v8_cbc_encrypt
+.hidden	aes_v8_cbc_encrypt
 .type	aes_v8_cbc_encrypt,%function
 .align	5
 aes_v8_cbc_encrypt:
@@ -570,6 +575,7 @@
 	ldmia	sp!,{r4,r5,r6,r7,r8,pc}
 .size	aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
 .globl	aes_v8_ctr32_encrypt_blocks
+.hidden	aes_v8_ctr32_encrypt_blocks
 .type	aes_v8_ctr32_encrypt_blocks,%function
 .align	5
 aes_v8_ctr32_encrypt_blocks:
@@ -753,4 +759,4 @@
 	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,pc}
 .size	aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index a3ebec8..abb414d 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -2574,4 +2574,4 @@
 
 .size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/bn/armv4-mont.S b/linux-arm/crypto/bn/armv4-mont.S
index fc671e8..e59599f 100644
--- a/linux-arm/crypto/bn/armv4-mont.S
+++ b/linux-arm/crypto/bn/armv4-mont.S
@@ -28,7 +28,7 @@
 #ifdef	__APPLE__
 	ldr	r0,[r0]
 #endif
-	tst	r0,#1			@ NEON available?
+	tst	r0,#ARMV7_NEON		@ NEON available?
 	ldmia	sp, {r0,r2}
 	beq	.Lialu
 	add	sp,sp,#8
@@ -586,4 +586,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/chacha/chacha-armv4.S b/linux-arm/crypto/chacha/chacha-armv4.S
new file mode 100644
index 0000000..19a4d2c
--- /dev/null
+++ b/linux-arm/crypto/chacha/chacha-armv4.S
@@ -0,0 +1,1471 @@
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax	unified
+.thumb
+#else
+.code	32
+#endif
+
+#if defined(__thumb2__) || defined(__clang__)
+#define ldrhsb	ldrbhs
+#endif
+
+.align	5
+.Lsigma:
+.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
+.Lone:
+.long	1,0,0,0
+#if __ARM_MAX_ARCH__>=7
+.LOPENSSL_armcap:
+.word	OPENSSL_armcap_P-.LChaCha20_ctr32
+#else
+.word	-1
+#endif
+
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+.LChaCha20_ctr32:
+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
+	sub	r14,pc,#16		@ ChaCha20_ctr32
+#else
+	adr	r14,.LChaCha20_ctr32
+#endif
+	cmp	r2,#0			@ len==0?
+#ifdef	__thumb2__
+	itt	eq
+#endif
+	addeq	sp,sp,#4*3
+	beq	.Lno_data
+#if __ARM_MAX_ARCH__>=7
+	cmp	r2,#192			@ test len
+	bls	.Lshort
+	ldr	r4,[r14,#-32]
+	ldr	r4,[r14,r4]
+# ifdef	__APPLE__
+	ldr	r4,[r4]
+# endif
+	tst	r4,#ARMV7_NEON
+	bne	.LChaCha20_neon
+.Lshort:
+#endif
+	ldmia	r12,{r4,r5,r6,r7}		@ load counter and nonce
+	sub	sp,sp,#4*(16)		@ off-load area
+	sub	r14,r14,#64		@ .Lsigma
+	stmdb	sp!,{r4,r5,r6,r7}		@ copy counter and nonce
+	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
+	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
+	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11}		@ copy key
+	stmdb	sp!,{r0,r1,r2,r3}		@ copy sigma
+	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
+	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
+	b	.Loop_outer_enter
+
+.align	4
+.Loop_outer:
+	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
+	str	r11,[sp,#4*(32+2)]	@ save len
+	str	r12,  [sp,#4*(32+1)]	@ save inp
+	str	r14,  [sp,#4*(32+0)]	@ save out
+.Loop_outer_enter:
+	ldr	r11, [sp,#4*(15)]
+	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
+	ldr	r10, [sp,#4*(13)]
+	ldr	r14,[sp,#4*(14)]
+	str	r11, [sp,#4*(16+15)]
+	mov	r11,#10
+	b	.Loop
+
+.align	4
+.Loop:
+	subs	r11,r11,#1
+	add	r0,r0,r4
+	mov	r12,r12,ror#16
+	add	r1,r1,r5
+	mov	r10,r10,ror#16
+	eor	r12,r12,r0,ror#16
+	eor	r10,r10,r1,ror#16
+	add	r8,r8,r12
+	mov	r4,r4,ror#20
+	add	r9,r9,r10
+	mov	r5,r5,ror#20
+	eor	r4,r4,r8,ror#20
+	eor	r5,r5,r9,ror#20
+	add	r0,r0,r4
+	mov	r12,r12,ror#24
+	add	r1,r1,r5
+	mov	r10,r10,ror#24
+	eor	r12,r12,r0,ror#24
+	eor	r10,r10,r1,ror#24
+	add	r8,r8,r12
+	mov	r4,r4,ror#25
+	add	r9,r9,r10
+	mov	r5,r5,ror#25
+	str	r10,[sp,#4*(16+13)]
+	ldr	r10,[sp,#4*(16+15)]
+	eor	r4,r4,r8,ror#25
+	eor	r5,r5,r9,ror#25
+	str	r8,[sp,#4*(16+8)]
+	ldr	r8,[sp,#4*(16+10)]
+	add	r2,r2,r6
+	mov	r14,r14,ror#16
+	str	r9,[sp,#4*(16+9)]
+	ldr	r9,[sp,#4*(16+11)]
+	add	r3,r3,r7
+	mov	r10,r10,ror#16
+	eor	r14,r14,r2,ror#16
+	eor	r10,r10,r3,ror#16
+	add	r8,r8,r14
+	mov	r6,r6,ror#20
+	add	r9,r9,r10
+	mov	r7,r7,ror#20
+	eor	r6,r6,r8,ror#20
+	eor	r7,r7,r9,ror#20
+	add	r2,r2,r6
+	mov	r14,r14,ror#24
+	add	r3,r3,r7
+	mov	r10,r10,ror#24
+	eor	r14,r14,r2,ror#24
+	eor	r10,r10,r3,ror#24
+	add	r8,r8,r14
+	mov	r6,r6,ror#25
+	add	r9,r9,r10
+	mov	r7,r7,ror#25
+	eor	r6,r6,r8,ror#25
+	eor	r7,r7,r9,ror#25
+	add	r0,r0,r5
+	mov	r10,r10,ror#16
+	add	r1,r1,r6
+	mov	r12,r12,ror#16
+	eor	r10,r10,r0,ror#16
+	eor	r12,r12,r1,ror#16
+	add	r8,r8,r10
+	mov	r5,r5,ror#20
+	add	r9,r9,r12
+	mov	r6,r6,ror#20
+	eor	r5,r5,r8,ror#20
+	eor	r6,r6,r9,ror#20
+	add	r0,r0,r5
+	mov	r10,r10,ror#24
+	add	r1,r1,r6
+	mov	r12,r12,ror#24
+	eor	r10,r10,r0,ror#24
+	eor	r12,r12,r1,ror#24
+	add	r8,r8,r10
+	mov	r5,r5,ror#25
+	str	r10,[sp,#4*(16+15)]
+	ldr	r10,[sp,#4*(16+13)]
+	add	r9,r9,r12
+	mov	r6,r6,ror#25
+	eor	r5,r5,r8,ror#25
+	eor	r6,r6,r9,ror#25
+	str	r8,[sp,#4*(16+10)]
+	ldr	r8,[sp,#4*(16+8)]
+	add	r2,r2,r7
+	mov	r10,r10,ror#16
+	str	r9,[sp,#4*(16+11)]
+	ldr	r9,[sp,#4*(16+9)]
+	add	r3,r3,r4
+	mov	r14,r14,ror#16
+	eor	r10,r10,r2,ror#16
+	eor	r14,r14,r3,ror#16
+	add	r8,r8,r10
+	mov	r7,r7,ror#20
+	add	r9,r9,r14
+	mov	r4,r4,ror#20
+	eor	r7,r7,r8,ror#20
+	eor	r4,r4,r9,ror#20
+	add	r2,r2,r7
+	mov	r10,r10,ror#24
+	add	r3,r3,r4
+	mov	r14,r14,ror#24
+	eor	r10,r10,r2,ror#24
+	eor	r14,r14,r3,ror#24
+	add	r8,r8,r10
+	mov	r7,r7,ror#25
+	add	r9,r9,r14
+	mov	r4,r4,ror#25
+	eor	r7,r7,r8,ror#25
+	eor	r4,r4,r9,ror#25
+	bne	.Loop
+
+	ldr	r11,[sp,#4*(32+2)]	@ load len
+
+	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
+	str	r9, [sp,#4*(16+9)]
+	str	r12,[sp,#4*(16+12)]
+	str	r10, [sp,#4*(16+13)]
+	str	r14,[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ rx and second half at sp+4*(16+8)
+
+	cmp	r11,#64		@ done yet?
+#ifdef	__thumb2__
+	itete	lo
+#endif
+	addlo	r12,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r12,[sp,#4*(32+1)]	@ ... load inp
+	addlo	r14,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r14,[sp,#4*(32+0)]	@ ... load out
+
+	ldr	r8,[sp,#4*(0)]	@ load key material
+	ldr	r9,[sp,#4*(1)]
+
+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
+# if __ARM_ARCH__<7
+	orr	r10,r12,r14
+	tst	r10,#3		@ are input and output aligned?
+	ldr	r10,[sp,#4*(2)]
+	bne	.Lunaligned
+	cmp	r11,#64		@ restore flags
+# else
+	ldr	r10,[sp,#4*(2)]
+# endif
+	ldr	r11,[sp,#4*(3)]
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r1,r1,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+
+	add	r2,r2,r10
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r0,r0,r8	@ xor with input
+	eorhs	r1,r1,r9
+	add	r8,sp,#4*(4)
+	str	r0,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r2,r2,r10
+	eorhs	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r1,[r14,#-12]
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r5,r5,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+	add	r6,r6,r10
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r4,r4,r8
+	eorhs	r5,r5,r9
+	add	r8,sp,#4*(8)
+	str	r4,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r6,r6,r10
+	eorhs	r7,r7,r11
+	str	r5,[r14,#-12]
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r6,[r14,#-8]
+	add	r0,sp,#4*(16+8)
+	str	r7,[r14,#-4]
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r1,r1,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
+	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
+	add	r2,r2,r10
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r0,r0,r8
+	eorhs	r1,r1,r9
+	add	r8,sp,#4*(12)
+	str	r0,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r2,r2,r10
+	eorhs	r3,r3,r11
+	str	r1,[r14,#-12]
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r5,r5,r9
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	addhi	r8,r8,#1		@ next counter value
+	strhi	r8,[sp,#4*(12)]	@ save next counter value
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+	add	r6,r6,r10
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r4,r4,r8
+	eorhs	r5,r5,r9
+# ifdef	__thumb2__
+	it	ne
+# endif
+	ldrne	r8,[sp,#4*(32+2)]	@ re-load len
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r6,r6,r10
+	eorhs	r7,r7,r11
+	str	r4,[r14],#16		@ store output
+	str	r5,[r14,#-12]
+# ifdef	__thumb2__
+	it	hs
+# endif
+	subhs	r11,r8,#64		@ len-=64
+	str	r6,[r14,#-8]
+	str	r7,[r14,#-4]
+	bhi	.Loop_outer
+
+	beq	.Ldone
+# if __ARM_ARCH__<7
+	b	.Ltail
+
+.align	4
+.Lunaligned:@ unaligned endian-neutral path
+	cmp	r11,#64		@ restore flags
+# endif
+#endif
+#if __ARM_ARCH__<7
+	ldr	r11,[sp,#4*(3)]
+	add	r0,r0,r8		@ accumulate key material
+	add	r1,r1,r9
+	add	r2,r2,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r0,r8,r0		@ xor with input (or zero)
+	eor	r1,r9,r1
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r2,r10,r2
+	strb	r0,[r14],#16		@ store output
+	eor	r3,r11,r3
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r1,[r14,#-12]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-8]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r3,[r14,#-4]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-15]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r1,[r14,#-11]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-7]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r3,[r14,#-3]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-14]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r1,[r14,#-10]
+	strb	r2,[r14,#-6]
+	eor	r0,r8,r0,lsr#8
+	strb	r3,[r14,#-2]
+	eor	r1,r9,r1,lsr#8
+	strb	r0,[r14,#-13]
+	eor	r2,r10,r2,lsr#8
+	strb	r1,[r14,#-9]
+	eor	r3,r11,r3,lsr#8
+	strb	r2,[r14,#-5]
+	strb	r3,[r14,#-1]
+	add	r8,sp,#4*(4+0)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	add	r0,sp,#4*(16+8)
+	add	r4,r4,r8		@ accumulate key material
+	add	r5,r5,r9
+	add	r6,r6,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r4,r8,r4		@ xor with input (or zero)
+	eor	r5,r9,r5
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r6,r10,r6
+	strb	r4,[r14],#16		@ store output
+	eor	r7,r11,r7
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r5,[r14,#-12]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-8]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r7,[r14,#-4]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-15]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r5,[r14,#-11]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-7]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r7,[r14,#-3]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-14]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r5,[r14,#-10]
+	strb	r6,[r14,#-6]
+	eor	r4,r8,r4,lsr#8
+	strb	r7,[r14,#-2]
+	eor	r5,r9,r5,lsr#8
+	strb	r4,[r14,#-13]
+	eor	r6,r10,r6,lsr#8
+	strb	r5,[r14,#-9]
+	eor	r7,r11,r7,lsr#8
+	strb	r6,[r14,#-5]
+	strb	r7,[r14,#-1]
+	add	r8,sp,#4*(4+4)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}		@ load second half
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]		@ copy "rx"
+	strhi	r11,[sp,#4*(16+11)]		@ copy "rx"
+	add	r0,r0,r8		@ accumulate key material
+	add	r1,r1,r9
+	add	r2,r2,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r0,r8,r0		@ xor with input (or zero)
+	eor	r1,r9,r1
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r2,r10,r2
+	strb	r0,[r14],#16		@ store output
+	eor	r3,r11,r3
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r1,[r14,#-12]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-8]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r3,[r14,#-4]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-15]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r1,[r14,#-11]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-7]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r3,[r14,#-3]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-14]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r1,[r14,#-10]
+	strb	r2,[r14,#-6]
+	eor	r0,r8,r0,lsr#8
+	strb	r3,[r14,#-2]
+	eor	r1,r9,r1,lsr#8
+	strb	r0,[r14,#-13]
+	eor	r2,r10,r2,lsr#8
+	strb	r1,[r14,#-9]
+	eor	r3,r11,r3,lsr#8
+	strb	r2,[r14,#-5]
+	strb	r3,[r14,#-1]
+	add	r8,sp,#4*(4+8)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	add	r4,r4,r8		@ accumulate key material
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	addhi	r8,r8,#1			@ next counter value
+	strhi	r8,[sp,#4*(12)]		@ save next counter value
+	add	r5,r5,r9
+	add	r6,r6,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r4,r8,r4		@ xor with input (or zero)
+	eor	r5,r9,r5
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r6,r10,r6
+	strb	r4,[r14],#16		@ store output
+	eor	r7,r11,r7
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r5,[r14,#-12]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-8]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r7,[r14,#-4]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-15]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r5,[r14,#-11]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-7]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r7,[r14,#-3]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-14]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r5,[r14,#-10]
+	strb	r6,[r14,#-6]
+	eor	r4,r8,r4,lsr#8
+	strb	r7,[r14,#-2]
+	eor	r5,r9,r5,lsr#8
+	strb	r4,[r14,#-13]
+	eor	r6,r10,r6,lsr#8
+	strb	r5,[r14,#-9]
+	eor	r7,r11,r7,lsr#8
+	strb	r6,[r14,#-5]
+	strb	r7,[r14,#-1]
+# ifdef	__thumb2__
+	it	ne
+# endif
+	ldrne	r8,[sp,#4*(32+2)]		@ re-load len
+# ifdef	__thumb2__
+	it	hs
+# endif
+	subhs	r11,r8,#64			@ len-=64
+	bhi	.Loop_outer
+
+	beq	.Ldone
+#endif
+
+.Ltail:
+	ldr	r12,[sp,#4*(32+1)]	@ load inp
+	add	r9,sp,#4*(0)
+	ldr	r14,[sp,#4*(32+0)]	@ load out
+
+.Loop_tail:
+	ldrb	r10,[r9],#1	@ read buffer on stack
+	ldrb	r11,[r12],#1		@ read input
+	subs	r8,r8,#1
+	eor	r11,r11,r10
+	strb	r11,[r14],#1		@ store output
+	bne	.Loop_tail
+
+.Ldone:
+	add	sp,sp,#4*(32+3)
+.Lno_data:
+	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+#if __ARM_MAX_ARCH__>=7
+.arch	armv7-a
+.fpu	neon
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
+.LChaCha20_neon:
+	adr	r14,.Lsigma
+	vstmdb	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}		@ ABI spec says so
+	stmdb	sp!,{r0,r1,r2,r3}
+
+	vld1.32	{q1,q2},[r3]		@ load key
+	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
+
+	sub	sp,sp,#4*(16+16)
+	vld1.32	{q3},[r12]		@ load counter and nonce
+	add	r12,sp,#4*8
+	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
+	vld1.32	{q0},[r14]!		@ load sigma
+	vld1.32	{q12},[r14]		@ one
+	vst1.32	{q2,q3},[r12]		@ copy 1/2key|counter|nonce
+	vst1.32	{q0,q1},[sp]		@ copy sigma|1/2key
+
+	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
+	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
+	vshl.i32	d26,d24,#1	@ two
+	vstr	d24,[sp,#4*(16+0)]
+	vshl.i32	d28,d24,#2	@ four
+	vstr	d26,[sp,#4*(16+2)]
+	vmov	q4,q0
+	vstr	d28,[sp,#4*(16+4)]
+	vmov	q8,q0
+	vmov	q5,q1
+	vmov	q9,q1
+	b	.Loop_neon_enter
+
+.align	4
+.Loop_neon_outer:
+	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
+	cmp	r11,#64*2		@ if len<=64*2
+	bls	.Lbreak_neon		@ switch to integer-only
+	vmov	q4,q0
+	str	r11,[sp,#4*(32+2)]	@ save len
+	vmov	q8,q0
+	str	r12,  [sp,#4*(32+1)]	@ save inp
+	vmov	q5,q1
+	str	r14,  [sp,#4*(32+0)]	@ save out
+	vmov	q9,q1
+.Loop_neon_enter:
+	ldr	r11, [sp,#4*(15)]
+	vadd.i32	q7,q3,q12		@ counter+1
+	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
+	vmov	q6,q2
+	ldr	r10, [sp,#4*(13)]
+	vmov	q10,q2
+	ldr	r14,[sp,#4*(14)]
+	vadd.i32	q11,q7,q12		@ counter+2
+	str	r11, [sp,#4*(16+15)]
+	mov	r11,#10
+	add	r12,r12,#3	@ counter+3
+	b	.Loop_neon
+
+.align	4
+.Loop_neon:
+	subs	r11,r11,#1
+	vadd.i32	q0,q0,q1
+	add	r0,r0,r4
+	vadd.i32	q4,q4,q5
+	mov	r12,r12,ror#16
+	vadd.i32	q8,q8,q9
+	add	r1,r1,r5
+	veor	q3,q3,q0
+	mov	r10,r10,ror#16
+	veor	q7,q7,q4
+	eor	r12,r12,r0,ror#16
+	veor	q11,q11,q8
+	eor	r10,r10,r1,ror#16
+	vrev32.16	q3,q3
+	add	r8,r8,r12
+	vrev32.16	q7,q7
+	mov	r4,r4,ror#20
+	vrev32.16	q11,q11
+	add	r9,r9,r10
+	vadd.i32	q2,q2,q3
+	mov	r5,r5,ror#20
+	vadd.i32	q6,q6,q7
+	eor	r4,r4,r8,ror#20
+	vadd.i32	q10,q10,q11
+	eor	r5,r5,r9,ror#20
+	veor	q12,q1,q2
+	add	r0,r0,r4
+	veor	q13,q5,q6
+	mov	r12,r12,ror#24
+	veor	q14,q9,q10
+	add	r1,r1,r5
+	vshr.u32	q1,q12,#20
+	mov	r10,r10,ror#24
+	vshr.u32	q5,q13,#20
+	eor	r12,r12,r0,ror#24
+	vshr.u32	q9,q14,#20
+	eor	r10,r10,r1,ror#24
+	vsli.32	q1,q12,#12
+	add	r8,r8,r12
+	vsli.32	q5,q13,#12
+	mov	r4,r4,ror#25
+	vsli.32	q9,q14,#12
+	add	r9,r9,r10
+	vadd.i32	q0,q0,q1
+	mov	r5,r5,ror#25
+	vadd.i32	q4,q4,q5
+	str	r10,[sp,#4*(16+13)]
+	vadd.i32	q8,q8,q9
+	ldr	r10,[sp,#4*(16+15)]
+	veor	q12,q3,q0
+	eor	r4,r4,r8,ror#25
+	veor	q13,q7,q4
+	eor	r5,r5,r9,ror#25
+	veor	q14,q11,q8
+	str	r8,[sp,#4*(16+8)]
+	vshr.u32	q3,q12,#24
+	ldr	r8,[sp,#4*(16+10)]
+	vshr.u32	q7,q13,#24
+	add	r2,r2,r6
+	vshr.u32	q11,q14,#24
+	mov	r14,r14,ror#16
+	vsli.32	q3,q12,#8
+	str	r9,[sp,#4*(16+9)]
+	vsli.32	q7,q13,#8
+	ldr	r9,[sp,#4*(16+11)]
+	vsli.32	q11,q14,#8
+	add	r3,r3,r7
+	vadd.i32	q2,q2,q3
+	mov	r10,r10,ror#16
+	vadd.i32	q6,q6,q7
+	eor	r14,r14,r2,ror#16
+	vadd.i32	q10,q10,q11
+	eor	r10,r10,r3,ror#16
+	veor	q12,q1,q2
+	add	r8,r8,r14
+	veor	q13,q5,q6
+	mov	r6,r6,ror#20
+	veor	q14,q9,q10
+	add	r9,r9,r10
+	vshr.u32	q1,q12,#25
+	mov	r7,r7,ror#20
+	vshr.u32	q5,q13,#25
+	eor	r6,r6,r8,ror#20
+	vshr.u32	q9,q14,#25
+	eor	r7,r7,r9,ror#20
+	vsli.32	q1,q12,#7
+	add	r2,r2,r6
+	vsli.32	q5,q13,#7
+	mov	r14,r14,ror#24
+	vsli.32	q9,q14,#7
+	add	r3,r3,r7
+	vext.8	q2,q2,q2,#8
+	mov	r10,r10,ror#24
+	vext.8	q6,q6,q6,#8
+	eor	r14,r14,r2,ror#24
+	vext.8	q10,q10,q10,#8
+	eor	r10,r10,r3,ror#24
+	vext.8	q1,q1,q1,#4
+	add	r8,r8,r14
+	vext.8	q5,q5,q5,#4
+	mov	r6,r6,ror#25
+	vext.8	q9,q9,q9,#4
+	add	r9,r9,r10
+	vext.8	q3,q3,q3,#12
+	mov	r7,r7,ror#25
+	vext.8	q7,q7,q7,#12
+	eor	r6,r6,r8,ror#25
+	vext.8	q11,q11,q11,#12
+	eor	r7,r7,r9,ror#25
+	vadd.i32	q0,q0,q1
+	add	r0,r0,r5
+	vadd.i32	q4,q4,q5
+	mov	r10,r10,ror#16
+	vadd.i32	q8,q8,q9
+	add	r1,r1,r6
+	veor	q3,q3,q0
+	mov	r12,r12,ror#16
+	veor	q7,q7,q4
+	eor	r10,r10,r0,ror#16
+	veor	q11,q11,q8
+	eor	r12,r12,r1,ror#16
+	vrev32.16	q3,q3
+	add	r8,r8,r10
+	vrev32.16	q7,q7
+	mov	r5,r5,ror#20
+	vrev32.16	q11,q11
+	add	r9,r9,r12
+	vadd.i32	q2,q2,q3
+	mov	r6,r6,ror#20
+	vadd.i32	q6,q6,q7
+	eor	r5,r5,r8,ror#20
+	vadd.i32	q10,q10,q11
+	eor	r6,r6,r9,ror#20
+	veor	q12,q1,q2
+	add	r0,r0,r5
+	veor	q13,q5,q6
+	mov	r10,r10,ror#24
+	veor	q14,q9,q10
+	add	r1,r1,r6
+	vshr.u32	q1,q12,#20
+	mov	r12,r12,ror#24
+	vshr.u32	q5,q13,#20
+	eor	r10,r10,r0,ror#24
+	vshr.u32	q9,q14,#20
+	eor	r12,r12,r1,ror#24
+	vsli.32	q1,q12,#12
+	add	r8,r8,r10
+	vsli.32	q5,q13,#12
+	mov	r5,r5,ror#25
+	vsli.32	q9,q14,#12
+	str	r10,[sp,#4*(16+15)]
+	vadd.i32	q0,q0,q1
+	ldr	r10,[sp,#4*(16+13)]
+	vadd.i32	q4,q4,q5
+	add	r9,r9,r12
+	vadd.i32	q8,q8,q9
+	mov	r6,r6,ror#25
+	veor	q12,q3,q0
+	eor	r5,r5,r8,ror#25
+	veor	q13,q7,q4
+	eor	r6,r6,r9,ror#25
+	veor	q14,q11,q8
+	str	r8,[sp,#4*(16+10)]
+	vshr.u32	q3,q12,#24
+	ldr	r8,[sp,#4*(16+8)]
+	vshr.u32	q7,q13,#24
+	add	r2,r2,r7
+	vshr.u32	q11,q14,#24
+	mov	r10,r10,ror#16
+	vsli.32	q3,q12,#8
+	str	r9,[sp,#4*(16+11)]
+	vsli.32	q7,q13,#8
+	ldr	r9,[sp,#4*(16+9)]
+	vsli.32	q11,q14,#8
+	add	r3,r3,r4
+	vadd.i32	q2,q2,q3
+	mov	r14,r14,ror#16
+	vadd.i32	q6,q6,q7
+	eor	r10,r10,r2,ror#16
+	vadd.i32	q10,q10,q11
+	eor	r14,r14,r3,ror#16
+	veor	q12,q1,q2
+	add	r8,r8,r10
+	veor	q13,q5,q6
+	mov	r7,r7,ror#20
+	veor	q14,q9,q10
+	add	r9,r9,r14
+	vshr.u32	q1,q12,#25
+	mov	r4,r4,ror#20
+	vshr.u32	q5,q13,#25
+	eor	r7,r7,r8,ror#20
+	vshr.u32	q9,q14,#25
+	eor	r4,r4,r9,ror#20
+	vsli.32	q1,q12,#7
+	add	r2,r2,r7
+	vsli.32	q5,q13,#7
+	mov	r10,r10,ror#24
+	vsli.32	q9,q14,#7
+	add	r3,r3,r4
+	vext.8	q2,q2,q2,#8
+	mov	r14,r14,ror#24
+	vext.8	q6,q6,q6,#8
+	eor	r10,r10,r2,ror#24
+	vext.8	q10,q10,q10,#8
+	eor	r14,r14,r3,ror#24
+	vext.8	q1,q1,q1,#12
+	add	r8,r8,r10
+	vext.8	q5,q5,q5,#12
+	mov	r7,r7,ror#25
+	vext.8	q9,q9,q9,#12
+	add	r9,r9,r14
+	vext.8	q3,q3,q3,#4
+	mov	r4,r4,ror#25
+	vext.8	q7,q7,q7,#4
+	eor	r7,r7,r8,ror#25
+	vext.8	q11,q11,q11,#4
+	eor	r4,r4,r9,ror#25
+	bne	.Loop_neon
+
+	add	r11,sp,#32
+	vld1.32	{q12,q13},[sp]		@ load key material
+	vld1.32	{q14,q15},[r11]
+
+	ldr	r11,[sp,#4*(32+2)]	@ load len
+
+	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
+	str	r9, [sp,#4*(16+9)]
+	str	r12,[sp,#4*(16+12)]
+	str	r10, [sp,#4*(16+13)]
+	str	r14,[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ rx and second half at sp+4*(16+8)
+
+	ldr	r12,[sp,#4*(32+1)]	@ load inp
+	ldr	r14,[sp,#4*(32+0)]	@ load out
+
+	vadd.i32	q0,q0,q12		@ accumulate key material
+	vadd.i32	q4,q4,q12
+	vadd.i32	q8,q8,q12
+	vldr	d24,[sp,#4*(16+0)]	@ one
+
+	vadd.i32	q1,q1,q13
+	vadd.i32	q5,q5,q13
+	vadd.i32	q9,q9,q13
+	vldr	d26,[sp,#4*(16+2)]	@ two
+
+	vadd.i32	q2,q2,q14
+	vadd.i32	q6,q6,q14
+	vadd.i32	q10,q10,q14
+	vadd.i32	d14,d14,d24	@ counter+1
+	vadd.i32	d22,d22,d26	@ counter+2
+
+	vadd.i32	q3,q3,q15
+	vadd.i32	q7,q7,q15
+	vadd.i32	q11,q11,q15
+
+	cmp	r11,#64*4
+	blo	.Ltail_neon
+
+	vld1.8	{q12,q13},[r12]!	@ load input
+	mov	r11,sp
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12		@ xor with input
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	vst1.8	{q0,q1},[r14]!	@ store output
+	veor	q5,q5,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q6,q6,q14
+	vst1.8	{q2,q3},[r14]!
+	veor	q7,q7,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q8,q8,q12
+	vld1.32	{q0,q1},[r11]!	@ load for next iteration
+	veor	d25,d25,d25
+	vldr	d24,[sp,#4*(16+4)]	@ four
+	veor	q9,q9,q13
+	vld1.32	{q2,q3},[r11]
+	veor	q10,q10,q14
+	vst1.8	{q4,q5},[r14]!
+	veor	q11,q11,q15
+	vst1.8	{q6,q7},[r14]!
+
+	vadd.i32	d6,d6,d24	@ next counter value
+	vldr	d24,[sp,#4*(16+0)]	@ one
+
+	ldmia	sp,{r8,r9,r10,r11}	@ load key material
+	add	r0,r0,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	vst1.8	{q8,q9},[r14]!
+	add	r1,r1,r9
+	ldr	r9,[r12,#-12]
+	vst1.8	{q10,q11},[r14]!
+	add	r2,r2,r10
+	ldr	r10,[r12,#-8]
+	add	r3,r3,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+	eor	r0,r0,r8	@ xor with input
+	add	r8,sp,#4*(4)
+	eor	r1,r1,r9
+	str	r0,[r14],#16		@ store output
+	eor	r2,r2,r10
+	str	r1,[r14,#-12]
+	eor	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	add	r5,r5,r9
+	ldr	r9,[r12,#-12]
+	add	r6,r6,r10
+	ldr	r10,[r12,#-8]
+	add	r7,r7,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	eor	r4,r4,r8
+	add	r8,sp,#4*(8)
+	eor	r5,r5,r9
+	str	r4,[r14],#16		@ store output
+	eor	r6,r6,r10
+	str	r5,[r14,#-12]
+	eor	r7,r7,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r6,[r14,#-8]
+	add	r0,sp,#4*(16+8)
+	str	r7,[r14,#-4]
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	add	r1,r1,r9
+	ldr	r9,[r12,#-12]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
+	add	r2,r2,r10
+	ldr	r10,[r12,#-8]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
+	add	r3,r3,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+	eor	r0,r0,r8
+	add	r8,sp,#4*(12)
+	eor	r1,r1,r9
+	str	r0,[r14],#16		@ store output
+	eor	r2,r2,r10
+	str	r1,[r14,#-12]
+	eor	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,r8,#4		@ next counter value
+	add	r5,r5,r9
+	str	r8,[sp,#4*(12)]	@ save next counter value
+	ldr	r8,[r12],#16		@ load input
+	add	r6,r6,r10
+	add	r4,r4,#3		@ counter+3
+	ldr	r9,[r12,#-12]
+	add	r7,r7,r11
+	ldr	r10,[r12,#-8]
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	eor	r4,r4,r8
+# ifdef	__thumb2__
+	it	hi
+# endif
+	ldrhi	r8,[sp,#4*(32+2)]	@ re-load len
+	eor	r5,r5,r9
+	eor	r6,r6,r10
+	str	r4,[r14],#16		@ store output
+	eor	r7,r7,r11
+	str	r5,[r14,#-12]
+	sub	r11,r8,#64*4	@ len-=64*4
+	str	r6,[r14,#-8]
+	str	r7,[r14,#-4]
+	bhi	.Loop_neon_outer
+
+	b	.Ldone_neon
+
+.align	4
+.Lbreak_neon:
+	@ harmonize NEON and integer-only stack frames: load data
+	@ from NEON frame, but save to integer-only one; distance
+	@ between the two is 4*(32+4+16-32)=4*(20).
+
+	str	r11, [sp,#4*(20+32+2)]	@ save len
+	add	r11,sp,#4*(32+4)
+	str	r12,   [sp,#4*(20+32+1)]	@ save inp
+	str	r14,   [sp,#4*(20+32+0)]	@ save out
+
+	ldr	r12,[sp,#4*(16+10)]
+	ldr	r14,[sp,#4*(16+11)]
+	vldmia	r11,{d8,d9,d10,d11,d12,d13,d14,d15}			@ fulfill ABI requirement
+	str	r12,[sp,#4*(20+16+10)]	@ copy "rx"
+	str	r14,[sp,#4*(20+16+11)]	@ copy "rx"
+
+	ldr	r11, [sp,#4*(15)]
+	ldr	r12,[sp,#4*(12)]		@ modulo-scheduled load
+	ldr	r10, [sp,#4*(13)]
+	ldr	r14,[sp,#4*(14)]
+	str	r11, [sp,#4*(20+16+15)]
+	add	r11,sp,#4*(20)
+	vst1.32	{q0,q1},[r11]!		@ copy key
+	add	sp,sp,#4*(20)			@ switch frame
+	vst1.32	{q2,q3},[r11]
+	mov	r11,#10
+	b	.Loop				@ go integer-only
+
+.align	4
+.Ltail_neon:
+	cmp	r11,#64*3
+	bhs	.L192_or_more_neon
+	cmp	r11,#64*2
+	bhs	.L128_or_more_neon
+	cmp	r11,#64*1
+	bhs	.L64_or_more_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q0,q1},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q2,q3},[r8]
+	b	.Loop_tail_neon
+
+.align	4
+.L64_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vst1.8	{q0,q1},[r14]!
+	vst1.8	{q2,q3},[r14]!
+
+	beq	.Ldone_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q4,q5},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q6,q7},[r8]
+	sub	r11,r11,#64*1	@ len-=64*1
+	b	.Loop_tail_neon
+
+.align	4
+.L128_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	veor	q5,q5,q13
+	vst1.8	{q0,q1},[r14]!
+	veor	q6,q6,q14
+	vst1.8	{q2,q3},[r14]!
+	veor	q7,q7,q15
+	vst1.8	{q4,q5},[r14]!
+	vst1.8	{q6,q7},[r14]!
+
+	beq	.Ldone_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q8,q9},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q10,q11},[r8]
+	sub	r11,r11,#64*2	@ len-=64*2
+	b	.Loop_tail_neon
+
+.align	4
+.L192_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	veor	q5,q5,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q6,q6,q14
+	vst1.8	{q0,q1},[r14]!
+	veor	q7,q7,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q8,q8,q12
+	vst1.8	{q2,q3},[r14]!
+	veor	q9,q9,q13
+	vst1.8	{q4,q5},[r14]!
+	veor	q10,q10,q14
+	vst1.8	{q6,q7},[r14]!
+	veor	q11,q11,q15
+	vst1.8	{q8,q9},[r14]!
+	vst1.8	{q10,q11},[r14]!
+
+	beq	.Ldone_neon
+
+	ldmia	sp,{r8,r9,r10,r11}	@ load key material
+	add	r0,r0,r8	@ accumulate key material
+	add	r8,sp,#4*(4)
+	add	r1,r1,r9
+	add	r2,r2,r10
+	add	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,sp,#4*(8)
+	add	r5,r5,r9
+	add	r6,r6,r10
+	add	r7,r7,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	stmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7}
+	add	r0,sp,#4*(16+8)
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r8,sp,#4*(12)
+	add	r1,r1,r9
+	add	r2,r2,r10
+	add	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,sp,#4*(8)
+	add	r5,r5,r9
+	add	r4,r4,#3		@ counter+3
+	add	r6,r6,r10
+	add	r7,r7,r11
+	ldr	r11,[sp,#4*(32+2)]	@ re-load len
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	stmia	r8,{r0,r1,r2,r3,r4,r5,r6,r7}
+	add	r10,sp,#4*(0)
+	sub	r11,r11,#64*3	@ len-=64*3
+
+.Loop_tail_neon:
+	ldrb	r8,[r10],#1	@ read buffer on stack
+	ldrb	r9,[r12],#1		@ read input
+	subs	r11,r11,#1
+	eor	r8,r8,r9
+	strb	r8,[r14],#1		@ store ouput
+	bne	.Loop_tail_neon
+
+.Ldone_neon:
+	add	sp,sp,#4*(32+4)
+	vldmia	sp,{d8,d9,d10,d11,d12,d13,d14,d15}
+	add	sp,sp,#4*(16+3)
+	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size	ChaCha20_neon,.-ChaCha20_neon
+.comm	OPENSSL_armcap_P,4,4
+#endif
+#endif
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index d955d82..791b289 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -535,4 +535,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/modes/ghashv8-armx32.S b/linux-arm/crypto/modes/ghashv8-armx32.S
index 9a38ded..0e1e631 100644
--- a/linux-arm/crypto/modes/ghashv8-armx32.S
+++ b/linux-arm/crypto/modes/ghashv8-armx32.S
@@ -5,6 +5,7 @@
 .fpu	neon
 .code	32
 .globl	gcm_init_v8
+.hidden	gcm_init_v8
 .type	gcm_init_v8,%function
 .align	4
 gcm_init_v8:
@@ -55,6 +56,7 @@
 	bx	lr
 .size	gcm_init_v8,.-gcm_init_v8
 .globl	gcm_gmult_v8
+.hidden	gcm_gmult_v8
 .type	gcm_gmult_v8,%function
 .align	4
 gcm_gmult_v8:
@@ -96,6 +98,7 @@
 	bx	lr
 .size	gcm_gmult_v8,.-gcm_gmult_v8
 .globl	gcm_ghash_v8
+.hidden	gcm_ghash_v8
 .type	gcm_ghash_v8,%function
 .align	4
 gcm_ghash_v8:
@@ -230,4 +233,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/sha/sha1-armv4-large.S b/linux-arm/crypto/sha/sha1-armv4-large.S
index 66d0ef3..36955fa 100644
--- a/linux-arm/crypto/sha/sha1-armv4-large.S
+++ b/linux-arm/crypto/sha/sha1-armv4-large.S
@@ -5,6 +5,7 @@
 .code	32
 
 .globl	sha1_block_data_order
+.hidden	sha1_block_data_order
 .type	sha1_block_data_order,%function
 
 .align	5
@@ -1459,4 +1460,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/sha/sha256-armv4.S b/linux-arm/crypto/sha/sha256-armv4.S
index 9fc3e0b..6040041 100644
--- a/linux-arm/crypto/sha/sha256-armv4.S
+++ b/linux-arm/crypto/sha/sha256-armv4.S
@@ -85,6 +85,7 @@
 .align	5
 
 .globl	sha256_block_data_order
+.hidden	sha256_block_data_order
 .type	sha256_block_data_order,%function
 sha256_block_data_order:
 .Lsha256_block_data_order:
@@ -1875,6 +1876,7 @@
 .fpu	neon
 
 .globl	sha256_block_data_order_neon
+.hidden	sha256_block_data_order_neon
 .type	sha256_block_data_order_neon,%function
 .align	4
 sha256_block_data_order_neon:
@@ -2815,4 +2817,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/sha/sha512-armv4.S b/linux-arm/crypto/sha/sha512-armv4.S
index 834ede9..93a7bf8 100644
--- a/linux-arm/crypto/sha/sha512-armv4.S
+++ b/linux-arm/crypto/sha/sha512-armv4.S
@@ -133,6 +133,7 @@
 #endif
 
 .globl	sha512_block_data_order
+.hidden	sha512_block_data_order
 .type	sha512_block_data_order,%function
 sha512_block_data_order:
 .Lsha512_block_data_order:
@@ -147,7 +148,7 @@
 #ifdef	__APPLE__
 	ldr	r12,[r12]
 #endif
-	tst	r12,#1
+	tst	r12,#ARMV7_NEON
 	bne	.LNEON
 #endif
 	add	r2,r1,r2,lsl#7	@ len to point at the end of inp
@@ -533,6 +534,7 @@
 .fpu	neon
 
 .globl	sha512_block_data_order_neon
+.hidden	sha512_block_data_order_neon
 .type	sha512_block_data_order_neon,%function
 .align	4
 sha512_block_data_order_neon:
@@ -1866,4 +1868,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/linux-x86/crypto/chacha/chacha-x86.S b/linux-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 0000000..f28459e
--- /dev/null
+++ b/linux-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,989 @@
+#if defined(__i386__)
+.file	"chacha-x86.S"
+.text
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,@function
+.align	16
+ChaCha20_ctr32:
+.L_ChaCha20_ctr32_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	xorl	%eax,%eax
+	cmpl	28(%esp),%eax
+	je	.L000no_data
+	call	.Lpic_point
+.Lpic_point:
+	popl	%eax
+	leal	OPENSSL_ia32cap_P-.Lpic_point(%eax),%ebp
+	testl	$16777216,(%ebp)
+	jz	.L001x86
+	testl	$512,4(%ebp)
+	jz	.L001x86
+	jmp	.Lssse3_shortcut
+.L001x86:
+	movl	32(%esp),%esi
+	movl	36(%esp),%edi
+	subl	$132,%esp
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edx
+	movl	%eax,80(%esp)
+	movl	%ebx,84(%esp)
+	movl	%ecx,88(%esp)
+	movl	%edx,92(%esp)
+	movl	16(%esi),%eax
+	movl	20(%esi),%ebx
+	movl	24(%esi),%ecx
+	movl	28(%esi),%edx
+	movl	%eax,96(%esp)
+	movl	%ebx,100(%esp)
+	movl	%ecx,104(%esp)
+	movl	%edx,108(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	subl	$1,%eax
+	movl	%eax,112(%esp)
+	movl	%ebx,116(%esp)
+	movl	%ecx,120(%esp)
+	movl	%edx,124(%esp)
+	jmp	.L002entry
+.align	16
+.L003outer_loop:
+	movl	%ebx,156(%esp)
+	movl	%eax,152(%esp)
+	movl	%ecx,160(%esp)
+.L002entry:
+	movl	$1634760805,%eax
+	movl	$857760878,4(%esp)
+	movl	$2036477234,8(%esp)
+	movl	$1797285236,12(%esp)
+	movl	84(%esp),%ebx
+	movl	88(%esp),%ebp
+	movl	104(%esp),%ecx
+	movl	108(%esp),%esi
+	movl	116(%esp),%edx
+	movl	120(%esp),%edi
+	movl	%ebx,20(%esp)
+	movl	%ebp,24(%esp)
+	movl	%ecx,40(%esp)
+	movl	%esi,44(%esp)
+	movl	%edx,52(%esp)
+	movl	%edi,56(%esp)
+	movl	92(%esp),%ebx
+	movl	124(%esp),%edi
+	movl	112(%esp),%edx
+	movl	80(%esp),%ebp
+	movl	96(%esp),%ecx
+	movl	100(%esp),%esi
+	addl	$1,%edx
+	movl	%ebx,28(%esp)
+	movl	%edi,60(%esp)
+	movl	%edx,112(%esp)
+	movl	$10,%ebx
+	jmp	.L004loop
+.align	16
+.L004loop:
+	addl	%ebp,%eax
+	movl	%ebx,128(%esp)
+	movl	%ebp,%ebx
+	xorl	%eax,%edx
+	roll	$16,%edx
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	52(%esp),%edi
+	roll	$12,%ebx
+	movl	20(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,48(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,32(%esp)
+	roll	$16,%edi
+	movl	%ebx,16(%esp)
+	addl	%edi,%esi
+	movl	40(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	56(%esp),%edx
+	roll	$12,%ebp
+	movl	24(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,52(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,36(%esp)
+	roll	$16,%edx
+	movl	%ebp,20(%esp)
+	addl	%edx,%ecx
+	movl	44(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	60(%esp),%edi
+	roll	$12,%ebx
+	movl	28(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,56(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,24(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	roll	$12,%ebp
+	movl	20(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,%edx
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	roll	$16,%edx
+	movl	%ebp,28(%esp)
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	48(%esp),%edi
+	roll	$12,%ebx
+	movl	24(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,60(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,40(%esp)
+	roll	$16,%edi
+	movl	%ebx,20(%esp)
+	addl	%edi,%esi
+	movl	32(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	52(%esp),%edx
+	roll	$12,%ebp
+	movl	28(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,48(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,44(%esp)
+	roll	$16,%edx
+	movl	%ebp,24(%esp)
+	addl	%edx,%ecx
+	movl	36(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	56(%esp),%edi
+	roll	$12,%ebx
+	movl	16(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,52(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,28(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	movl	48(%esp),%edx
+	roll	$12,%ebp
+	movl	128(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,56(%esp)
+	xorl	%esi,%ebp
+	roll	$7,%ebp
+	decl	%ebx
+	jnz	.L004loop
+	movl	160(%esp),%ebx
+	addl	$1634760805,%eax
+	addl	80(%esp),%ebp
+	addl	96(%esp),%ecx
+	addl	100(%esp),%esi
+	cmpl	$64,%ebx
+	jb	.L005tail
+	movl	156(%esp),%ebx
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	xorl	(%ebx),%eax
+	xorl	16(%ebx),%ebp
+	movl	%eax,(%esp)
+	movl	152(%esp),%eax
+	xorl	32(%ebx),%ecx
+	xorl	36(%ebx),%esi
+	xorl	48(%ebx),%edx
+	xorl	56(%ebx),%edi
+	movl	%ebp,16(%esp)
+	movl	(%esp),%ebp
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	%ebp,(%eax)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	xorl	4(%ebx),%ebp
+	xorl	8(%ebx),%ecx
+	xorl	12(%ebx),%esi
+	xorl	20(%ebx),%edx
+	xorl	24(%ebx),%edi
+	movl	%ebp,4(%eax)
+	movl	16(%esp),%ebp
+	movl	%ecx,8(%eax)
+	movl	%esi,12(%eax)
+	movl	%ebp,16(%eax)
+	movl	%edx,20(%eax)
+	movl	%edi,24(%eax)
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%edi
+	addl	92(%esp),%ecx
+	movl	40(%esp),%ebp
+	xorl	28(%ebx),%ecx
+	movl	44(%esp),%esi
+	movl	%ecx,28(%eax)
+	movl	%edx,32(%eax)
+	movl	%edi,36(%eax)
+	addl	104(%esp),%ebp
+	addl	108(%esp),%esi
+	xorl	40(%ebx),%ebp
+	xorl	44(%ebx),%esi
+	movl	%ebp,40(%eax)
+	movl	%esi,44(%eax)
+	movl	48(%esp),%ecx
+	movl	56(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	xorl	52(%ebx),%edx
+	xorl	60(%ebx),%edi
+	leal	64(%ebx),%ebx
+	movl	%ecx,48(%eax)
+	movl	160(%esp),%ecx
+	movl	%edx,52(%eax)
+	movl	%esi,56(%eax)
+	movl	%edi,60(%eax)
+	leal	64(%eax),%eax
+	subl	$64,%ecx
+	jnz	.L003outer_loop
+	jmp	.L006done
+.L005tail:
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	movl	%eax,(%esp)
+	movl	%ebp,16(%esp)
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	movl	%ebp,4(%esp)
+	movl	%ecx,8(%esp)
+	movl	%esi,12(%esp)
+	movl	%edx,20(%esp)
+	movl	%edi,24(%esp)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	movl	%ebp,28(%esp)
+	movl	156(%esp),%ebp
+	movl	%ecx,40(%esp)
+	movl	152(%esp),%ecx
+	movl	%esi,44(%esp)
+	xorl	%esi,%esi
+	movl	%edx,52(%esp)
+	movl	%edi,60(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+.L007tail_loop:
+	movb	(%esi,%ebp,1),%al
+	movb	(%esp,%esi,1),%dl
+	leal	1(%esi),%esi
+	xorb	%dl,%al
+	movb	%al,-1(%ecx,%esi,1)
+	decl	%ebx
+	jnz	.L007tail_loop
+.L006done:
+	addl	$132,%esp
+.L000no_data:
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.size	ChaCha20_ctr32,.-.L_ChaCha20_ctr32_begin
+.globl	ChaCha20_ssse3
+.hidden	ChaCha20_ssse3
+.type	ChaCha20_ssse3,@function
+.align	16
+ChaCha20_ssse3:
+.L_ChaCha20_ssse3_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+.Lssse3_shortcut:
+	movl	20(%esp),%edi
+	movl	24(%esp),%esi
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%ebx
+	movl	%esp,%ebp
+	subl	$524,%esp
+	andl	$-64,%esp
+	movl	%ebp,512(%esp)
+	leal	.Lssse3_data-.Lpic_point(%eax),%eax
+	movdqu	(%ebx),%xmm3
+	cmpl	$256,%ecx
+	jb	.L0081x
+	movl	%edx,516(%esp)
+	movl	%ebx,520(%esp)
+	subl	$256,%ecx
+	leal	384(%esp),%ebp
+	movdqu	(%edx),%xmm7
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	paddd	48(%eax),%xmm0
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	psubd	64(%eax),%xmm0
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,64(%ebp)
+	movdqa	%xmm1,80(%ebp)
+	movdqa	%xmm2,96(%ebp)
+	movdqa	%xmm3,112(%ebp)
+	movdqu	16(%edx),%xmm3
+	movdqa	%xmm4,-64(%ebp)
+	movdqa	%xmm5,-48(%ebp)
+	movdqa	%xmm6,-32(%ebp)
+	movdqa	%xmm7,-16(%ebp)
+	movdqa	32(%eax),%xmm7
+	leal	128(%esp),%ebx
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,(%ebp)
+	movdqa	%xmm1,16(%ebp)
+	movdqa	%xmm2,32(%ebp)
+	movdqa	%xmm3,48(%ebp)
+	movdqa	%xmm4,-128(%ebp)
+	movdqa	%xmm5,-112(%ebp)
+	movdqa	%xmm6,-96(%ebp)
+	movdqa	%xmm7,-80(%ebp)
+	leal	128(%esi),%esi
+	leal	128(%edi),%edi
+	jmp	.L009outer_loop
+.align	16
+.L009outer_loop:
+	movdqa	-112(%ebp),%xmm1
+	movdqa	-96(%ebp),%xmm2
+	movdqa	-80(%ebp),%xmm3
+	movdqa	-48(%ebp),%xmm5
+	movdqa	-32(%ebp),%xmm6
+	movdqa	-16(%ebp),%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm2,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	%xmm5,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm7,-16(%ebx)
+	movdqa	32(%ebp),%xmm2
+	movdqa	48(%ebp),%xmm3
+	movdqa	64(%ebp),%xmm4
+	movdqa	80(%ebp),%xmm5
+	movdqa	96(%ebp),%xmm6
+	movdqa	112(%ebp),%xmm7
+	paddd	64(%eax),%xmm4
+	movdqa	%xmm2,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	%xmm4,64(%ebx)
+	movdqa	%xmm5,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm7,112(%ebx)
+	movdqa	%xmm4,64(%ebp)
+	movdqa	-128(%ebp),%xmm0
+	movdqa	%xmm4,%xmm6
+	movdqa	-64(%ebp),%xmm3
+	movdqa	(%ebp),%xmm4
+	movdqa	16(%ebp),%xmm5
+	movl	$10,%edx
+	nop
+.align	16
+.L010loop:
+	paddd	%xmm3,%xmm0
+	movdqa	%xmm3,%xmm2
+	pxor	%xmm0,%xmm6
+	pshufb	(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-48(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	80(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,64(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-64(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	32(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-32(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	96(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,80(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,16(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-48(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	48(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-16(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	112(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,96(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-32(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	-48(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,%xmm6
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-16(%ebx)
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-32(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	64(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,112(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,32(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-48(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-16(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	80(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,64(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,48(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-32(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	16(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-64(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	96(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,80(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-16(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	64(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,96(%ebx)
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	por	%xmm1,%xmm3
+	decl	%edx
+	jnz	.L010loop
+	movdqa	%xmm3,-64(%ebx)
+	movdqa	%xmm4,(%ebx)
+	movdqa	%xmm5,16(%ebx)
+	movdqa	%xmm6,64(%ebx)
+	movdqa	%xmm7,96(%ebx)
+	movdqa	-112(%ebx),%xmm1
+	movdqa	-96(%ebx),%xmm2
+	movdqa	-80(%ebx),%xmm3
+	paddd	-128(%ebp),%xmm0
+	paddd	-112(%ebp),%xmm1
+	paddd	-96(%ebp),%xmm2
+	paddd	-80(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,-128(%ebx)
+	movdqa	-64(%ebx),%xmm0
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm6,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	-48(%ebx),%xmm1
+	movdqa	-32(%ebx),%xmm2
+	movdqa	-16(%ebx),%xmm3
+	paddd	-64(%ebp),%xmm0
+	paddd	-48(%ebp),%xmm1
+	paddd	-32(%ebp),%xmm2
+	paddd	-16(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,-64(%ebx)
+	movdqa	(%ebx),%xmm0
+	movdqa	%xmm1,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm3,-16(%ebx)
+	movdqa	16(%ebx),%xmm1
+	movdqa	32(%ebx),%xmm2
+	movdqa	48(%ebx),%xmm3
+	paddd	(%ebp),%xmm0
+	paddd	16(%ebp),%xmm1
+	paddd	32(%ebp),%xmm2
+	paddd	48(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,(%ebx)
+	movdqa	64(%ebx),%xmm0
+	movdqa	%xmm1,16(%ebx)
+	movdqa	%xmm6,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	80(%ebx),%xmm1
+	movdqa	96(%ebx),%xmm2
+	movdqa	112(%ebx),%xmm3
+	paddd	64(%ebp),%xmm0
+	paddd	80(%ebp),%xmm1
+	paddd	96(%ebp),%xmm2
+	paddd	112(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,64(%ebx)
+	movdqa	%xmm1,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm3,112(%ebx)
+	movdqu	-128(%esi),%xmm0
+	movdqu	-112(%esi),%xmm1
+	movdqu	-96(%esi),%xmm2
+	movdqu	-80(%esi),%xmm3
+	pxor	-128(%ebx),%xmm0
+	pxor	-64(%ebx),%xmm1
+	pxor	(%ebx),%xmm2
+	pxor	64(%ebx),%xmm3
+	movdqu	%xmm0,-128(%edi)
+	movdqu	%xmm1,-112(%edi)
+	movdqu	%xmm2,-96(%edi)
+	movdqu	%xmm3,-80(%edi)
+	movdqu	-64(%esi),%xmm0
+	movdqu	-48(%esi),%xmm1
+	movdqu	-32(%esi),%xmm2
+	movdqu	-16(%esi),%xmm3
+	pxor	-112(%ebx),%xmm0
+	pxor	-48(%ebx),%xmm1
+	pxor	16(%ebx),%xmm2
+	pxor	80(%ebx),%xmm3
+	movdqu	%xmm0,-64(%edi)
+	movdqu	%xmm1,-48(%edi)
+	movdqu	%xmm2,-32(%edi)
+	movdqu	%xmm3,-16(%edi)
+	movdqu	(%esi),%xmm0
+	movdqu	16(%esi),%xmm1
+	movdqu	32(%esi),%xmm2
+	movdqu	48(%esi),%xmm3
+	pxor	-96(%ebx),%xmm0
+	pxor	-32(%ebx),%xmm1
+	pxor	32(%ebx),%xmm2
+	pxor	96(%ebx),%xmm3
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	movdqu	64(%esi),%xmm0
+	movdqu	80(%esi),%xmm1
+	movdqu	96(%esi),%xmm2
+	movdqu	112(%esi),%xmm3
+	pxor	-80(%ebx),%xmm0
+	pxor	-16(%ebx),%xmm1
+	pxor	48(%ebx),%xmm2
+	pxor	112(%ebx),%xmm3
+	movdqu	%xmm0,64(%edi)
+	movdqu	%xmm1,80(%edi)
+	movdqu	%xmm2,96(%edi)
+	movdqu	%xmm3,112(%edi)
+	leal	256(%esi),%esi
+	leal	256(%edi),%edi
+	subl	$256,%ecx
+	jnc	.L009outer_loop
+	addl	$256,%ecx
+	jz	.L011done
+	movl	520(%esp),%ebx
+	leal	-128(%esi),%esi
+	movl	516(%esp),%edx
+	leal	-128(%edi),%edi
+	movd	64(%ebp),%xmm2
+	movdqu	(%ebx),%xmm3
+	paddd	96(%eax),%xmm2
+	pand	112(%eax),%xmm3
+	por	%xmm2,%xmm3
+.L0081x:
+	movdqa	32(%eax),%xmm0
+	movdqu	(%edx),%xmm1
+	movdqu	16(%edx),%xmm2
+	movdqa	(%eax),%xmm6
+	movdqa	16(%eax),%xmm7
+	movl	%ebp,48(%esp)
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	movl	$10,%edx
+	jmp	.L012loop1x
+.align	16
+.L013outer1x:
+	movdqa	80(%eax),%xmm3
+	movdqa	(%esp),%xmm0
+	movdqa	16(%esp),%xmm1
+	movdqa	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	movl	$10,%edx
+	movdqa	%xmm3,48(%esp)
+	jmp	.L012loop1x
+.align	16
+.L012loop1x:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%edx
+	jnz	.L012loop1x
+	paddd	(%esp),%xmm0
+	paddd	16(%esp),%xmm1
+	paddd	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	cmpl	$64,%ecx
+	jb	.L014tail
+	movdqu	(%esi),%xmm4
+	movdqu	16(%esi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%esi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%esi),%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+	leal	64(%esi),%esi
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	leal	64(%edi),%edi
+	subl	$64,%ecx
+	jnz	.L013outer1x
+	jmp	.L011done
+.L014tail:
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+	xorl	%ebp,%ebp
+.L015tail_loop:
+	movb	(%esp,%ebp,1),%al
+	movb	(%esi,%ebp,1),%dl
+	leal	1(%ebp),%ebp
+	xorb	%dl,%al
+	movb	%al,-1(%edi,%ebp,1)
+	decl	%ecx
+	jnz	.L015tail_loop
+.L011done:
+	movl	512(%esp),%esp
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.size	ChaCha20_ssse3,.-.L_ChaCha20_ssse3_begin
+.align	64
+.Lssse3_data:
+.byte	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long	1634760805,857760878,2036477234,1797285236
+.long	0,1,2,3
+.long	4,4,4,4
+.long	1,0,0,0
+.long	4,0,0,0
+.long	0,-1,-1,-1
+.align	64
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte	114,103,62,0
+#endif
diff --git a/linux-x86/crypto/rc4/rc4-586.S b/linux-x86/crypto/rc4/rc4-586.S
index a5cce47..d245589 100644
--- a/linux-x86/crypto/rc4/rc4-586.S
+++ b/linux-x86/crypto/rc4/rc4-586.S
@@ -347,39 +347,4 @@
 	popl	%ebp
 	ret
 .size	asm_RC4_set_key,.-.L_asm_RC4_set_key_begin
-.globl	RC4_options
-.hidden	RC4_options
-.type	RC4_options,@function
-.align	16
-RC4_options:
-.L_RC4_options_begin:
-	call	.L018pic_point
-.L018pic_point:
-	popl	%eax
-	leal	.L019opts-.L018pic_point(%eax),%eax
-	call	.L020PIC_me_up
-.L020PIC_me_up:
-	popl	%edx
-	leal	OPENSSL_ia32cap_P-.L020PIC_me_up(%edx),%edx
-	movl	(%edx),%edx
-	btl	$20,%edx
-	jc	.L0211xchar
-	btl	$26,%edx
-	jnc	.L022ret
-	addl	$25,%eax
-	ret
-.L0211xchar:
-	addl	$12,%eax
-.L022ret:
-	ret
-.align	64
-.L019opts:
-.byte	114,99,52,40,52,120,44,105,110,116,41,0
-.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte	114,99,52,40,56,120,44,109,109,120,41,0
-.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align	64
-.size	RC4_options,.-.L_RC4_options_begin
 #endif
diff --git a/linux-x86_64/crypto/aes/aes-x86_64.S b/linux-x86_64/crypto/aes/aes-x86_64.S
index 5f4b057..361e84c 100644
--- a/linux-x86_64/crypto/aes/aes-x86_64.S
+++ b/linux-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$65280,%edi
-	andl	$65280,%ebp
+	andl	$0x0000ff00,%edi
+	andl	$0x0000ff00,%ebp
 
 	xorl	%edi,%r10d
 	xorl	%ebp,%r11d
@@ -95,8 +95,8 @@
 	movl	0(%r14,%rsi,8),%esi
 	movl	0(%r14,%rdi,8),%edi
 
-	andl	$65280,%esi
-	andl	$65280,%edi
+	andl	$0x0000ff00,%esi
+	andl	$0x0000ff00,%edi
 	shrl	$16,%ebx
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -109,9 +109,9 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$16711680,%edi
-	andl	$16711680,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0x00ff0000,%edi
+	andl	$0x00ff0000,%ebp
 
 	xorl	%esi,%r10d
 	xorl	%edi,%r11d
@@ -124,9 +124,9 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	2(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$4278190080,%edi
-	andl	$4278190080,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0xff000000,%edi
+	andl	$0xff000000,%ebp
 
 	xorl	%esi,%r8d
 	xorl	%edi,%r10d
@@ -139,8 +139,8 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
-	andl	$4278190080,%esi
-	andl	$4278190080,%edi
+	andl	$0xff000000,%esi
+	andl	$0xff000000,%edi
 
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -242,8 +242,8 @@
 	xorl	%r8d,%edx
 	cmpq	16(%rsp),%r15
 	je	.Lenc_compact_done
-	movl	$2155905152,%r10d
-	movl	$2155905152,%r11d
+	movl	$0x80808080,%r10d
+	movl	$0x80808080,%r11d
 	andl	%eax,%r10d
 	andl	%ebx,%r11d
 	movl	%r10d,%esi
@@ -254,10 +254,10 @@
 	leal	(%rbx,%rbx,1),%r9d
 	subl	%r10d,%esi
 	subl	%r11d,%edi
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%eax,%r10d
 	movl	%ebx,%r11d
 	xorl	%esi,%r8d
@@ -265,9 +265,9 @@
 
 	xorl	%r8d,%eax
 	xorl	%r9d,%ebx
-	movl	$2155905152,%r12d
+	movl	$0x80808080,%r12d
 	roll	$24,%eax
-	movl	$2155905152,%ebp
+	movl	$0x80808080,%ebp
 	roll	$24,%ebx
 	andl	%ecx,%r12d
 	andl	%edx,%ebp
@@ -290,10 +290,10 @@
 	xorl	%r10d,%eax
 	xorl	%r11d,%ebx
 
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%ecx,%r12d
 	movl	%edx,%ebp
 	xorl	%esi,%r8d
@@ -345,7 +345,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -370,7 +370,7 @@
 	leaq	.LAES_Te+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 
 	call	_x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -816,7 +816,7 @@
 	leaq	.LAES_Td+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 	shrq	$3,%rbp
 	addq	%rbp,%r14
@@ -1334,9 +1334,9 @@
 	movq	%r14,%r10
 	leaq	2304(%r14),%r11
 	movq	%r15,%r12
-	andq	$4095,%r10
-	andq	$4095,%r11
-	andq	$4095,%r12
+	andq	$0xFFF,%r10
+	andq	$0xFFF,%r11
+	andq	$0xFFF,%r12
 
 	cmpq	%r11,%r12
 	jb	.Lcbc_te_break_out
@@ -1345,7 +1345,7 @@
 	jmp	.Lcbc_te_ok
 .Lcbc_te_break_out:
 	subq	%r10,%r12
-	andq	$4095,%r12
+	andq	$0xFFF,%r12
 	addq	$320,%r12
 	subq	%r12,%r15
 .align	4
@@ -1371,7 +1371,7 @@
 
 	movq	%r15,%r10
 	subq	%r14,%r10
-	andq	$4095,%r10
+	andq	$0xfff,%r10
 	cmpq	$2304,%r10
 	jb	.Lcbc_do_ecopy
 	cmpq	$4096-248,%r10
@@ -1558,7 +1558,7 @@
 	leaq	-88-63(%rcx),%r10
 	subq	%rbp,%r10
 	negq	%r10
-	andq	$960,%r10
+	andq	$0x3c0,%r10
 	subq	%r10,%rbp
 
 	xchgq	%rsp,%rbp
@@ -1587,7 +1587,7 @@
 	leaq	2048(%r14),%r14
 	leaq	768-8(%rsp),%rax
 	subq	%r14,%rax
-	andq	$768,%rax
+	andq	$0x300,%rax
 	leaq	(%r14,%rax,1),%r14
 
 	cmpq	$0,%rbx
diff --git a/linux-x86_64/crypto/aes/aesni-x86_64.S b/linux-x86_64/crypto/aes/aesni-x86_64.S
index 1d51d5b..5709a2d 100644
--- a/linux-x86_64/crypto/aes/aesni-x86_64.S
+++ b/linux-x86_64/crypto/aes/aesni-x86_64.S
@@ -508,7 +508,7 @@
 	testl	%r8d,%r8d
 	jz	.Lecb_decrypt
 
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	.Lecb_enc_tail
 
 	movdqu	(%rdi),%xmm2
@@ -520,7 +520,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	.Lecb_enc_loop8_enter
 .align	16
 .Lecb_enc_loop8:
@@ -548,7 +548,7 @@
 
 	call	_aesni_encrypt8
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	.Lecb_enc_loop8
 
 	movups	%xmm2,(%rsi)
@@ -562,22 +562,22 @@
 	movups	%xmm8,96(%rsi)
 	movups	%xmm9,112(%rsi)
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	.Lecb_ret
 
 .Lecb_enc_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lecb_enc_one
 	movups	16(%rdi),%xmm3
 	je	.Lecb_enc_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lecb_enc_three
 	movups	48(%rdi),%xmm5
 	je	.Lecb_enc_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	.Lecb_enc_five
 	movups	80(%rdi),%xmm7
 	je	.Lecb_enc_six
@@ -651,7 +651,7 @@
 
 .align	16
 .Lecb_decrypt:
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	.Lecb_dec_tail
 
 	movdqu	(%rdi),%xmm2
@@ -663,7 +663,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	.Lecb_dec_loop8_enter
 .align	16
 .Lecb_dec_loop8:
@@ -692,7 +692,7 @@
 	call	_aesni_decrypt8
 
 	movups	(%r11),%xmm0
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	.Lecb_dec_loop8
 
 	movups	%xmm2,(%rsi)
@@ -714,22 +714,22 @@
 	movups	%xmm9,112(%rsi)
 	pxor	%xmm9,%xmm9
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	.Lecb_ret
 
 .Lecb_dec_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lecb_dec_one
 	movups	16(%rdi),%xmm3
 	je	.Lecb_dec_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lecb_dec_three
 	movups	48(%rdi),%xmm5
 	je	.Lecb_dec_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	.Lecb_dec_five
 	movups	80(%rdi),%xmm7
 	je	.Lecb_dec_six
@@ -1607,7 +1607,7 @@
 
 	movdqa	.Lxts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -1706,7 +1706,7 @@
 .byte	102,15,56,220,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	.Lxts_enc_loop6
 .align	32
 .Lxts_enc_loop6:
@@ -1845,13 +1845,13 @@
 	jz	.Lxts_enc_done
 
 	pxor	%xmm0,%xmm11
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lxts_enc_one
 	pxor	%xmm0,%xmm12
 	je	.Lxts_enc_two
 
 	pxor	%xmm0,%xmm13
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lxts_enc_three
 	pxor	%xmm0,%xmm14
 	je	.Lxts_enc_four
@@ -2079,7 +2079,7 @@
 
 	movdqa	.Lxts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -2178,7 +2178,7 @@
 .byte	102,15,56,222,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	.Lxts_dec_loop6
 .align	32
 .Lxts_dec_loop6:
@@ -2318,13 +2318,13 @@
 	jz	.Lxts_dec_done
 
 	pxor	%xmm0,%xmm12
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lxts_dec_one
 	pxor	%xmm0,%xmm13
 	je	.Lxts_dec_two
 
 	pxor	%xmm0,%xmm14
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lxts_dec_three
 	je	.Lxts_dec_four
 
@@ -2355,7 +2355,7 @@
 	pcmpgtd	%xmm15,%xmm14
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	pshufd	$19,%xmm14,%xmm11
+	pshufd	$0x13,%xmm14,%xmm11
 	andq	$15,%r9
 	jz	.Lxts_dec_ret
 
@@ -2645,7 +2645,7 @@
 	leaq	-8(%rax),%rbp
 	movups	(%r8),%xmm10
 	movl	%r10d,%eax
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	.Lcbc_dec_tail
 
 	movups	(%rcx),%xmm0
@@ -2661,14 +2661,14 @@
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
 	movl	OPENSSL_ia32cap_P+4(%rip),%r9d
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	jbe	.Lcbc_dec_six_or_seven
 
 	andl	$71303168,%r9d
-	subq	$80,%rdx
+	subq	$0x50,%rdx
 	cmpl	$4194304,%r9d
 	je	.Lcbc_dec_loop6_enter
-	subq	$32,%rdx
+	subq	$0x20,%rdx
 	leaq	112(%rcx),%rcx
 	jmp	.Lcbc_dec_loop8_enter
 .align	16
@@ -2683,7 +2683,7 @@
 	movups	16-112(%rcx),%xmm1
 	pxor	%xmm0,%xmm4
 	xorq	%r11,%r11
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	pxor	%xmm0,%xmm5
 	pxor	%xmm0,%xmm6
 	pxor	%xmm0,%xmm7
@@ -2868,21 +2868,21 @@
 	movups	%xmm8,96(%rsi)
 	leaq	112(%rsi),%rsi
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	ja	.Lcbc_dec_loop8
 
 	movaps	%xmm9,%xmm2
 	leaq	-112(%rcx),%rcx
-	addq	$112,%rdx
+	addq	$0x70,%rdx
 	jle	.Lcbc_dec_clear_tail_collected
 	movups	%xmm9,(%rsi)
 	leaq	16(%rsi),%rsi
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	.Lcbc_dec_tail
 
 	movaps	%xmm11,%xmm2
 .Lcbc_dec_six_or_seven:
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	ja	.Lcbc_dec_seven
 
 	movaps	%xmm7,%xmm8
@@ -2975,33 +2975,33 @@
 	movl	%r10d,%eax
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	subq	$96,%rdx
+	subq	$0x60,%rdx
 	ja	.Lcbc_dec_loop6
 
 	movdqa	%xmm7,%xmm2
-	addq	$80,%rdx
+	addq	$0x50,%rdx
 	jle	.Lcbc_dec_clear_tail_collected
 	movups	%xmm7,(%rsi)
 	leaq	16(%rsi),%rsi
 
 .Lcbc_dec_tail:
 	movups	(%rdi),%xmm2
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_one
 
 	movups	16(%rdi),%xmm3
 	movaps	%xmm2,%xmm11
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_two
 
 	movups	32(%rdi),%xmm4
 	movaps	%xmm3,%xmm12
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_three
 
 	movups	48(%rdi),%xmm5
 	movaps	%xmm4,%xmm13
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_four
 
 	movups	64(%rdi),%xmm6
@@ -3026,7 +3026,7 @@
 	movdqa	%xmm6,%xmm2
 	pxor	%xmm6,%xmm6
 	pxor	%xmm7,%xmm7
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jmp	.Lcbc_dec_tail_collected
 
 .align	16
@@ -3345,7 +3345,7 @@
 	pslldq	$4,%xmm0
 	pxor	%xmm3,%xmm0
 
-	pshufd	$255,%xmm0,%xmm3
+	pshufd	$0xff,%xmm0,%xmm3
 	pxor	%xmm1,%xmm3
 	pslldq	$4,%xmm1
 	pxor	%xmm1,%xmm3
@@ -3432,7 +3432,7 @@
 	decl	%r10d
 	jz	.Ldone_key256
 
-	pshufd	$255,%xmm0,%xmm2
+	pshufd	$0xff,%xmm0,%xmm2
 	pxor	%xmm3,%xmm3
 .byte	102,15,56,221,211
 
diff --git a/linux-x86_64/crypto/aes/bsaes-x86_64.S b/linux-x86_64/crypto/aes/bsaes-x86_64.S
index 8cfa4df..c5491ce 100644
--- a/linux-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/linux-x86_64/crypto/aes/bsaes-x86_64.S
@@ -327,45 +327,45 @@
 	pxor	%xmm2,%xmm5
 	decl	%r10d
 	jl	.Lenc_done
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm3,%xmm9
+	pshufd	$0x93,%xmm3,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm5,%xmm10
+	pshufd	$0x93,%xmm5,%xmm10
 	pxor	%xmm9,%xmm3
-	pshufd	$147,%xmm2,%xmm11
+	pshufd	$0x93,%xmm2,%xmm11
 	pxor	%xmm10,%xmm5
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm2
-	pshufd	$147,%xmm1,%xmm13
+	pshufd	$0x93,%xmm1,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm1
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm2,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm5,%xmm11
-	pshufd	$78,%xmm2,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm7
 	pxor	%xmm1,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm3,%xmm10
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm1,%xmm5
+	pshufd	$0x4E,%xmm1,%xmm5
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm12,%xmm8
 	pxor	%xmm10,%xmm2
 	pxor	%xmm14,%xmm6
@@ -799,24 +799,24 @@
 	decl	%r10d
 	jl	.Ldec_done
 
-	pshufd	$78,%xmm15,%xmm7
-	pshufd	$78,%xmm2,%xmm13
+	pshufd	$0x4E,%xmm15,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm13
 	pxor	%xmm15,%xmm7
-	pshufd	$78,%xmm4,%xmm14
+	pshufd	$0x4E,%xmm4,%xmm14
 	pxor	%xmm2,%xmm13
-	pshufd	$78,%xmm0,%xmm8
+	pshufd	$0x4E,%xmm0,%xmm8
 	pxor	%xmm4,%xmm14
-	pshufd	$78,%xmm5,%xmm9
+	pshufd	$0x4E,%xmm5,%xmm9
 	pxor	%xmm0,%xmm8
-	pshufd	$78,%xmm3,%xmm10
+	pshufd	$0x4E,%xmm3,%xmm10
 	pxor	%xmm5,%xmm9
 	pxor	%xmm13,%xmm15
 	pxor	%xmm13,%xmm0
-	pshufd	$78,%xmm1,%xmm11
+	pshufd	$0x4E,%xmm1,%xmm11
 	pxor	%xmm3,%xmm10
 	pxor	%xmm7,%xmm5
 	pxor	%xmm8,%xmm3
-	pshufd	$78,%xmm6,%xmm12
+	pshufd	$0x4E,%xmm6,%xmm12
 	pxor	%xmm1,%xmm11
 	pxor	%xmm14,%xmm0
 	pxor	%xmm9,%xmm1
@@ -830,45 +830,45 @@
 	pxor	%xmm14,%xmm1
 	pxor	%xmm14,%xmm6
 	pxor	%xmm12,%xmm4
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm5,%xmm9
+	pshufd	$0x93,%xmm5,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm3,%xmm10
+	pshufd	$0x93,%xmm3,%xmm10
 	pxor	%xmm9,%xmm5
-	pshufd	$147,%xmm1,%xmm11
+	pshufd	$0x93,%xmm1,%xmm11
 	pxor	%xmm10,%xmm3
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm1
-	pshufd	$147,%xmm2,%xmm13
+	pshufd	$0x93,%xmm2,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm2
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm1,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm3,%xmm11
-	pshufd	$78,%xmm1,%xmm7
+	pshufd	$0x4E,%xmm1,%xmm7
 	pxor	%xmm2,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm5,%xmm10
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm2,%xmm3
+	pshufd	$0x4E,%xmm2,%xmm3
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm12,%xmm8
 	pxor	%xmm1,%xmm10
 	pxor	%xmm14,%xmm6
@@ -1559,20 +1559,20 @@
 	movdqa	%xmm7,(%rax)
 
 	andq	$-16,%r14
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	.Lxts_enc_short
 	jmp	.Lxts_enc_loop
 
 .align	16
 .Lxts_enc_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1580,7 +1580,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1589,7 +1589,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1599,7 +1599,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1609,7 +1609,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1619,7 +1619,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1629,7 +1629,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -1673,20 +1673,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	.Lxts_enc_loop
 
 .Lxts_enc_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	.Lxts_enc_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1694,7 +1694,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1705,7 +1705,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	.Lxts_enc_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1717,7 +1717,7 @@
 	cmpq	$32,%r14
 	je	.Lxts_enc_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1729,7 +1729,7 @@
 	cmpq	$48,%r14
 	je	.Lxts_enc_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1741,7 +1741,7 @@
 	cmpq	$64,%r14
 	je	.Lxts_enc_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1753,7 +1753,7 @@
 	cmpq	$80,%r14
 	je	.Lxts_enc_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2019,20 +2019,20 @@
 	shlq	$4,%rax
 	subq	%rax,%r14
 
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	.Lxts_dec_short
 	jmp	.Lxts_dec_loop
 
 .align	16
 .Lxts_dec_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2040,7 +2040,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2049,7 +2049,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2059,7 +2059,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2069,7 +2069,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2079,7 +2079,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2089,7 +2089,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2133,20 +2133,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	.Lxts_dec_loop
 
 .Lxts_dec_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	.Lxts_dec_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2154,7 +2154,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2165,7 +2165,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	.Lxts_dec_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2177,7 +2177,7 @@
 	cmpq	$32,%r14
 	je	.Lxts_dec_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2189,7 +2189,7 @@
 	cmpq	$48,%r14
 	je	.Lxts_dec_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2201,7 +2201,7 @@
 	cmpq	$64,%r14
 	je	.Lxts_dec_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2213,7 +2213,7 @@
 	cmpq	$80,%r14
 	je	.Lxts_dec_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2390,7 +2390,7 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	movdqa	%xmm6,%xmm5
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
diff --git a/linux-x86_64/crypto/aes/vpaes-x86_64.S b/linux-x86_64/crypto/aes/vpaes-x86_64.S
index 1d12424..4dfafa9 100644
--- a/linux-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/linux-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@
 	addq	$16,%r11
 	pxor	%xmm0,%xmm3
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	subq	$1,%rax
 	pxor	%xmm3,%xmm0
 
@@ -121,10 +121,10 @@
 	pand	%xmm9,%xmm0
 .byte	102,15,56,0,208
 	movdqa	.Lk_dipt+16(%rip),%xmm0
-	xorq	$48,%r11
+	xorq	$0x30,%r11
 	leaq	.Lk_dsbd(%rip),%r10
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	pxor	%xmm5,%xmm2
 	movdqa	.Lk_mc_forward+48(%rip),%xmm5
 	pxor	%xmm2,%xmm0
@@ -243,7 +243,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	movdqu	%xmm3,(%rdx)
-	xorq	$48,%r8
+	xorq	$0x30,%r8
 
 .Lschedule_go:
 	cmpl	$192,%esi
@@ -333,7 +333,7 @@
 	call	_vpaes_schedule_mangle
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 	movdqa	%xmm7,%xmm5
 	movdqa	%xmm6,%xmm7
 	call	_vpaes_schedule_low_round
@@ -400,8 +400,8 @@
 .type	_vpaes_schedule_192_smear,@function
 .align	16
 _vpaes_schedule_192_smear:
-	pshufd	$128,%xmm6,%xmm1
-	pshufd	$254,%xmm7,%xmm0
+	pshufd	$0x80,%xmm6,%xmm1
+	pshufd	$0xFE,%xmm7,%xmm0
 	pxor	%xmm1,%xmm6
 	pxor	%xmm1,%xmm1
 	pxor	%xmm0,%xmm6
@@ -438,7 +438,7 @@
 	pxor	%xmm1,%xmm7
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 .byte	102,15,58,15,192,1
 
 
@@ -597,7 +597,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	addq	$-16,%r8
-	andq	$48,%r8
+	andq	$0x30,%r8
 	movdqu	%xmm3,(%rdx)
 	.byte	0xf3,0xc3
 .size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
@@ -616,7 +616,7 @@
 	movl	%eax,240(%rdx)
 
 	movl	$0,%ecx
-	movl	$48,%r8d
+	movl	$0x30,%r8d
 	call	_vpaes_schedule_core
 	xorl	%eax,%eax
 	.byte	0xf3,0xc3
diff --git a/linux-x86_64/crypto/bn/rsaz-x86_64.S b/linux-x86_64/crypto/bn/rsaz-x86_64.S
index dd3d310..21531d1 100644
--- a/linux-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/linux-x86_64/crypto/bn/rsaz-x86_64.S
@@ -466,48 +466,94 @@
 	pushq	%r14
 	pushq	%r15
 
-	movl	%r9d,%r9d
-	subq	$128+24,%rsp
+	subq	$152,%rsp
 .Lmul_gather4_body:
-	movl	64(%rdx,%r9,4),%eax
-.byte	102,72,15,110,199
-	movl	(%rdx,%r9,4),%ebx
-.byte	102,72,15,110,201
-	movq	%r8,128(%rsp)
+	movd	%r9d,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1
+	movdqa	.Linc(%rip),%xmm0
 
-	shlq	$32,%rax
-	orq	%rax,%rbx
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
+
+	movdqa	0(%rdx),%xmm8
+	movdqa	16(%rdx),%xmm9
+	movdqa	32(%rdx),%xmm10
+	movdqa	48(%rdx),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rdx),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rdx),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rdx),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rdx),%xmm15
+	leaq	128(%rdx),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
+	movq	%r8,128(%rsp)
+	movq	%rdi,128+8(%rsp)
+	movq	%rcx,128+16(%rsp)
+
 	movq	(%rsi),%rax
 	movq	8(%rsi),%rcx
-	leaq	128(%rdx,%r9,4),%rbp
 	mulq	%rbx
 	movq	%rax,(%rsp)
 	movq	%rcx,%rax
 	movq	%rdx,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r8
 	movq	16(%rsi),%rax
 	movq	%rdx,%r9
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r9
 	movq	24(%rsi),%rax
 	movq	%rdx,%r10
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r10
 	movq	32(%rsi),%rax
 	movq	%rdx,%r11
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r11
 	movq	40(%rsi),%rax
 	movq	%rdx,%r12
@@ -520,14 +566,12 @@
 	adcq	$0,%r13
 
 	mulq	%rbx
-	leaq	128(%rbp),%rbp
 	addq	%rax,%r13
 	movq	56(%rsi),%rax
 	movq	%rdx,%r14
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r14
 	movq	(%rsi),%rax
 	movq	%rdx,%r15
@@ -539,6 +583,35 @@
 
 .align	32
 .Loop_mul_gather:
+	movdqa	0(%rbp),%xmm8
+	movdqa	16(%rbp),%xmm9
+	movdqa	32(%rbp),%xmm10
+	movdqa	48(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rbp),%xmm15
+	leaq	128(%rbp),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
 	mulq	%rbx
 	addq	%rax,%r8
 	movq	8(%rsi),%rax
@@ -547,7 +620,6 @@
 	adcq	$0,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r9
 	movq	16(%rsi),%rax
 	adcq	$0,%rdx
@@ -556,7 +628,6 @@
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r10
 	movq	24(%rsi),%rax
 	adcq	$0,%rdx
@@ -565,7 +636,6 @@
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r11
 	movq	32(%rsi),%rax
 	adcq	$0,%rdx
@@ -574,7 +644,6 @@
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r12
 	movq	40(%rsi),%rax
 	adcq	$0,%rdx
@@ -599,7 +668,6 @@
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r15
 	movq	(%rsi),%rax
 	adcq	$0,%rdx
@@ -607,7 +675,6 @@
 	movq	%rdx,%r15
 	adcq	$0,%r15
 
-	leaq	128(%rbp),%rbp
 	leaq	8(%rdi),%rdi
 
 	decl	%ecx
@@ -622,8 +689,8 @@
 	movq	%r14,48(%rdi)
 	movq	%r15,56(%rdi)
 
-.byte	102,72,15,126,199
-.byte	102,72,15,126,205
+	movq	128+8(%rsp),%rdi
+	movq	128+16(%rsp),%rbp
 
 	movq	(%rsp),%r8
 	movq	8(%rsp),%r9
@@ -673,7 +740,7 @@
 	movl	%r9d,%r9d
 	subq	$128+24,%rsp
 .Lmul_scatter4_body:
-	leaq	(%r8,%r9,4),%r8
+	leaq	(%r8,%r9,8),%r8
 .byte	102,72,15,110,199
 .byte	102,72,15,110,202
 .byte	102,73,15,110,208
@@ -709,30 +776,14 @@
 
 	call	__rsaz_512_subtract
 
-	movl	%r8d,0(%rsi)
-	shrq	$32,%r8
-	movl	%r9d,128(%rsi)
-	shrq	$32,%r9
-	movl	%r10d,256(%rsi)
-	shrq	$32,%r10
-	movl	%r11d,384(%rsi)
-	shrq	$32,%r11
-	movl	%r12d,512(%rsi)
-	shrq	$32,%r12
-	movl	%r13d,640(%rsi)
-	shrq	$32,%r13
-	movl	%r14d,768(%rsi)
-	shrq	$32,%r14
-	movl	%r15d,896(%rsi)
-	shrq	$32,%r15
-	movl	%r8d,64(%rsi)
-	movl	%r9d,192(%rsi)
-	movl	%r10d,320(%rsi)
-	movl	%r11d,448(%rsi)
-	movl	%r12d,576(%rsi)
-	movl	%r13d,704(%rsi)
-	movl	%r14d,832(%rsi)
-	movl	%r15d,960(%rsi)
+	movq	%r8,0(%rsi)
+	movq	%r9,128(%rsi)
+	movq	%r10,256(%rsi)
+	movq	%r11,384(%rsi)
+	movq	%r12,512(%rsi)
+	movq	%r13,640(%rsi)
+	movq	%r14,768(%rsi)
+	movq	%r15,896(%rsi)
 
 	leaq	128+24+48(%rsp),%rax
 	movq	-48(%rax),%r15
@@ -1087,16 +1138,14 @@
 .type	rsaz_512_scatter4,@function
 .align	16
 rsaz_512_scatter4:
-	leaq	(%rdi,%rdx,4),%rdi
+	leaq	(%rdi,%rdx,8),%rdi
 	movl	$8,%r9d
 	jmp	.Loop_scatter
 .align	16
 .Loop_scatter:
 	movq	(%rsi),%rax
 	leaq	8(%rsi),%rsi
-	movl	%eax,(%rdi)
-	shrq	$32,%rax
-	movl	%eax,64(%rdi)
+	movq	%rax,(%rdi)
 	leaq	128(%rdi),%rdi
 	decl	%r9d
 	jnz	.Loop_scatter
@@ -1108,20 +1157,73 @@
 .type	rsaz_512_gather4,@function
 .align	16
 rsaz_512_gather4:
-	leaq	(%rsi,%rdx,4),%rsi
+	movd	%edx,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1
+	movdqa	.Linc(%rip),%xmm0
+
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
 	movl	$8,%r9d
 	jmp	.Loop_gather
 .align	16
 .Loop_gather:
-	movl	(%rsi),%eax
-	movl	64(%rsi),%r8d
+	movdqa	0(%rsi),%xmm8
+	movdqa	16(%rsi),%xmm9
+	movdqa	32(%rsi),%xmm10
+	movdqa	48(%rsi),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rsi),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rsi),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rsi),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rsi),%xmm15
 	leaq	128(%rsi),%rsi
-	shlq	$32,%r8
-	orq	%r8,%rax
-	movq	%rax,(%rdi)
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,(%rdi)
 	leaq	8(%rdi),%rdi
 	decl	%r9d
 	jnz	.Loop_gather
 	.byte	0xf3,0xc3
+.LSEH_end_rsaz_512_gather4:
 .size	rsaz_512_gather4,.-rsaz_512_gather4
+
+.align	64
+.Linc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 #endif
diff --git a/linux-x86_64/crypto/bn/x86_64-mont.S b/linux-x86_64/crypto/bn/x86_64-mont.S
index 4d401c6..83926ad 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont.S
@@ -636,20 +636,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,4),%r11
+	leaq	-64(%rsp,%r9,2),%r11
 	movq	(%r8),%r8
 	subq	%rsi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lsqr8x_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	-64(%rsp,%r9,2),%rsp
 	jmp	.Lsqr8x_sp_done
 
 .align	32
 .Lsqr8x_sp_alt:
-	leaq	4096-64(,%r9,4),%r10
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	4096-64(,%r9,2),%r10
+	leaq	-64(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -659,58 +659,80 @@
 	movq	%r9,%r10
 	negq	%r9
 
-	leaq	64(%rsp,%r9,2),%r11
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 .Lsqr8x_body:
 
-	movq	%r9,%rbp
-.byte	102,73,15,110,211
-	shrq	$3+2,%rbp
-	movl	OPENSSL_ia32cap_P+8(%rip),%eax
-	jmp	.Lsqr8x_copy_n
-
-.align	32
-.Lsqr8x_copy_n:
-	movq	0(%rcx),%xmm0
-	movq	8(%rcx),%xmm1
-	movq	16(%rcx),%xmm3
-	movq	24(%rcx),%xmm4
-	leaq	32(%rcx),%rcx
-	movdqa	%xmm0,0(%r11)
-	movdqa	%xmm1,16(%r11)
-	movdqa	%xmm3,32(%r11)
-	movdqa	%xmm4,48(%r11)
-	leaq	64(%r11),%r11
-	decq	%rbp
-	jnz	.Lsqr8x_copy_n
-
+.byte	102,72,15,110,209
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,73,15,110,218
 	call	bn_sqr8x_internal
 
-	pxor	%xmm0,%xmm0
-	leaq	48(%rsp),%rax
-	leaq	64(%rsp,%r9,2),%rdx
-	shrq	$3+2,%r9
-	movq	40(%rsp),%rsi
-	jmp	.Lsqr8x_zero
+
+
+
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+	movq	%r9,%rdx
+.byte	102,72,15,126,207
+	sarq	$3+2,%rcx
+	jmp	.Lsqr8x_sub
 
 .align	32
-.Lsqr8x_zero:
-	movdqa	%xmm0,0(%rax)
-	movdqa	%xmm0,16(%rax)
-	movdqa	%xmm0,32(%rax)
-	movdqa	%xmm0,48(%rax)
-	leaq	64(%rax),%rax
-	movdqa	%xmm0,0(%rdx)
-	movdqa	%xmm0,16(%rdx)
-	movdqa	%xmm0,32(%rdx)
-	movdqa	%xmm0,48(%rdx)
-	leaq	64(%rdx),%rdx
-	decq	%r9
-	jnz	.Lsqr8x_zero
+.Lsqr8x_sub:
+	movq	0(%rbx),%r12
+	movq	8(%rbx),%r13
+	movq	16(%rbx),%r14
+	movq	24(%rbx),%r15
+	leaq	32(%rbx),%rbx
+	sbbq	0(%rbp),%r12
+	sbbq	8(%rbp),%r13
+	sbbq	16(%rbp),%r14
+	sbbq	24(%rbp),%r15
+	leaq	32(%rbp),%rbp
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	leaq	32(%rdi),%rdi
+	incq	%rcx
+	jnz	.Lsqr8x_sub
+
+	sbbq	$0,%rax
+	leaq	(%rbx,%r9,1),%rbx
+	leaq	(%rdi,%r9,1),%rdi
+
+.byte	102,72,15,110,200
+	pxor	%xmm0,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	40(%rsp),%rsi
+	jmp	.Lsqr8x_cond_copy
+
+.align	32
+.Lsqr8x_cond_copy:
+	movdqa	0(%rbx),%xmm2
+	movdqa	16(%rbx),%xmm3
+	leaq	32(%rbx),%rbx
+	movdqu	0(%rdi),%xmm4
+	movdqu	16(%rdi),%xmm5
+	leaq	32(%rdi),%rdi
+	movdqa	%xmm0,-32(%rbx)
+	movdqa	%xmm0,-16(%rbx)
+	movdqa	%xmm0,-32(%rbx,%rdx,1)
+	movdqa	%xmm0,-16(%rbx,%rdx,1)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-32(%rdi)
+	movdqu	%xmm5,-16(%rdi)
+	addq	$32,%r9
+	jnz	.Lsqr8x_cond_copy
 
 	movq	$1,%rax
 	movq	-48(%rsi),%r15
diff --git a/linux-x86_64/crypto/bn/x86_64-mont5.S b/linux-x86_64/crypto/bn/x86_64-mont5.S
index 214064e..554df1f 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -17,46 +17,151 @@
 .Lmul_enter:
 	movl	%r9d,%r9d
 	movq	%rsp,%rax
-	movl	8(%rsp),%r10d
+	movd	8(%rsp),%xmm5
+	leaq	.Linc(%rip),%r10
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 	leaq	2(%r9),%r11
 	negq	%r11
-	leaq	(%rsp,%r11,8),%rsp
+	leaq	-264(%rsp,%r11,8),%rsp
 	andq	$-1024,%rsp
 
 	movq	%rax,8(%rsp,%r9,8)
 .Lmul_body:
-	movq	%rdx,%r12
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	.Lmagic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%r12,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
+	leaq	128(%rdx),%r12
+	movdqa	0(%r10),%xmm0
+	movdqa	16(%r10),%xmm1
+	leaq	24-112(%rsp,%r9,8),%r10
+	andq	$-16,%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+.byte	0x67
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
+.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
 	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 .byte	102,72,15,126,195
 
 	movq	(%r8),%r8
@@ -65,29 +170,14 @@
 	xorq	%r14,%r14
 	xorq	%r15,%r15
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	movq	%r8,%rbp
 	mulq	%rbx
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -120,14 +210,12 @@
 	cmpq	%r9,%r15
 	jne	.L1st
 
-.byte	102,72,15,126,195
 
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r13
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 	movq	%r10,%r11
 
@@ -141,33 +229,78 @@
 	jmp	.Louter
 .align	16
 .Louter:
+	leaq	24+128(%rsp,%r9,8),%rdx
+	andq	$-16,%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+
+	movq	(%rsi),%rax
+.byte	102,72,15,126,195
+
 	xorq	%r15,%r15
 	movq	%r8,%rbp
 	movq	(%rsp),%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	mulq	%rbx
 	addq	%rax,%r10
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -203,15 +336,12 @@
 	cmpq	%r9,%r15
 	jne	.Linner
 
-.byte	102,72,15,126,195
-
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r13
-	movq	(%rsp,%r15,8),%r10
+	movq	(%rsp,%r9,8),%r10
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 
 	xorq	%rdx,%rdx
@@ -257,6 +387,7 @@
 
 	movq	8(%rsp,%r9,8),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -279,10 +410,10 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 .byte	0x67
-	movl	%r9d,%r10d
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
 
@@ -292,19 +423,21 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lmul4xsp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lmul4xsp_done
 
 .align	32
 .Lmul4xsp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -320,6 +453,7 @@
 
 	movq	40(%rsp),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -335,47 +469,141 @@
 .align	32
 mul4x_internal:
 	shlq	$5,%r9
-	movl	8(%rax),%r10d
-	leaq	256(%rdx,%r9,1),%r13
+	movd	8(%rax),%xmm5
+	leaq	.Linc(%rip),%rax
+	leaq	128(%rdx,%r9,1),%r13
 	shrq	$5,%r9
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	.Lmagic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%rdx,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	addq	$7,%r11
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
-	andq	$7,%r11
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	88-112(%rsp,%r9,1),%r10
+	leaq	128(%rdx),%r12
 
-	movq	-96(%r12),%xmm0
-	leaq	256(%r12),%r14
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+.byte	0x67,0x67
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
 .byte	0x67
-	por	%xmm1,%xmm0
-	movq	-96(%r14),%xmm1
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
 .byte	0x67
-	pand	%xmm7,%xmm3
-.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
-	movq	-32(%r14),%xmm2
-.byte	0x67
-	pand	%xmm4,%xmm1
-.byte	0x67
-	por	%xmm3,%xmm0
-	movq	32(%r14),%xmm3
-
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	leaq	256(%r12),%r12
 .byte	102,72,15,126,195
-	movq	96(%r14),%xmm0
+
 	movq	%r13,16+8(%rsp)
 	movq	%rdi,56+8(%rsp)
 
@@ -389,26 +617,10 @@
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	pand	%xmm5,%xmm2
-	pand	%xmm6,%xmm3
-	por	%xmm2,%xmm1
-
 	imulq	%r10,%rbp
-
-
-
-
-
-
-
-	leaq	64+8(%rsp,%r11,8),%r14
+	leaq	64+8(%rsp),%r14
 	movq	%rdx,%r11
 
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
-	leaq	512(%r12),%r12
-	por	%xmm1,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi,%r9,1),%rax
@@ -417,7 +629,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -427,7 +639,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -437,7 +649,7 @@
 .L1st4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -453,7 +665,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -483,7 +695,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -492,7 +704,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -502,7 +714,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -518,7 +730,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -531,8 +743,7 @@
 	movq	%rdi,-16(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -543,6 +754,63 @@
 
 .align	32
 .Louter4x:
+	leaq	16+128(%r14),%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+.byte	102,72,15,126,195
+
 	movq	(%r14,%r9,1),%r10
 	movq	%r8,%rbp
 	mulq	%rbx
@@ -550,25 +818,11 @@
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-
 	imulq	%r10,%rbp
-.byte	0x67
 	movq	%rdx,%r11
 	movq	%rdi,(%r14)
 
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	por	%xmm2,%xmm0
 	leaq	(%r14,%r9,1),%r14
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
 
 	mulq	%rbp
 	addq	%rax,%r10
@@ -578,7 +832,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -590,7 +844,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdx,%r13
 	jmp	.Linner4x
@@ -599,7 +853,7 @@
 .Linner4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -617,7 +871,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -651,7 +905,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -662,7 +916,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%r13,-8(%r14)
 	movq	%rdx,%r13
@@ -672,7 +926,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -691,7 +945,7 @@
 	mulq	%rbx
 	addq	%rax,%r11
 	movq	%rbp,%rax
-	movq	-16(%rcx),%rbp
+	movq	-8(%rcx),%rbp
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -706,9 +960,8 @@
 	movq	%r13,-24(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
 	movq	%rdi,-16(%r14)
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -719,16 +972,23 @@
 
 	cmpq	16+8(%rsp),%r12
 	jb	.Louter4x
+	xorq	%rax,%rax
 	subq	%r13,%rbp
 	adcq	%r15,%r15
 	orq	%r15,%rdi
-	xorq	$1,%rdi
+	subq	%rdi,%rax
 	leaq	(%r14,%r9,1),%rbx
-	leaq	(%rcx,%rdi,8),%rbp
+	movq	(%rcx),%r12
+	leaq	(%rcx),%rbp
 	movq	%r9,%rcx
 	sarq	$3+2,%rcx
 	movq	56+8(%rsp),%rdi
-	jmp	.Lsqr4x_sub
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	.Lsqr4x_sub_entry
 .size	mul4x_internal,.-mul4x_internal
 .globl	bn_power5
 .hidden bn_power5
@@ -742,9 +1002,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leal	(%r9,%r9,2),%r10d
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -754,19 +1014,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lpwr_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lpwr_sp_done
 
 .align	32
 .Lpwr_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -794,10 +1055,15 @@
 .byte	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 .byte	102,72,15,126,209
 .byte	102,72,15,126,226
@@ -1342,9 +1608,9 @@
 	movq	%rbx,-16(%rdi)
 	movq	%r8,-8(%rdi)
 .byte	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xorq	%rax,%rax
-	leaq	(%rbp,%r9,2),%rcx
+	leaq	(%r9,%rbp,1),%rcx
 	leaq	48+8(%rsp,%r9,2),%rdx
 	movq	%rcx,0+8(%rsp)
 	leaq	48+8(%rsp,%r9,1),%rdi
@@ -1377,14 +1643,14 @@
 .align	32
 .L8x_reduce:
 	mulq	%rbx
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	negq	%r8
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	movq	%rbx,48-8+8(%rsp,%rcx,8)
@@ -1393,7 +1659,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	32+8(%rsp),%rsi
@@ -1402,7 +1668,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	imulq	%r8,%rsi
 	addq	%r11,%r10
@@ -1411,7 +1677,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1419,7 +1685,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1427,7 +1693,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1445,7 +1711,7 @@
 	decl	%ecx
 	jnz	.L8x_reduce
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	xorq	%rax,%rax
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
@@ -1471,14 +1737,14 @@
 .L8x_tail:
 	mulq	%rbx
 	addq	%rax,%r8
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	movq	%r8,(%rdi)
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	leaq	8(%rdi),%rdi
@@ -1487,7 +1753,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	%rdx,%r10
@@ -1495,7 +1761,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r10
 	movq	%rdx,%r11
@@ -1503,7 +1769,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1511,7 +1777,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1519,7 +1785,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1537,7 +1803,7 @@
 	decl	%ecx
 	jnz	.L8x_tail
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
 	jae	.L8x_tail_done
@@ -1583,7 +1849,7 @@
 	adcq	48(%rdi),%r14
 	adcq	56(%rdi),%r15
 	adcq	$0,%rax
-	movq	-16(%rbp),%rcx
+	movq	-8(%rbp),%rcx
 	xorq	%rsi,%rsi
 
 .byte	102,72,15,126,213
@@ -1601,44 +1867,62 @@
 
 	cmpq	%rdx,%rdi
 	jb	.L8x_reduction_loop
-
-	subq	%r15,%rcx
-	leaq	(%rdi,%r9,1),%rbx
-	adcq	%rsi,%rsi
-	movq	%r9,%rcx
-	orq	%rsi,%rax
-.byte	102,72,15,126,207
-	xorq	$1,%rax
-.byte	102,72,15,126,206
-	leaq	(%rbp,%rax,8),%rbp
-	sarq	$3+2,%rcx
-	jmp	.Lsqr4x_sub
-
+	.byte	0xf3,0xc3
+.size	bn_sqr8x_internal,.-bn_sqr8x_internal
+.type	__bn_post4x_internal,@function
 .align	32
+__bn_post4x_internal:
+	movq	0(%rbp),%r12
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+.byte	102,72,15,126,207
+	negq	%rax
+.byte	102,72,15,126,206
+	sarq	$3+2,%rcx
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	.Lsqr4x_sub_entry
+
+.align	16
 .Lsqr4x_sub:
-.byte	0x66
-	movq	0(%rbx),%r12
-	movq	8(%rbx),%r13
-	sbbq	0(%rbp),%r12
-	movq	16(%rbx),%r14
-	sbbq	16(%rbp),%r13
-	movq	24(%rbx),%r15
-	leaq	32(%rbx),%rbx
-	sbbq	32(%rbp),%r14
+	movq	0(%rbp),%r12
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+.Lsqr4x_sub_entry:
+	leaq	32(%rbp),%rbp
+	notq	%r12
+	notq	%r13
+	notq	%r14
+	notq	%r15
+	andq	%rax,%r12
+	andq	%rax,%r13
+	andq	%rax,%r14
+	andq	%rax,%r15
+
+	negq	%r10
+	adcq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	adcq	16(%rbx),%r14
+	adcq	24(%rbx),%r15
 	movq	%r12,0(%rdi)
-	sbbq	48(%rbp),%r15
-	leaq	64(%rbp),%rbp
+	leaq	32(%rbx),%rbx
 	movq	%r13,8(%rdi)
+	sbbq	%r10,%r10
 	movq	%r14,16(%rdi)
 	movq	%r15,24(%rdi)
 	leaq	32(%rdi),%rdi
 
 	incq	%rcx
 	jnz	.Lsqr4x_sub
+
 	movq	%r9,%r10
 	negq	%r9
 	.byte	0xf3,0xc3
-.size	bn_sqr8x_internal,.-bn_sqr8x_internal
+.size	__bn_post4x_internal,.-__bn_post4x_internal
 .globl	bn_from_montgomery
 .hidden bn_from_montgomery
 .type	bn_from_montgomery,@function
@@ -1661,10 +1945,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-.byte	0x67
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -1674,19 +1957,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lfrom_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lfrom_sp_done
 
 .align	32
 .Lfrom_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -1737,7 +2021,8 @@
 .byte	0x67
 	movq	%rcx,%rbp
 .byte	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	%xmm0,%xmm0
 	leaq	48(%rsp),%rax
@@ -1787,46 +2072,170 @@
 .globl	bn_gather5
 .hidden bn_gather5
 .type	bn_gather5,@function
-.align	16
+.align	32
 bn_gather5:
-	movl	%ecx,%r11d
-	shrl	$3,%ecx
-	andq	$7,%r11
-	notl	%ecx
-	leaq	.Lmagic_masks(%rip),%rax
-	andl	$3,%ecx
-	leaq	128(%rdx,%r11,8),%rdx
-	movq	0(%rax,%rcx,8),%xmm4
-	movq	8(%rax,%rcx,8),%xmm5
-	movq	16(%rax,%rcx,8),%xmm6
-	movq	24(%rax,%rcx,8),%xmm7
-	jmp	.Lgather
-.align	16
-.Lgather:
-	movq	-128(%rdx),%xmm0
-	movq	-64(%rdx),%xmm1
-	pand	%xmm4,%xmm0
-	movq	0(%rdx),%xmm2
-	pand	%xmm5,%xmm1
-	movq	64(%rdx),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-.byte	0x67,0x67
-	por	%xmm2,%xmm0
-	leaq	256(%rdx),%rdx
-	por	%xmm3,%xmm0
+.LSEH_begin_bn_gather5:
 
+.byte	0x4c,0x8d,0x14,0x24
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	leaq	.Linc(%rip),%rax
+	andq	$-16,%rsp
+
+	movd	%ecx,%xmm5
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	128(%rdx),%r11
+	leaq	128(%rsp),%rax
+
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-128(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-112(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-96(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-80(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-48(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-16(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,16(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,48(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,80(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,96(%rax)
+	movdqa	%xmm4,%xmm2
+	movdqa	%xmm3,112(%rax)
+	jmp	.Lgather
+
+.align	32
+.Lgather:
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r11),%xmm0
+	movdqa	-112(%r11),%xmm1
+	movdqa	-96(%r11),%xmm2
+	pand	-128(%rax),%xmm0
+	movdqa	-80(%r11),%xmm3
+	pand	-112(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r11),%xmm0
+	movdqa	-48(%r11),%xmm1
+	movdqa	-32(%r11),%xmm2
+	pand	-64(%rax),%xmm0
+	movdqa	-16(%r11),%xmm3
+	pand	-48(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	pand	0(%rax),%xmm0
+	movdqa	48(%r11),%xmm3
+	pand	16(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r11),%xmm0
+	movdqa	80(%r11),%xmm1
+	movdqa	96(%r11),%xmm2
+	pand	64(%rax),%xmm0
+	movdqa	112(%r11),%xmm3
+	pand	80(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	leaq	256(%r11),%r11
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
 	movq	%xmm0,(%rdi)
 	leaq	8(%rdi),%rdi
 	subl	$1,%esi
 	jnz	.Lgather
+
+	leaq	(%r10),%rsp
 	.byte	0xf3,0xc3
 .LSEH_end_bn_gather5:
 .size	bn_gather5,.-bn_gather5
 .align	64
-.Lmagic_masks:
-.long	0,0, 0,0, 0,0, -1,-1
-.long	0,0, 0,0, 0,0,  0,0
+.Linc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 .byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 #endif
diff --git a/linux-x86_64/crypto/chacha/chacha-x86_64.S b/linux-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 0000000..e994940
--- /dev/null
+++ b/linux-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1585 @@
+#if defined(__x86_64__)
+.text	
+
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
+
+.align	64
+.Lzero:
+.long	0,0,0,0
+.Lone:
+.long	1,0,0,0
+.Linc:
+.long	0,1,2,3
+.Lfour:
+.long	4,4,4,4
+.Lincy:
+.long	0,2,4,6,1,3,5,7
+.Leight:
+.long	8,8,8,8,8,8,8,8
+.Lrot16:
+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+.Lrot24:
+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+.Lsigma:
+.byte	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl	ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type	ChaCha20_ctr32,@function
+.align	64
+ChaCha20_ctr32:
+	cmpq	$0,%rdx
+	je	.Lno_data
+	movq	OPENSSL_ia32cap_P+4(%rip),%r10
+	testl	$512,%r10d
+	jnz	.LChaCha20_ssse3
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$64+24,%rsp
+
+
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	.Lone(%rip),%xmm4
+
+
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movq	%rdx,%rbp
+	jmp	.Loop_outer
+
+.align	32
+.Loop_outer:
+	movl	$0x61707865,%eax
+	movl	$0x3320646e,%ebx
+	movl	$0x79622d32,%ecx
+	movl	$0x6b206574,%edx
+	movl	16(%rsp),%r8d
+	movl	20(%rsp),%r9d
+	movl	24(%rsp),%r10d
+	movl	28(%rsp),%r11d
+	movd	%xmm3,%r12d
+	movl	52(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	60(%rsp),%r15d
+
+	movq	%rbp,64+0(%rsp)
+	movl	$10,%ebp
+	movq	%rsi,64+8(%rsp)
+.byte	102,72,15,126,214
+	movq	%rdi,64+16(%rsp)
+	movq	%rsi,%rdi
+	shrq	$32,%rdi
+	jmp	.Loop
+
+.align	32
+.Loop:
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$16,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$16,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$12,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$12,%r9d
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$8,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$8,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$7,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$7,%r9d
+	movl	%esi,32(%rsp)
+	movl	%edi,36(%rsp)
+	movl	40(%rsp),%esi
+	movl	44(%rsp),%edi
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$16,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$16,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$12,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$12,%r11d
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$8,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$8,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$7,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$7,%r11d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$16,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$16,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$12,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$12,%r10d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$8,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$8,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$7,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$7,%r10d
+	movl	%esi,40(%rsp)
+	movl	%edi,44(%rsp)
+	movl	32(%rsp),%esi
+	movl	36(%rsp),%edi
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$16,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$16,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$12,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$12,%r8d
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$8,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$8,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$7,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$7,%r8d
+	decl	%ebp
+	jnz	.Loop
+	movl	%edi,36(%rsp)
+	movl	%esi,32(%rsp)
+	movq	64(%rsp),%rbp
+	movdqa	%xmm2,%xmm1
+	movq	64+8(%rsp),%rsi
+	paddd	%xmm4,%xmm3
+	movq	64+16(%rsp),%rdi
+
+	addl	$0x61707865,%eax
+	addl	$0x3320646e,%ebx
+	addl	$0x79622d32,%ecx
+	addl	$0x6b206574,%edx
+	addl	16(%rsp),%r8d
+	addl	20(%rsp),%r9d
+	addl	24(%rsp),%r10d
+	addl	28(%rsp),%r11d
+	addl	48(%rsp),%r12d
+	addl	52(%rsp),%r13d
+	addl	56(%rsp),%r14d
+	addl	60(%rsp),%r15d
+	paddd	32(%rsp),%xmm1
+
+	cmpq	$64,%rbp
+	jb	.Ltail
+
+	xorl	0(%rsi),%eax
+	xorl	4(%rsi),%ebx
+	xorl	8(%rsi),%ecx
+	xorl	12(%rsi),%edx
+	xorl	16(%rsi),%r8d
+	xorl	20(%rsi),%r9d
+	xorl	24(%rsi),%r10d
+	xorl	28(%rsi),%r11d
+	movdqu	32(%rsi),%xmm0
+	xorl	48(%rsi),%r12d
+	xorl	52(%rsi),%r13d
+	xorl	56(%rsi),%r14d
+	xorl	60(%rsi),%r15d
+	leaq	64(%rsi),%rsi
+	pxor	%xmm1,%xmm0
+
+	movdqa	%xmm2,32(%rsp)
+	movd	%xmm3,48(%rsp)
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movl	%r12d,48(%rdi)
+	movl	%r13d,52(%rdi)
+	movl	%r14d,56(%rdi)
+	movl	%r15d,60(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rbp
+	jnz	.Loop_outer
+
+	jmp	.Ldone
+
+.align	16
+.Ltail:
+	movl	%eax,0(%rsp)
+	movl	%ebx,4(%rsp)
+	xorq	%rbx,%rbx
+	movl	%ecx,8(%rsp)
+	movl	%edx,12(%rsp)
+	movl	%r8d,16(%rsp)
+	movl	%r9d,20(%rsp)
+	movl	%r10d,24(%rsp)
+	movl	%r11d,28(%rsp)
+	movdqa	%xmm1,32(%rsp)
+	movl	%r12d,48(%rsp)
+	movl	%r13d,52(%rsp)
+	movl	%r14d,56(%rsp)
+	movl	%r15d,60(%rsp)
+
+.Loop_tail:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%edx
+	leaq	1(%rbx),%rbx
+	xorl	%edx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rbp
+	jnz	.Loop_tail
+
+.Ldone:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+.Lno_data:
+	.byte	0xf3,0xc3
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+.type	ChaCha20_ssse3,@function
+.align	32
+ChaCha20_ssse3:
+.LChaCha20_ssse3:
+	cmpq	$128,%rdx
+	ja	.LChaCha20_4x
+
+.Ldo_sse3_after_all:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	subq	$64+24,%rsp
+	movdqa	.Lsigma(%rip),%xmm0
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	.Lrot16(%rip),%xmm6
+	movdqa	.Lrot24(%rip),%xmm7
+
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movl	$10,%ebp
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_outer_ssse3:
+	movdqa	.Lone(%rip),%xmm3
+	movdqa	0(%rsp),%xmm0
+	movdqa	16(%rsp),%xmm1
+	movdqa	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+	movl	$10,%ebp
+	movdqa	%xmm3,48(%rsp)
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_ssse3:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%ebp
+	jnz	.Loop_ssse3
+	paddd	0(%rsp),%xmm0
+	paddd	16(%rsp),%xmm1
+	paddd	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+
+	cmpq	$64,%rdx
+	jb	.Ltail_ssse3
+
+	movdqu	0(%rsi),%xmm4
+	movdqu	16(%rsi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%rsi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%rsi),%xmm5
+	leaq	64(%rsi),%rsi
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm1,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rdx
+	jnz	.Loop_outer_ssse3
+
+	jmp	.Ldone_ssse3
+
+.align	16
+.Ltail_ssse3:
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	xorq	%rbx,%rbx
+
+.Loop_tail_ssse3:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%ecx
+	leaq	1(%rbx),%rbx
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rdx
+	jnz	.Loop_tail_ssse3
+
+.Ldone_ssse3:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+	.byte	0xf3,0xc3
+.size	ChaCha20_ssse3,.-ChaCha20_ssse3
+.type	ChaCha20_4x,@function
+.align	32
+ChaCha20_4x:
+.LChaCha20_4x:
+	movq	%r10,%r11
+	shrq	$32,%r10
+	testq	$32,%r10
+	jnz	.LChaCha20_8x
+	cmpq	$192,%rdx
+	ja	.Lproceed4x
+
+	andq	$71303168,%r11
+	cmpq	$4194304,%r11
+	je	.Ldo_sse3_after_all
+
+.Lproceed4x:
+	leaq	-120(%rsp),%r11
+	subq	$0x148+0,%rsp
+	movdqa	.Lsigma(%rip),%xmm11
+	movdqu	(%rcx),%xmm15
+	movdqu	16(%rcx),%xmm7
+	movdqu	(%r8),%xmm3
+	leaq	256(%rsp),%rcx
+	leaq	.Lrot16(%rip),%r10
+	leaq	.Lrot24(%rip),%r11
+
+	pshufd	$0x00,%xmm11,%xmm8
+	pshufd	$0x55,%xmm11,%xmm9
+	movdqa	%xmm8,64(%rsp)
+	pshufd	$0xaa,%xmm11,%xmm10
+	movdqa	%xmm9,80(%rsp)
+	pshufd	$0xff,%xmm11,%xmm11
+	movdqa	%xmm10,96(%rsp)
+	movdqa	%xmm11,112(%rsp)
+
+	pshufd	$0x00,%xmm15,%xmm12
+	pshufd	$0x55,%xmm15,%xmm13
+	movdqa	%xmm12,128-256(%rcx)
+	pshufd	$0xaa,%xmm15,%xmm14
+	movdqa	%xmm13,144-256(%rcx)
+	pshufd	$0xff,%xmm15,%xmm15
+	movdqa	%xmm14,160-256(%rcx)
+	movdqa	%xmm15,176-256(%rcx)
+
+	pshufd	$0x00,%xmm7,%xmm4
+	pshufd	$0x55,%xmm7,%xmm5
+	movdqa	%xmm4,192-256(%rcx)
+	pshufd	$0xaa,%xmm7,%xmm6
+	movdqa	%xmm5,208-256(%rcx)
+	pshufd	$0xff,%xmm7,%xmm7
+	movdqa	%xmm6,224-256(%rcx)
+	movdqa	%xmm7,240-256(%rcx)
+
+	pshufd	$0x00,%xmm3,%xmm0
+	pshufd	$0x55,%xmm3,%xmm1
+	paddd	.Linc(%rip),%xmm0
+	pshufd	$0xaa,%xmm3,%xmm2
+	movdqa	%xmm1,272-256(%rcx)
+	pshufd	$0xff,%xmm3,%xmm3
+	movdqa	%xmm2,288-256(%rcx)
+	movdqa	%xmm3,304-256(%rcx)
+
+	jmp	.Loop_enter4x
+
+.align	32
+.Loop_outer4x:
+	movdqa	64(%rsp),%xmm8
+	movdqa	80(%rsp),%xmm9
+	movdqa	96(%rsp),%xmm10
+	movdqa	112(%rsp),%xmm11
+	movdqa	128-256(%rcx),%xmm12
+	movdqa	144-256(%rcx),%xmm13
+	movdqa	160-256(%rcx),%xmm14
+	movdqa	176-256(%rcx),%xmm15
+	movdqa	192-256(%rcx),%xmm4
+	movdqa	208-256(%rcx),%xmm5
+	movdqa	224-256(%rcx),%xmm6
+	movdqa	240-256(%rcx),%xmm7
+	movdqa	256-256(%rcx),%xmm0
+	movdqa	272-256(%rcx),%xmm1
+	movdqa	288-256(%rcx),%xmm2
+	movdqa	304-256(%rcx),%xmm3
+	paddd	.Lfour(%rip),%xmm0
+
+.Loop_enter4x:
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm7,48(%rsp)
+	movdqa	(%r10),%xmm7
+	movl	$10,%eax
+	movdqa	%xmm0,256-256(%rcx)
+	jmp	.Loop4x
+
+.align	32
+.Loop4x:
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,199
+.byte	102,15,56,0,207
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm6
+	pslld	$12,%xmm12
+	psrld	$20,%xmm6
+	movdqa	%xmm13,%xmm7
+	pslld	$12,%xmm13
+	por	%xmm6,%xmm12
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm13
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,198
+.byte	102,15,56,0,206
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm7
+	pslld	$7,%xmm12
+	psrld	$25,%xmm7
+	movdqa	%xmm13,%xmm6
+	pslld	$7,%xmm13
+	por	%xmm7,%xmm12
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm13
+	movdqa	%xmm4,0(%rsp)
+	movdqa	%xmm5,16(%rsp)
+	movdqa	32(%rsp),%xmm4
+	movdqa	48(%rsp),%xmm5
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,215
+.byte	102,15,56,0,223
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm6
+	pslld	$12,%xmm14
+	psrld	$20,%xmm6
+	movdqa	%xmm15,%xmm7
+	pslld	$12,%xmm15
+	por	%xmm6,%xmm14
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm15
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm7
+	pslld	$7,%xmm14
+	psrld	$25,%xmm7
+	movdqa	%xmm15,%xmm6
+	pslld	$7,%xmm15
+	por	%xmm7,%xmm14
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm15
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,223
+.byte	102,15,56,0,199
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm6
+	pslld	$12,%xmm13
+	psrld	$20,%xmm6
+	movdqa	%xmm14,%xmm7
+	pslld	$12,%xmm14
+	por	%xmm6,%xmm13
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm14
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,222
+.byte	102,15,56,0,198
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm7
+	pslld	$7,%xmm13
+	psrld	$25,%xmm7
+	movdqa	%xmm14,%xmm6
+	pslld	$7,%xmm14
+	por	%xmm7,%xmm13
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm14
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm5,48(%rsp)
+	movdqa	0(%rsp),%xmm4
+	movdqa	16(%rsp),%xmm5
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,207
+.byte	102,15,56,0,215
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm6
+	pslld	$12,%xmm15
+	psrld	$20,%xmm6
+	movdqa	%xmm12,%xmm7
+	pslld	$12,%xmm12
+	por	%xmm6,%xmm15
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm12
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm7
+	pslld	$7,%xmm15
+	psrld	$25,%xmm7
+	movdqa	%xmm12,%xmm6
+	pslld	$7,%xmm12
+	por	%xmm7,%xmm15
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm12
+	decl	%eax
+	jnz	.Loop4x
+
+	paddd	64(%rsp),%xmm8
+	paddd	80(%rsp),%xmm9
+	paddd	96(%rsp),%xmm10
+	paddd	112(%rsp),%xmm11
+
+	movdqa	%xmm8,%xmm6
+	punpckldq	%xmm9,%xmm8
+	movdqa	%xmm10,%xmm7
+	punpckldq	%xmm11,%xmm10
+	punpckhdq	%xmm9,%xmm6
+	punpckhdq	%xmm11,%xmm7
+	movdqa	%xmm8,%xmm9
+	punpcklqdq	%xmm10,%xmm8
+	movdqa	%xmm6,%xmm11
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm10,%xmm9
+	punpckhqdq	%xmm7,%xmm11
+	paddd	128-256(%rcx),%xmm12
+	paddd	144-256(%rcx),%xmm13
+	paddd	160-256(%rcx),%xmm14
+	paddd	176-256(%rcx),%xmm15
+
+	movdqa	%xmm8,0(%rsp)
+	movdqa	%xmm9,16(%rsp)
+	movdqa	32(%rsp),%xmm8
+	movdqa	48(%rsp),%xmm9
+
+	movdqa	%xmm12,%xmm10
+	punpckldq	%xmm13,%xmm12
+	movdqa	%xmm14,%xmm7
+	punpckldq	%xmm15,%xmm14
+	punpckhdq	%xmm13,%xmm10
+	punpckhdq	%xmm15,%xmm7
+	movdqa	%xmm12,%xmm13
+	punpcklqdq	%xmm14,%xmm12
+	movdqa	%xmm10,%xmm15
+	punpcklqdq	%xmm7,%xmm10
+	punpckhqdq	%xmm14,%xmm13
+	punpckhqdq	%xmm7,%xmm15
+	paddd	192-256(%rcx),%xmm4
+	paddd	208-256(%rcx),%xmm5
+	paddd	224-256(%rcx),%xmm8
+	paddd	240-256(%rcx),%xmm9
+
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm11,48(%rsp)
+
+	movdqa	%xmm4,%xmm14
+	punpckldq	%xmm5,%xmm4
+	movdqa	%xmm8,%xmm7
+	punpckldq	%xmm9,%xmm8
+	punpckhdq	%xmm5,%xmm14
+	punpckhdq	%xmm9,%xmm7
+	movdqa	%xmm4,%xmm5
+	punpcklqdq	%xmm8,%xmm4
+	movdqa	%xmm14,%xmm9
+	punpcklqdq	%xmm7,%xmm14
+	punpckhqdq	%xmm8,%xmm5
+	punpckhqdq	%xmm7,%xmm9
+	paddd	256-256(%rcx),%xmm0
+	paddd	272-256(%rcx),%xmm1
+	paddd	288-256(%rcx),%xmm2
+	paddd	304-256(%rcx),%xmm3
+
+	movdqa	%xmm0,%xmm8
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm8
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm8,%xmm3
+	punpcklqdq	%xmm7,%xmm8
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	cmpq	$256,%rdx
+	jb	.Ltail4x
+
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	48(%rsp),%xmm6
+	pxor	%xmm15,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$256,%rdx
+	jnz	.Loop_outer4x
+
+	jmp	.Ldone4x
+
+.Ltail4x:
+	cmpq	$192,%rdx
+	jae	.L192_or_more4x
+	cmpq	$128,%rdx
+	jae	.L128_or_more4x
+	cmpq	$64,%rdx
+	jae	.L64_or_more4x
+
+
+	xorq	%r10,%r10
+
+	movdqa	%xmm12,16(%rsp)
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm0,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L64_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	.Ldone4x
+
+	movdqa	16(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm13,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm5,32(%rsp)
+	subq	$64,%rdx
+	movdqa	%xmm1,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L128_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	je	.Ldone4x
+
+	movdqa	32(%rsp),%xmm6
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm10,16(%rsp)
+	leaq	128(%rdi),%rdi
+	movdqa	%xmm14,32(%rsp)
+	subq	$128,%rdx
+	movdqa	%xmm8,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L192_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	.Ldone4x
+
+	movdqa	48(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm15,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm9,32(%rsp)
+	subq	$192,%rdx
+	movdqa	%xmm3,48(%rsp)
+
+.Loop_tail4x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	.Loop_tail4x
+
+.Ldone4x:
+	addq	$0x148+0,%rsp
+	.byte	0xf3,0xc3
+.size	ChaCha20_4x,.-ChaCha20_4x
+.type	ChaCha20_8x,@function
+.align	32
+ChaCha20_8x:
+.LChaCha20_8x:
+	movq	%rsp,%r10
+	subq	$0x280+8,%rsp
+	andq	$-32,%rsp
+	vzeroupper
+	movq	%r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	.Lsigma(%rip),%ymm11
+	vbroadcasti128	(%rcx),%ymm3
+	vbroadcasti128	16(%rcx),%ymm15
+	vbroadcasti128	(%r8),%ymm7
+	leaq	256(%rsp),%rcx
+	leaq	512(%rsp),%rax
+	leaq	.Lrot16(%rip),%r10
+	leaq	.Lrot24(%rip),%r11
+
+	vpshufd	$0x00,%ymm11,%ymm8
+	vpshufd	$0x55,%ymm11,%ymm9
+	vmovdqa	%ymm8,128-256(%rcx)
+	vpshufd	$0xaa,%ymm11,%ymm10
+	vmovdqa	%ymm9,160-256(%rcx)
+	vpshufd	$0xff,%ymm11,%ymm11
+	vmovdqa	%ymm10,192-256(%rcx)
+	vmovdqa	%ymm11,224-256(%rcx)
+
+	vpshufd	$0x00,%ymm3,%ymm0
+	vpshufd	$0x55,%ymm3,%ymm1
+	vmovdqa	%ymm0,256-256(%rcx)
+	vpshufd	$0xaa,%ymm3,%ymm2
+	vmovdqa	%ymm1,288-256(%rcx)
+	vpshufd	$0xff,%ymm3,%ymm3
+	vmovdqa	%ymm2,320-256(%rcx)
+	vmovdqa	%ymm3,352-256(%rcx)
+
+	vpshufd	$0x00,%ymm15,%ymm12
+	vpshufd	$0x55,%ymm15,%ymm13
+	vmovdqa	%ymm12,384-512(%rax)
+	vpshufd	$0xaa,%ymm15,%ymm14
+	vmovdqa	%ymm13,416-512(%rax)
+	vpshufd	$0xff,%ymm15,%ymm15
+	vmovdqa	%ymm14,448-512(%rax)
+	vmovdqa	%ymm15,480-512(%rax)
+
+	vpshufd	$0x00,%ymm7,%ymm4
+	vpshufd	$0x55,%ymm7,%ymm5
+	vpaddd	.Lincy(%rip),%ymm4,%ymm4
+	vpshufd	$0xaa,%ymm7,%ymm6
+	vmovdqa	%ymm5,544-512(%rax)
+	vpshufd	$0xff,%ymm7,%ymm7
+	vmovdqa	%ymm6,576-512(%rax)
+	vmovdqa	%ymm7,608-512(%rax)
+
+	jmp	.Loop_enter8x
+
+.align	32
+.Loop_outer8x:
+	vmovdqa	128-256(%rcx),%ymm8
+	vmovdqa	160-256(%rcx),%ymm9
+	vmovdqa	192-256(%rcx),%ymm10
+	vmovdqa	224-256(%rcx),%ymm11
+	vmovdqa	256-256(%rcx),%ymm0
+	vmovdqa	288-256(%rcx),%ymm1
+	vmovdqa	320-256(%rcx),%ymm2
+	vmovdqa	352-256(%rcx),%ymm3
+	vmovdqa	384-512(%rax),%ymm12
+	vmovdqa	416-512(%rax),%ymm13
+	vmovdqa	448-512(%rax),%ymm14
+	vmovdqa	480-512(%rax),%ymm15
+	vmovdqa	512-512(%rax),%ymm4
+	vmovdqa	544-512(%rax),%ymm5
+	vmovdqa	576-512(%rax),%ymm6
+	vmovdqa	608-512(%rax),%ymm7
+	vpaddd	.Leight(%rip),%ymm4,%ymm4
+
+.Loop_enter8x:
+	vmovdqa	%ymm14,64(%rsp)
+	vmovdqa	%ymm15,96(%rsp)
+	vbroadcasti128	(%r10),%ymm15
+	vmovdqa	%ymm4,512-512(%rax)
+	movl	$10,%eax
+	jmp	.Loop8x
+
+.align	32
+.Loop8x:
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$12,%ymm0,%ymm14
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$12,%ymm1,%ymm15
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$7,%ymm0,%ymm15
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$7,%ymm1,%ymm14
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vmovdqa	%ymm12,0(%rsp)
+	vmovdqa	%ymm13,32(%rsp)
+	vmovdqa	64(%rsp),%ymm12
+	vmovdqa	96(%rsp),%ymm13
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$12,%ymm2,%ymm14
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$12,%ymm3,%ymm15
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$7,%ymm2,%ymm15
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$7,%ymm3,%ymm14
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$12,%ymm1,%ymm14
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$12,%ymm2,%ymm15
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$7,%ymm1,%ymm15
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$7,%ymm2,%ymm14
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vmovdqa	%ymm12,64(%rsp)
+	vmovdqa	%ymm13,96(%rsp)
+	vmovdqa	0(%rsp),%ymm12
+	vmovdqa	32(%rsp),%ymm13
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$12,%ymm3,%ymm14
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$12,%ymm0,%ymm15
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$7,%ymm3,%ymm15
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$7,%ymm0,%ymm14
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	decl	%eax
+	jnz	.Loop8x
+
+	leaq	512(%rsp),%rax
+	vpaddd	128-256(%rcx),%ymm8,%ymm8
+	vpaddd	160-256(%rcx),%ymm9,%ymm9
+	vpaddd	192-256(%rcx),%ymm10,%ymm10
+	vpaddd	224-256(%rcx),%ymm11,%ymm11
+
+	vpunpckldq	%ymm9,%ymm8,%ymm14
+	vpunpckldq	%ymm11,%ymm10,%ymm15
+	vpunpckhdq	%ymm9,%ymm8,%ymm8
+	vpunpckhdq	%ymm11,%ymm10,%ymm10
+	vpunpcklqdq	%ymm15,%ymm14,%ymm9
+	vpunpckhqdq	%ymm15,%ymm14,%ymm14
+	vpunpcklqdq	%ymm10,%ymm8,%ymm11
+	vpunpckhqdq	%ymm10,%ymm8,%ymm8
+	vpaddd	256-256(%rcx),%ymm0,%ymm0
+	vpaddd	288-256(%rcx),%ymm1,%ymm1
+	vpaddd	320-256(%rcx),%ymm2,%ymm2
+	vpaddd	352-256(%rcx),%ymm3,%ymm3
+
+	vpunpckldq	%ymm1,%ymm0,%ymm10
+	vpunpckldq	%ymm3,%ymm2,%ymm15
+	vpunpckhdq	%ymm1,%ymm0,%ymm0
+	vpunpckhdq	%ymm3,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm10,%ymm1
+	vpunpckhqdq	%ymm15,%ymm10,%ymm10
+	vpunpcklqdq	%ymm2,%ymm0,%ymm3
+	vpunpckhqdq	%ymm2,%ymm0,%ymm0
+	vperm2i128	$0x20,%ymm1,%ymm9,%ymm15
+	vperm2i128	$0x31,%ymm1,%ymm9,%ymm1
+	vperm2i128	$0x20,%ymm10,%ymm14,%ymm9
+	vperm2i128	$0x31,%ymm10,%ymm14,%ymm10
+	vperm2i128	$0x20,%ymm3,%ymm11,%ymm14
+	vperm2i128	$0x31,%ymm3,%ymm11,%ymm3
+	vperm2i128	$0x20,%ymm0,%ymm8,%ymm11
+	vperm2i128	$0x31,%ymm0,%ymm8,%ymm0
+	vmovdqa	%ymm15,0(%rsp)
+	vmovdqa	%ymm9,32(%rsp)
+	vmovdqa	64(%rsp),%ymm15
+	vmovdqa	96(%rsp),%ymm9
+
+	vpaddd	384-512(%rax),%ymm12,%ymm12
+	vpaddd	416-512(%rax),%ymm13,%ymm13
+	vpaddd	448-512(%rax),%ymm15,%ymm15
+	vpaddd	480-512(%rax),%ymm9,%ymm9
+
+	vpunpckldq	%ymm13,%ymm12,%ymm2
+	vpunpckldq	%ymm9,%ymm15,%ymm8
+	vpunpckhdq	%ymm13,%ymm12,%ymm12
+	vpunpckhdq	%ymm9,%ymm15,%ymm15
+	vpunpcklqdq	%ymm8,%ymm2,%ymm13
+	vpunpckhqdq	%ymm8,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm12,%ymm9
+	vpunpckhqdq	%ymm15,%ymm12,%ymm12
+	vpaddd	512-512(%rax),%ymm4,%ymm4
+	vpaddd	544-512(%rax),%ymm5,%ymm5
+	vpaddd	576-512(%rax),%ymm6,%ymm6
+	vpaddd	608-512(%rax),%ymm7,%ymm7
+
+	vpunpckldq	%ymm5,%ymm4,%ymm15
+	vpunpckldq	%ymm7,%ymm6,%ymm8
+	vpunpckhdq	%ymm5,%ymm4,%ymm4
+	vpunpckhdq	%ymm7,%ymm6,%ymm6
+	vpunpcklqdq	%ymm8,%ymm15,%ymm5
+	vpunpckhqdq	%ymm8,%ymm15,%ymm15
+	vpunpcklqdq	%ymm6,%ymm4,%ymm7
+	vpunpckhqdq	%ymm6,%ymm4,%ymm4
+	vperm2i128	$0x20,%ymm5,%ymm13,%ymm8
+	vperm2i128	$0x31,%ymm5,%ymm13,%ymm5
+	vperm2i128	$0x20,%ymm15,%ymm2,%ymm13
+	vperm2i128	$0x31,%ymm15,%ymm2,%ymm15
+	vperm2i128	$0x20,%ymm7,%ymm9,%ymm2
+	vperm2i128	$0x31,%ymm7,%ymm9,%ymm7
+	vperm2i128	$0x20,%ymm4,%ymm12,%ymm9
+	vperm2i128	$0x31,%ymm4,%ymm12,%ymm4
+	vmovdqa	0(%rsp),%ymm6
+	vmovdqa	32(%rsp),%ymm12
+
+	cmpq	$512,%rdx
+	jb	.Ltail8x
+
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm12,%ymm12
+	vpxor	32(%rsi),%ymm13,%ymm13
+	vpxor	64(%rsi),%ymm10,%ymm10
+	vpxor	96(%rsi),%ymm15,%ymm15
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm12,0(%rdi)
+	vmovdqu	%ymm13,32(%rdi)
+	vmovdqu	%ymm10,64(%rdi)
+	vmovdqu	%ymm15,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm14,%ymm14
+	vpxor	32(%rsi),%ymm2,%ymm2
+	vpxor	64(%rsi),%ymm3,%ymm3
+	vpxor	96(%rsi),%ymm7,%ymm7
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm14,0(%rdi)
+	vmovdqu	%ymm2,32(%rdi)
+	vmovdqu	%ymm3,64(%rdi)
+	vmovdqu	%ymm7,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm11,%ymm11
+	vpxor	32(%rsi),%ymm9,%ymm9
+	vpxor	64(%rsi),%ymm0,%ymm0
+	vpxor	96(%rsi),%ymm4,%ymm4
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm11,0(%rdi)
+	vmovdqu	%ymm9,32(%rdi)
+	vmovdqu	%ymm0,64(%rdi)
+	vmovdqu	%ymm4,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$512,%rdx
+	jnz	.Loop_outer8x
+
+	jmp	.Ldone8x
+
+.Ltail8x:
+	cmpq	$448,%rdx
+	jae	.L448_or_more8x
+	cmpq	$384,%rdx
+	jae	.L384_or_more8x
+	cmpq	$320,%rdx
+	jae	.L320_or_more8x
+	cmpq	$256,%rdx
+	jae	.L256_or_more8x
+	cmpq	$192,%rdx
+	jae	.L192_or_more8x
+	cmpq	$128,%rdx
+	jae	.L128_or_more8x
+	cmpq	$64,%rdx
+	jae	.L64_or_more8x
+
+	xorq	%r10,%r10
+	vmovdqa	%ymm6,0(%rsp)
+	vmovdqa	%ymm8,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L64_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	je	.Ldone8x
+
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm1,0(%rsp)
+	leaq	64(%rdi),%rdi
+	subq	$64,%rdx
+	vmovdqa	%ymm5,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L128_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	je	.Ldone8x
+
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm12,0(%rsp)
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	vmovdqa	%ymm13,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L192_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	je	.Ldone8x
+
+	leaq	192(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm10,0(%rsp)
+	leaq	192(%rdi),%rdi
+	subq	$192,%rdx
+	vmovdqa	%ymm15,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L256_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	je	.Ldone8x
+
+	leaq	256(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm14,0(%rsp)
+	leaq	256(%rdi),%rdi
+	subq	$256,%rdx
+	vmovdqa	%ymm2,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L320_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	je	.Ldone8x
+
+	leaq	320(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm3,0(%rsp)
+	leaq	320(%rdi),%rdi
+	subq	$320,%rdx
+	vmovdqa	%ymm7,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L384_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	je	.Ldone8x
+
+	leaq	384(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm11,0(%rsp)
+	leaq	384(%rdi),%rdi
+	subq	$384,%rdx
+	vmovdqa	%ymm9,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L448_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vpxor	384(%rsi),%ymm11,%ymm11
+	vpxor	416(%rsi),%ymm9,%ymm9
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	vmovdqu	%ymm11,384(%rdi)
+	vmovdqu	%ymm9,416(%rdi)
+	je	.Ldone8x
+
+	leaq	448(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm0,0(%rsp)
+	leaq	448(%rdi),%rdi
+	subq	$448,%rdx
+	vmovdqa	%ymm4,32(%rsp)
+
+.Loop_tail8x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	.Loop_tail8x
+
+.Ldone8x:
+	vzeroall
+	movq	640(%rsp),%rsp
+	.byte	0xf3,0xc3
+.size	ChaCha20_8x,.-ChaCha20_8x
+#endif
diff --git a/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
index 2884c69..4abce6f 100644
--- a/linux-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -894,6 +894,7 @@
 	pushq	%r15
 	subq	$160+8,%rsp
 
+.Lpoint_double_shortcutq:
 	movdqu	0(%rsi),%xmm0
 	movq	%rsi,%rbx
 	movdqu	16(%rsi),%xmm1
@@ -1115,7 +1116,7 @@
 	por	%xmm1,%xmm3
 
 	movdqu	0(%rsi),%xmm0
-	pshufd	$177,%xmm3,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm5
 	movdqu	16(%rsi),%xmm1
 	movdqu	32(%rsi),%xmm2
 	por	%xmm3,%xmm5
@@ -1125,7 +1126,7 @@
 	movq	64+16(%rsi),%r15
 	movq	64+24(%rsi),%r8
 	movdqa	%xmm0,480(%rsp)
-	pshufd	$30,%xmm5,%xmm4
+	pshufd	$0x1e,%xmm5,%xmm4
 	movdqa	%xmm1,480+16(%rsp)
 	por	%xmm0,%xmm1
 .byte	102,72,15,110,199
@@ -1145,10 +1146,10 @@
 	call	__ecp_nistz256_sqr_montq
 
 	pcmpeqd	%xmm4,%xmm5
-	pshufd	$177,%xmm3,%xmm4
+	pshufd	$0xb1,%xmm3,%xmm4
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
-	pshufd	$30,%xmm4,%xmm3
+	pshufd	$0x1e,%xmm4,%xmm3
 	por	%xmm3,%xmm4
 	pxor	%xmm3,%xmm3
 	pcmpeqd	%xmm3,%xmm4
@@ -1157,6 +1158,7 @@
 	movq	64+8(%rbx),%r14
 	movq	64+16(%rbx),%r15
 	movq	64+24(%rbx),%r8
+.byte	102,72,15,110,203
 
 	leaq	64-0(%rbx),%rsi
 	leaq	32(%rsp),%rdi
@@ -1248,7 +1250,7 @@
 	testq	%r8,%r8
 	jnz	.Ladd_proceedq
 	testq	%r9,%r9
-	jz	.Ladd_proceedq
+	jz	.Ladd_doubleq
 
 .byte	102,72,15,126,199
 	pxor	%xmm0,%xmm0
@@ -1261,6 +1263,13 @@
 	jmp	.Ladd_doneq
 
 .align	32
+.Ladd_doubleq:
+.byte	102,72,15,126,206
+.byte	102,72,15,126,199
+	addq	$416,%rsp
+	jmp	.Lpoint_double_shortcutq
+
+.align	32
 .Ladd_proceedq:
 	movq	0+64(%rsp),%rax
 	movq	8+64(%rsp),%r14
@@ -1508,13 +1517,13 @@
 	por	%xmm1,%xmm3
 
 	movdqu	0(%rbx),%xmm0
-	pshufd	$177,%xmm3,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm5
 	movdqu	16(%rbx),%xmm1
 	movdqu	32(%rbx),%xmm2
 	por	%xmm3,%xmm5
 	movdqu	48(%rbx),%xmm3
 	movdqa	%xmm0,416(%rsp)
-	pshufd	$30,%xmm5,%xmm4
+	pshufd	$0x1e,%xmm5,%xmm4
 	movdqa	%xmm1,416+16(%rsp)
 	por	%xmm0,%xmm1
 .byte	102,72,15,110,199
@@ -1530,13 +1539,13 @@
 	call	__ecp_nistz256_sqr_montq
 
 	pcmpeqd	%xmm4,%xmm5
-	pshufd	$177,%xmm3,%xmm4
+	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rax
 
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
-	pshufd	$30,%xmm4,%xmm3
+	pshufd	$0x1e,%xmm4,%xmm3
 	movq	%r13,%r10
 	por	%xmm3,%xmm4
 	pxor	%xmm3,%xmm3
diff --git a/linux-x86_64/crypto/md5/md5-x86_64.S b/linux-x86_64/crypto/md5/md5-x86_64.S
index 7644689..05369e2 100644
--- a/linux-x86_64/crypto/md5/md5-x86_64.S
+++ b/linux-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@
 	movl	%ecx,%r11d
 	addl	%ecx,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	xorl	%edx,%r11d
 	leal	-198630844(%rax,%r10,1),%eax
 	orl	%ebx,%r11d
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	28(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -511,7 +511,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	56(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -520,7 +520,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	20(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -529,7 +529,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	48(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -538,7 +538,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	12(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -547,7 +547,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	40(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -556,7 +556,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	4(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -565,7 +565,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	32(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -574,7 +574,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	60(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -583,7 +583,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	24(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -592,7 +592,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	52(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -601,7 +601,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	16(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -610,7 +610,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	44(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -619,7 +619,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	8(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -628,7 +628,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	36(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -637,7 +637,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
diff --git a/linux-x86_64/crypto/modes/ghash-x86_64.S b/linux-x86_64/crypto/modes/ghash-x86_64.S
index 1db7d69..b47bdc9 100644
--- a/linux-x86_64/crypto/modes/ghash-x86_64.S
+++ b/linux-x86_64/crypto/modes/ghash-x86_64.S
@@ -23,14 +23,14 @@
 	movq	$14,%rcx
 	movq	8(%rsi,%rax,1),%r8
 	movq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	movq	%r8,%rdx
 	jmp	.Loop1
 
 .align	16
 .Loop1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	movb	(%rdi,%rcx,1),%al
 	shrq	$4,%r9
@@ -46,13 +46,13 @@
 	js	.Lbreak1
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
@@ -61,19 +61,19 @@
 .align	16
 .Lbreak1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rbx,1),%r8
@@ -881,20 +881,20 @@
 	movdqu	32(%rsi),%xmm7
 .byte	102,65,15,56,0,194
 
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	.Lodd_tail
 
 	movdqu	16(%rsi),%xmm6
 	movl	OPENSSL_ia32cap_P+4(%rip),%eax
-	cmpq	$48,%rcx
+	cmpq	$0x30,%rcx
 	jb	.Lskip4x
 
 	andl	$71303168,%eax
 	cmpl	$4194304,%eax
 	je	.Lskip4x
 
-	subq	$48,%rcx
-	movq	$11547335547999543296,%rax
+	subq	$0x30,%rcx
+	movq	$0xA040608020C0E000,%rax
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
@@ -941,7 +941,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jc	.Ltail4x
 
 	jmp	.Lmod4_loop
@@ -1024,7 +1024,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jnc	.Lmod4_loop
 
 .Ltail4x:
@@ -1068,10 +1068,10 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-	addq	$64,%rcx
+	addq	$0x40,%rcx
 	jz	.Ldone
 	movdqu	32(%rsi),%xmm7
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	.Lodd_tail
 .Lskip4x:
 
@@ -1094,7 +1094,7 @@
 
 	leaq	32(%rdx),%rdx
 	nop
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	jbe	.Leven_tail
 	nop
 	jmp	.Lmod_loop
@@ -1157,7 +1157,7 @@
 .byte	102,15,58,68,231,0
 	pxor	%xmm1,%xmm0
 
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	ja	.Lmod_loop
 
 .Leven_tail:
diff --git a/mac-x86/crypto/chacha/chacha-x86.S b/mac-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 0000000..9bd31b8
--- /dev/null
+++ b/mac-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,989 @@
+#if defined(__i386__)
+.file	"chacha-x86.S"
+.text
+.globl	_ChaCha20_ctr32
+.private_extern	_ChaCha20_ctr32
+.align	4
+_ChaCha20_ctr32:
+L_ChaCha20_ctr32_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	xorl	%eax,%eax
+	cmpl	28(%esp),%eax
+	je	L000no_data
+	call	Lpic_point
+Lpic_point:
+	popl	%eax
+	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-Lpic_point(%eax),%ebp
+	testl	$16777216,(%ebp)
+	jz	L001x86
+	testl	$512,4(%ebp)
+	jz	L001x86
+	jmp	Lssse3_shortcut
+L001x86:
+	movl	32(%esp),%esi
+	movl	36(%esp),%edi
+	subl	$132,%esp
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edx
+	movl	%eax,80(%esp)
+	movl	%ebx,84(%esp)
+	movl	%ecx,88(%esp)
+	movl	%edx,92(%esp)
+	movl	16(%esi),%eax
+	movl	20(%esi),%ebx
+	movl	24(%esi),%ecx
+	movl	28(%esi),%edx
+	movl	%eax,96(%esp)
+	movl	%ebx,100(%esp)
+	movl	%ecx,104(%esp)
+	movl	%edx,108(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	subl	$1,%eax
+	movl	%eax,112(%esp)
+	movl	%ebx,116(%esp)
+	movl	%ecx,120(%esp)
+	movl	%edx,124(%esp)
+	jmp	L002entry
+.align	4,0x90
+L003outer_loop:
+	movl	%ebx,156(%esp)
+	movl	%eax,152(%esp)
+	movl	%ecx,160(%esp)
+L002entry:
+	movl	$1634760805,%eax
+	movl	$857760878,4(%esp)
+	movl	$2036477234,8(%esp)
+	movl	$1797285236,12(%esp)
+	movl	84(%esp),%ebx
+	movl	88(%esp),%ebp
+	movl	104(%esp),%ecx
+	movl	108(%esp),%esi
+	movl	116(%esp),%edx
+	movl	120(%esp),%edi
+	movl	%ebx,20(%esp)
+	movl	%ebp,24(%esp)
+	movl	%ecx,40(%esp)
+	movl	%esi,44(%esp)
+	movl	%edx,52(%esp)
+	movl	%edi,56(%esp)
+	movl	92(%esp),%ebx
+	movl	124(%esp),%edi
+	movl	112(%esp),%edx
+	movl	80(%esp),%ebp
+	movl	96(%esp),%ecx
+	movl	100(%esp),%esi
+	addl	$1,%edx
+	movl	%ebx,28(%esp)
+	movl	%edi,60(%esp)
+	movl	%edx,112(%esp)
+	movl	$10,%ebx
+	jmp	L004loop
+.align	4,0x90
+L004loop:
+	addl	%ebp,%eax
+	movl	%ebx,128(%esp)
+	movl	%ebp,%ebx
+	xorl	%eax,%edx
+	roll	$16,%edx
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	52(%esp),%edi
+	roll	$12,%ebx
+	movl	20(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,48(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,32(%esp)
+	roll	$16,%edi
+	movl	%ebx,16(%esp)
+	addl	%edi,%esi
+	movl	40(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	56(%esp),%edx
+	roll	$12,%ebp
+	movl	24(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,52(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,36(%esp)
+	roll	$16,%edx
+	movl	%ebp,20(%esp)
+	addl	%edx,%ecx
+	movl	44(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	60(%esp),%edi
+	roll	$12,%ebx
+	movl	28(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,56(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,24(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	roll	$12,%ebp
+	movl	20(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,%edx
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	roll	$16,%edx
+	movl	%ebp,28(%esp)
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	48(%esp),%edi
+	roll	$12,%ebx
+	movl	24(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,60(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,40(%esp)
+	roll	$16,%edi
+	movl	%ebx,20(%esp)
+	addl	%edi,%esi
+	movl	32(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	52(%esp),%edx
+	roll	$12,%ebp
+	movl	28(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,48(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,44(%esp)
+	roll	$16,%edx
+	movl	%ebp,24(%esp)
+	addl	%edx,%ecx
+	movl	36(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	56(%esp),%edi
+	roll	$12,%ebx
+	movl	16(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,52(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,28(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	movl	48(%esp),%edx
+	roll	$12,%ebp
+	movl	128(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,56(%esp)
+	xorl	%esi,%ebp
+	roll	$7,%ebp
+	decl	%ebx
+	jnz	L004loop
+	movl	160(%esp),%ebx
+	addl	$1634760805,%eax
+	addl	80(%esp),%ebp
+	addl	96(%esp),%ecx
+	addl	100(%esp),%esi
+	cmpl	$64,%ebx
+	jb	L005tail
+	movl	156(%esp),%ebx
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	xorl	(%ebx),%eax
+	xorl	16(%ebx),%ebp
+	movl	%eax,(%esp)
+	movl	152(%esp),%eax
+	xorl	32(%ebx),%ecx
+	xorl	36(%ebx),%esi
+	xorl	48(%ebx),%edx
+	xorl	56(%ebx),%edi
+	movl	%ebp,16(%esp)
+	movl	(%esp),%ebp
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	%ebp,(%eax)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	xorl	4(%ebx),%ebp
+	xorl	8(%ebx),%ecx
+	xorl	12(%ebx),%esi
+	xorl	20(%ebx),%edx
+	xorl	24(%ebx),%edi
+	movl	%ebp,4(%eax)
+	movl	16(%esp),%ebp
+	movl	%ecx,8(%eax)
+	movl	%esi,12(%eax)
+	movl	%ebp,16(%eax)
+	movl	%edx,20(%eax)
+	movl	%edi,24(%eax)
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%edi
+	addl	92(%esp),%ecx
+	movl	40(%esp),%ebp
+	xorl	28(%ebx),%ecx
+	movl	44(%esp),%esi
+	movl	%ecx,28(%eax)
+	movl	%edx,32(%eax)
+	movl	%edi,36(%eax)
+	addl	104(%esp),%ebp
+	addl	108(%esp),%esi
+	xorl	40(%ebx),%ebp
+	xorl	44(%ebx),%esi
+	movl	%ebp,40(%eax)
+	movl	%esi,44(%eax)
+	movl	48(%esp),%ecx
+	movl	56(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	xorl	52(%ebx),%edx
+	xorl	60(%ebx),%edi
+	leal	64(%ebx),%ebx
+	movl	%ecx,48(%eax)
+	movl	160(%esp),%ecx
+	movl	%edx,52(%eax)
+	movl	%esi,56(%eax)
+	movl	%edi,60(%eax)
+	leal	64(%eax),%eax
+	subl	$64,%ecx
+	jnz	L003outer_loop
+	jmp	L006done
+L005tail:
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	movl	%eax,(%esp)
+	movl	%ebp,16(%esp)
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	movl	%ebp,4(%esp)
+	movl	%ecx,8(%esp)
+	movl	%esi,12(%esp)
+	movl	%edx,20(%esp)
+	movl	%edi,24(%esp)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	movl	%ebp,28(%esp)
+	movl	156(%esp),%ebp
+	movl	%ecx,40(%esp)
+	movl	152(%esp),%ecx
+	movl	%esi,44(%esp)
+	xorl	%esi,%esi
+	movl	%edx,52(%esp)
+	movl	%edi,60(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+L007tail_loop:
+	movb	(%esi,%ebp,1),%al
+	movb	(%esp,%esi,1),%dl
+	leal	1(%esi),%esi
+	xorb	%dl,%al
+	movb	%al,-1(%ecx,%esi,1)
+	decl	%ebx
+	jnz	L007tail_loop
+L006done:
+	addl	$132,%esp
+L000no_data:
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.globl	_ChaCha20_ssse3
+.private_extern	_ChaCha20_ssse3
+.align	4
+_ChaCha20_ssse3:
+L_ChaCha20_ssse3_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+Lssse3_shortcut:
+	movl	20(%esp),%edi
+	movl	24(%esp),%esi
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%ebx
+	movl	%esp,%ebp
+	subl	$524,%esp
+	andl	$-64,%esp
+	movl	%ebp,512(%esp)
+	leal	Lssse3_data-Lpic_point(%eax),%eax
+	movdqu	(%ebx),%xmm3
+	cmpl	$256,%ecx
+	jb	L0081x
+	movl	%edx,516(%esp)
+	movl	%ebx,520(%esp)
+	subl	$256,%ecx
+	leal	384(%esp),%ebp
+	movdqu	(%edx),%xmm7
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	paddd	48(%eax),%xmm0
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	psubd	64(%eax),%xmm0
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,64(%ebp)
+	movdqa	%xmm1,80(%ebp)
+	movdqa	%xmm2,96(%ebp)
+	movdqa	%xmm3,112(%ebp)
+	movdqu	16(%edx),%xmm3
+	movdqa	%xmm4,-64(%ebp)
+	movdqa	%xmm5,-48(%ebp)
+	movdqa	%xmm6,-32(%ebp)
+	movdqa	%xmm7,-16(%ebp)
+	movdqa	32(%eax),%xmm7
+	leal	128(%esp),%ebx
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,(%ebp)
+	movdqa	%xmm1,16(%ebp)
+	movdqa	%xmm2,32(%ebp)
+	movdqa	%xmm3,48(%ebp)
+	movdqa	%xmm4,-128(%ebp)
+	movdqa	%xmm5,-112(%ebp)
+	movdqa	%xmm6,-96(%ebp)
+	movdqa	%xmm7,-80(%ebp)
+	leal	128(%esi),%esi
+	leal	128(%edi),%edi
+	jmp	L009outer_loop
+.align	4,0x90
+L009outer_loop:
+	movdqa	-112(%ebp),%xmm1
+	movdqa	-96(%ebp),%xmm2
+	movdqa	-80(%ebp),%xmm3
+	movdqa	-48(%ebp),%xmm5
+	movdqa	-32(%ebp),%xmm6
+	movdqa	-16(%ebp),%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm2,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	%xmm5,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm7,-16(%ebx)
+	movdqa	32(%ebp),%xmm2
+	movdqa	48(%ebp),%xmm3
+	movdqa	64(%ebp),%xmm4
+	movdqa	80(%ebp),%xmm5
+	movdqa	96(%ebp),%xmm6
+	movdqa	112(%ebp),%xmm7
+	paddd	64(%eax),%xmm4
+	movdqa	%xmm2,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	%xmm4,64(%ebx)
+	movdqa	%xmm5,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm7,112(%ebx)
+	movdqa	%xmm4,64(%ebp)
+	movdqa	-128(%ebp),%xmm0
+	movdqa	%xmm4,%xmm6
+	movdqa	-64(%ebp),%xmm3
+	movdqa	(%ebp),%xmm4
+	movdqa	16(%ebp),%xmm5
+	movl	$10,%edx
+	nop
+.align	4,0x90
+L010loop:
+	paddd	%xmm3,%xmm0
+	movdqa	%xmm3,%xmm2
+	pxor	%xmm0,%xmm6
+	pshufb	(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-48(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	80(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,64(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-64(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	32(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-32(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	96(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,80(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,16(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-48(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	48(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-16(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	112(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,96(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-32(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	-48(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,%xmm6
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-16(%ebx)
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-32(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	64(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,112(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,32(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-48(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-16(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	80(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,64(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,48(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-32(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	16(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-64(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	96(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,80(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-16(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	64(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,96(%ebx)
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	por	%xmm1,%xmm3
+	decl	%edx
+	jnz	L010loop
+	movdqa	%xmm3,-64(%ebx)
+	movdqa	%xmm4,(%ebx)
+	movdqa	%xmm5,16(%ebx)
+	movdqa	%xmm6,64(%ebx)
+	movdqa	%xmm7,96(%ebx)
+	movdqa	-112(%ebx),%xmm1
+	movdqa	-96(%ebx),%xmm2
+	movdqa	-80(%ebx),%xmm3
+	paddd	-128(%ebp),%xmm0
+	paddd	-112(%ebp),%xmm1
+	paddd	-96(%ebp),%xmm2
+	paddd	-80(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,-128(%ebx)
+	movdqa	-64(%ebx),%xmm0
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm6,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	-48(%ebx),%xmm1
+	movdqa	-32(%ebx),%xmm2
+	movdqa	-16(%ebx),%xmm3
+	paddd	-64(%ebp),%xmm0
+	paddd	-48(%ebp),%xmm1
+	paddd	-32(%ebp),%xmm2
+	paddd	-16(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,-64(%ebx)
+	movdqa	(%ebx),%xmm0
+	movdqa	%xmm1,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm3,-16(%ebx)
+	movdqa	16(%ebx),%xmm1
+	movdqa	32(%ebx),%xmm2
+	movdqa	48(%ebx),%xmm3
+	paddd	(%ebp),%xmm0
+	paddd	16(%ebp),%xmm1
+	paddd	32(%ebp),%xmm2
+	paddd	48(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,(%ebx)
+	movdqa	64(%ebx),%xmm0
+	movdqa	%xmm1,16(%ebx)
+	movdqa	%xmm6,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	80(%ebx),%xmm1
+	movdqa	96(%ebx),%xmm2
+	movdqa	112(%ebx),%xmm3
+	paddd	64(%ebp),%xmm0
+	paddd	80(%ebp),%xmm1
+	paddd	96(%ebp),%xmm2
+	paddd	112(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqa	%xmm0,64(%ebx)
+	movdqa	%xmm1,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm3,112(%ebx)
+	movdqu	-128(%esi),%xmm0
+	movdqu	-112(%esi),%xmm1
+	movdqu	-96(%esi),%xmm2
+	movdqu	-80(%esi),%xmm3
+	pxor	-128(%ebx),%xmm0
+	pxor	-64(%ebx),%xmm1
+	pxor	(%ebx),%xmm2
+	pxor	64(%ebx),%xmm3
+	movdqu	%xmm0,-128(%edi)
+	movdqu	%xmm1,-112(%edi)
+	movdqu	%xmm2,-96(%edi)
+	movdqu	%xmm3,-80(%edi)
+	movdqu	-64(%esi),%xmm0
+	movdqu	-48(%esi),%xmm1
+	movdqu	-32(%esi),%xmm2
+	movdqu	-16(%esi),%xmm3
+	pxor	-112(%ebx),%xmm0
+	pxor	-48(%ebx),%xmm1
+	pxor	16(%ebx),%xmm2
+	pxor	80(%ebx),%xmm3
+	movdqu	%xmm0,-64(%edi)
+	movdqu	%xmm1,-48(%edi)
+	movdqu	%xmm2,-32(%edi)
+	movdqu	%xmm3,-16(%edi)
+	movdqu	(%esi),%xmm0
+	movdqu	16(%esi),%xmm1
+	movdqu	32(%esi),%xmm2
+	movdqu	48(%esi),%xmm3
+	pxor	-96(%ebx),%xmm0
+	pxor	-32(%ebx),%xmm1
+	pxor	32(%ebx),%xmm2
+	pxor	96(%ebx),%xmm3
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	movdqu	64(%esi),%xmm0
+	movdqu	80(%esi),%xmm1
+	movdqu	96(%esi),%xmm2
+	movdqu	112(%esi),%xmm3
+	pxor	-80(%ebx),%xmm0
+	pxor	-16(%ebx),%xmm1
+	pxor	48(%ebx),%xmm2
+	pxor	112(%ebx),%xmm3
+	movdqu	%xmm0,64(%edi)
+	movdqu	%xmm1,80(%edi)
+	movdqu	%xmm2,96(%edi)
+	movdqu	%xmm3,112(%edi)
+	leal	256(%esi),%esi
+	leal	256(%edi),%edi
+	subl	$256,%ecx
+	jnc	L009outer_loop
+	addl	$256,%ecx
+	jz	L011done
+	movl	520(%esp),%ebx
+	leal	-128(%esi),%esi
+	movl	516(%esp),%edx
+	leal	-128(%edi),%edi
+	movd	64(%ebp),%xmm2
+	movdqu	(%ebx),%xmm3
+	paddd	96(%eax),%xmm2
+	pand	112(%eax),%xmm3
+	por	%xmm2,%xmm3
+L0081x:
+	movdqa	32(%eax),%xmm0
+	movdqu	(%edx),%xmm1
+	movdqu	16(%edx),%xmm2
+	movdqa	(%eax),%xmm6
+	movdqa	16(%eax),%xmm7
+	movl	%ebp,48(%esp)
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	movl	$10,%edx
+	jmp	L012loop1x
+.align	4,0x90
+L013outer1x:
+	movdqa	80(%eax),%xmm3
+	movdqa	(%esp),%xmm0
+	movdqa	16(%esp),%xmm1
+	movdqa	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	movl	$10,%edx
+	movdqa	%xmm3,48(%esp)
+	jmp	L012loop1x
+.align	4,0x90
+L012loop1x:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%edx
+	jnz	L012loop1x
+	paddd	(%esp),%xmm0
+	paddd	16(%esp),%xmm1
+	paddd	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	cmpl	$64,%ecx
+	jb	L014tail
+	movdqu	(%esi),%xmm4
+	movdqu	16(%esi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%esi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%esi),%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+	leal	64(%esi),%esi
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	leal	64(%edi),%edi
+	subl	$64,%ecx
+	jnz	L013outer1x
+	jmp	L011done
+L014tail:
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+	xorl	%ebp,%ebp
+L015tail_loop:
+	movb	(%esp,%ebp,1),%al
+	movb	(%esi,%ebp,1),%dl
+	leal	1(%ebp),%ebp
+	xorb	%dl,%al
+	movb	%al,-1(%edi,%ebp,1)
+	decl	%ecx
+	jnz	L015tail_loop
+L011done:
+	movl	512(%esp),%esp
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.align	6,0x90
+Lssse3_data:
+.byte	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long	1634760805,857760878,2036477234,1797285236
+.long	0,1,2,3
+.long	4,4,4,4
+.long	1,0,0,0
+.long	4,0,0,0
+.long	0,-1,-1,-1
+.align	6,0x90
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte	114,103,62,0
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_OPENSSL_ia32cap_P$non_lazy_ptr:
+.indirect_symbol	_OPENSSL_ia32cap_P
+.long	0
+#endif
diff --git a/mac-x86/crypto/rc4/rc4-586.S b/mac-x86/crypto/rc4/rc4-586.S
index faecdfa..dcddc58 100644
--- a/mac-x86/crypto/rc4/rc4-586.S
+++ b/mac-x86/crypto/rc4/rc4-586.S
@@ -343,39 +343,6 @@
 	popl	%ebx
 	popl	%ebp
 	ret
-.globl	_RC4_options
-.private_extern	_RC4_options
-.align	4
-_RC4_options:
-L_RC4_options_begin:
-	call	L018pic_point
-L018pic_point:
-	popl	%eax
-	leal	L019opts-L018pic_point(%eax),%eax
-	call	L020PIC_me_up
-L020PIC_me_up:
-	popl	%edx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L020PIC_me_up(%edx),%edx
-	movl	(%edx),%edx
-	btl	$20,%edx
-	jc	L0211xchar
-	btl	$26,%edx
-	jnc	L022ret
-	addl	$25,%eax
-	ret
-L0211xchar:
-	addl	$12,%eax
-L022ret:
-	ret
-.align	6,0x90
-L019opts:
-.byte	114,99,52,40,52,120,44,105,110,116,41,0
-.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte	114,99,52,40,56,120,44,109,109,120,41,0
-.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align	6,0x90
 .section __IMPORT,__pointers,non_lazy_symbol_pointers
 L_OPENSSL_ia32cap_P$non_lazy_ptr:
 .indirect_symbol	_OPENSSL_ia32cap_P
diff --git a/mac-x86_64/crypto/aes/aes-x86_64.S b/mac-x86_64/crypto/aes/aes-x86_64.S
index 02f378b..b5d188a 100644
--- a/mac-x86_64/crypto/aes/aes-x86_64.S
+++ b/mac-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$65280,%edi
-	andl	$65280,%ebp
+	andl	$0x0000ff00,%edi
+	andl	$0x0000ff00,%ebp
 
 	xorl	%edi,%r10d
 	xorl	%ebp,%r11d
@@ -95,8 +95,8 @@
 	movl	0(%r14,%rsi,8),%esi
 	movl	0(%r14,%rdi,8),%edi
 
-	andl	$65280,%esi
-	andl	$65280,%edi
+	andl	$0x0000ff00,%esi
+	andl	$0x0000ff00,%edi
 	shrl	$16,%ebx
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -109,9 +109,9 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$16711680,%edi
-	andl	$16711680,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0x00ff0000,%edi
+	andl	$0x00ff0000,%ebp
 
 	xorl	%esi,%r10d
 	xorl	%edi,%r11d
@@ -124,9 +124,9 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	2(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$4278190080,%edi
-	andl	$4278190080,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0xff000000,%edi
+	andl	$0xff000000,%ebp
 
 	xorl	%esi,%r8d
 	xorl	%edi,%r10d
@@ -139,8 +139,8 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
-	andl	$4278190080,%esi
-	andl	$4278190080,%edi
+	andl	$0xff000000,%esi
+	andl	$0xff000000,%edi
 
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -242,8 +242,8 @@
 	xorl	%r8d,%edx
 	cmpq	16(%rsp),%r15
 	je	L$enc_compact_done
-	movl	$2155905152,%r10d
-	movl	$2155905152,%r11d
+	movl	$0x80808080,%r10d
+	movl	$0x80808080,%r11d
 	andl	%eax,%r10d
 	andl	%ebx,%r11d
 	movl	%r10d,%esi
@@ -254,10 +254,10 @@
 	leal	(%rbx,%rbx,1),%r9d
 	subl	%r10d,%esi
 	subl	%r11d,%edi
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%eax,%r10d
 	movl	%ebx,%r11d
 	xorl	%esi,%r8d
@@ -265,9 +265,9 @@
 
 	xorl	%r8d,%eax
 	xorl	%r9d,%ebx
-	movl	$2155905152,%r12d
+	movl	$0x80808080,%r12d
 	roll	$24,%eax
-	movl	$2155905152,%ebp
+	movl	$0x80808080,%ebp
 	roll	$24,%ebx
 	andl	%ecx,%r12d
 	andl	%edx,%ebp
@@ -290,10 +290,10 @@
 	xorl	%r10d,%eax
 	xorl	%r11d,%ebx
 
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%ecx,%r12d
 	movl	%edx,%ebp
 	xorl	%esi,%r8d
@@ -345,7 +345,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -370,7 +370,7 @@
 	leaq	L$AES_Te+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 
 	call	_x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -816,7 +816,7 @@
 	leaq	L$AES_Td+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 	shrq	$3,%rbp
 	addq	%rbp,%r14
@@ -1333,9 +1333,9 @@
 	movq	%r14,%r10
 	leaq	2304(%r14),%r11
 	movq	%r15,%r12
-	andq	$4095,%r10
-	andq	$4095,%r11
-	andq	$4095,%r12
+	andq	$0xFFF,%r10
+	andq	$0xFFF,%r11
+	andq	$0xFFF,%r12
 
 	cmpq	%r11,%r12
 	jb	L$cbc_te_break_out
@@ -1344,7 +1344,7 @@
 	jmp	L$cbc_te_ok
 L$cbc_te_break_out:
 	subq	%r10,%r12
-	andq	$4095,%r12
+	andq	$0xFFF,%r12
 	addq	$320,%r12
 	subq	%r12,%r15
 .p2align	2
@@ -1370,7 +1370,7 @@
 
 	movq	%r15,%r10
 	subq	%r14,%r10
-	andq	$4095,%r10
+	andq	$0xfff,%r10
 	cmpq	$2304,%r10
 	jb	L$cbc_do_ecopy
 	cmpq	$4096-248,%r10
@@ -1557,7 +1557,7 @@
 	leaq	-88-63(%rcx),%r10
 	subq	%rbp,%r10
 	negq	%r10
-	andq	$960,%r10
+	andq	$0x3c0,%r10
 	subq	%r10,%rbp
 
 	xchgq	%rsp,%rbp
@@ -1586,7 +1586,7 @@
 	leaq	2048(%r14),%r14
 	leaq	768-8(%rsp),%rax
 	subq	%r14,%rax
-	andq	$768,%rax
+	andq	$0x300,%rax
 	leaq	(%r14,%rax,1),%r14
 
 	cmpq	$0,%rbx
diff --git a/mac-x86_64/crypto/aes/aesni-x86_64.S b/mac-x86_64/crypto/aes/aesni-x86_64.S
index 69b22c2..3d98fa1 100644
--- a/mac-x86_64/crypto/aes/aesni-x86_64.S
+++ b/mac-x86_64/crypto/aes/aesni-x86_64.S
@@ -507,7 +507,7 @@
 	testl	%r8d,%r8d
 	jz	L$ecb_decrypt
 
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	L$ecb_enc_tail
 
 	movdqu	(%rdi),%xmm2
@@ -519,7 +519,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	L$ecb_enc_loop8_enter
 .p2align	4
 L$ecb_enc_loop8:
@@ -547,7 +547,7 @@
 
 	call	_aesni_encrypt8
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	L$ecb_enc_loop8
 
 	movups	%xmm2,(%rsi)
@@ -561,22 +561,22 @@
 	movups	%xmm8,96(%rsi)
 	movups	%xmm9,112(%rsi)
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	L$ecb_ret
 
 L$ecb_enc_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$ecb_enc_one
 	movups	16(%rdi),%xmm3
 	je	L$ecb_enc_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$ecb_enc_three
 	movups	48(%rdi),%xmm5
 	je	L$ecb_enc_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	L$ecb_enc_five
 	movups	80(%rdi),%xmm7
 	je	L$ecb_enc_six
@@ -650,7 +650,7 @@
 
 .p2align	4
 L$ecb_decrypt:
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	L$ecb_dec_tail
 
 	movdqu	(%rdi),%xmm2
@@ -662,7 +662,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	L$ecb_dec_loop8_enter
 .p2align	4
 L$ecb_dec_loop8:
@@ -691,7 +691,7 @@
 	call	_aesni_decrypt8
 
 	movups	(%r11),%xmm0
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	L$ecb_dec_loop8
 
 	movups	%xmm2,(%rsi)
@@ -713,22 +713,22 @@
 	movups	%xmm9,112(%rsi)
 	pxor	%xmm9,%xmm9
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	L$ecb_ret
 
 L$ecb_dec_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$ecb_dec_one
 	movups	16(%rdi),%xmm3
 	je	L$ecb_dec_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$ecb_dec_three
 	movups	48(%rdi),%xmm5
 	je	L$ecb_dec_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	L$ecb_dec_five
 	movups	80(%rdi),%xmm7
 	je	L$ecb_dec_six
@@ -1606,7 +1606,7 @@
 
 	movdqa	L$xts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -1705,7 +1705,7 @@
 .byte	102,15,56,220,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	L$xts_enc_loop6
 .p2align	5
 L$xts_enc_loop6:
@@ -1844,13 +1844,13 @@
 	jz	L$xts_enc_done
 
 	pxor	%xmm0,%xmm11
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$xts_enc_one
 	pxor	%xmm0,%xmm12
 	je	L$xts_enc_two
 
 	pxor	%xmm0,%xmm13
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$xts_enc_three
 	pxor	%xmm0,%xmm14
 	je	L$xts_enc_four
@@ -2078,7 +2078,7 @@
 
 	movdqa	L$xts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -2177,7 +2177,7 @@
 .byte	102,15,56,222,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	L$xts_dec_loop6
 .p2align	5
 L$xts_dec_loop6:
@@ -2317,13 +2317,13 @@
 	jz	L$xts_dec_done
 
 	pxor	%xmm0,%xmm12
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$xts_dec_one
 	pxor	%xmm0,%xmm13
 	je	L$xts_dec_two
 
 	pxor	%xmm0,%xmm14
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$xts_dec_three
 	je	L$xts_dec_four
 
@@ -2354,7 +2354,7 @@
 	pcmpgtd	%xmm15,%xmm14
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	pshufd	$19,%xmm14,%xmm11
+	pshufd	$0x13,%xmm14,%xmm11
 	andq	$15,%r9
 	jz	L$xts_dec_ret
 
@@ -2644,7 +2644,7 @@
 	leaq	-8(%rax),%rbp
 	movups	(%r8),%xmm10
 	movl	%r10d,%eax
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	L$cbc_dec_tail
 
 	movups	(%rcx),%xmm0
@@ -2660,14 +2660,14 @@
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
 	movl	_OPENSSL_ia32cap_P+4(%rip),%r9d
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	jbe	L$cbc_dec_six_or_seven
 
 	andl	$71303168,%r9d
-	subq	$80,%rdx
+	subq	$0x50,%rdx
 	cmpl	$4194304,%r9d
 	je	L$cbc_dec_loop6_enter
-	subq	$32,%rdx
+	subq	$0x20,%rdx
 	leaq	112(%rcx),%rcx
 	jmp	L$cbc_dec_loop8_enter
 .p2align	4
@@ -2682,7 +2682,7 @@
 	movups	16-112(%rcx),%xmm1
 	pxor	%xmm0,%xmm4
 	xorq	%r11,%r11
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	pxor	%xmm0,%xmm5
 	pxor	%xmm0,%xmm6
 	pxor	%xmm0,%xmm7
@@ -2867,21 +2867,21 @@
 	movups	%xmm8,96(%rsi)
 	leaq	112(%rsi),%rsi
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	ja	L$cbc_dec_loop8
 
 	movaps	%xmm9,%xmm2
 	leaq	-112(%rcx),%rcx
-	addq	$112,%rdx
+	addq	$0x70,%rdx
 	jle	L$cbc_dec_clear_tail_collected
 	movups	%xmm9,(%rsi)
 	leaq	16(%rsi),%rsi
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	L$cbc_dec_tail
 
 	movaps	%xmm11,%xmm2
 L$cbc_dec_six_or_seven:
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	ja	L$cbc_dec_seven
 
 	movaps	%xmm7,%xmm8
@@ -2974,33 +2974,33 @@
 	movl	%r10d,%eax
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	subq	$96,%rdx
+	subq	$0x60,%rdx
 	ja	L$cbc_dec_loop6
 
 	movdqa	%xmm7,%xmm2
-	addq	$80,%rdx
+	addq	$0x50,%rdx
 	jle	L$cbc_dec_clear_tail_collected
 	movups	%xmm7,(%rsi)
 	leaq	16(%rsi),%rsi
 
 L$cbc_dec_tail:
 	movups	(%rdi),%xmm2
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_one
 
 	movups	16(%rdi),%xmm3
 	movaps	%xmm2,%xmm11
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_two
 
 	movups	32(%rdi),%xmm4
 	movaps	%xmm3,%xmm12
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_three
 
 	movups	48(%rdi),%xmm5
 	movaps	%xmm4,%xmm13
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_four
 
 	movups	64(%rdi),%xmm6
@@ -3025,7 +3025,7 @@
 	movdqa	%xmm6,%xmm2
 	pxor	%xmm6,%xmm6
 	pxor	%xmm7,%xmm7
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jmp	L$cbc_dec_tail_collected
 
 .p2align	4
@@ -3344,7 +3344,7 @@
 	pslldq	$4,%xmm0
 	pxor	%xmm3,%xmm0
 
-	pshufd	$255,%xmm0,%xmm3
+	pshufd	$0xff,%xmm0,%xmm3
 	pxor	%xmm1,%xmm3
 	pslldq	$4,%xmm1
 	pxor	%xmm1,%xmm3
@@ -3431,7 +3431,7 @@
 	decl	%r10d
 	jz	L$done_key256
 
-	pshufd	$255,%xmm0,%xmm2
+	pshufd	$0xff,%xmm0,%xmm2
 	pxor	%xmm3,%xmm3
 .byte	102,15,56,221,211
 
diff --git a/mac-x86_64/crypto/aes/bsaes-x86_64.S b/mac-x86_64/crypto/aes/bsaes-x86_64.S
index c2d0477..ad802e3 100644
--- a/mac-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/mac-x86_64/crypto/aes/bsaes-x86_64.S
@@ -325,45 +325,45 @@
 	pxor	%xmm2,%xmm5
 	decl	%r10d
 	jl	L$enc_done
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm3,%xmm9
+	pshufd	$0x93,%xmm3,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm5,%xmm10
+	pshufd	$0x93,%xmm5,%xmm10
 	pxor	%xmm9,%xmm3
-	pshufd	$147,%xmm2,%xmm11
+	pshufd	$0x93,%xmm2,%xmm11
 	pxor	%xmm10,%xmm5
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm2
-	pshufd	$147,%xmm1,%xmm13
+	pshufd	$0x93,%xmm1,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm1
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm2,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm5,%xmm11
-	pshufd	$78,%xmm2,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm7
 	pxor	%xmm1,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm3,%xmm10
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm1,%xmm5
+	pshufd	$0x4E,%xmm1,%xmm5
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm12,%xmm8
 	pxor	%xmm10,%xmm2
 	pxor	%xmm14,%xmm6
@@ -797,24 +797,24 @@
 	decl	%r10d
 	jl	L$dec_done
 
-	pshufd	$78,%xmm15,%xmm7
-	pshufd	$78,%xmm2,%xmm13
+	pshufd	$0x4E,%xmm15,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm13
 	pxor	%xmm15,%xmm7
-	pshufd	$78,%xmm4,%xmm14
+	pshufd	$0x4E,%xmm4,%xmm14
 	pxor	%xmm2,%xmm13
-	pshufd	$78,%xmm0,%xmm8
+	pshufd	$0x4E,%xmm0,%xmm8
 	pxor	%xmm4,%xmm14
-	pshufd	$78,%xmm5,%xmm9
+	pshufd	$0x4E,%xmm5,%xmm9
 	pxor	%xmm0,%xmm8
-	pshufd	$78,%xmm3,%xmm10
+	pshufd	$0x4E,%xmm3,%xmm10
 	pxor	%xmm5,%xmm9
 	pxor	%xmm13,%xmm15
 	pxor	%xmm13,%xmm0
-	pshufd	$78,%xmm1,%xmm11
+	pshufd	$0x4E,%xmm1,%xmm11
 	pxor	%xmm3,%xmm10
 	pxor	%xmm7,%xmm5
 	pxor	%xmm8,%xmm3
-	pshufd	$78,%xmm6,%xmm12
+	pshufd	$0x4E,%xmm6,%xmm12
 	pxor	%xmm1,%xmm11
 	pxor	%xmm14,%xmm0
 	pxor	%xmm9,%xmm1
@@ -828,45 +828,45 @@
 	pxor	%xmm14,%xmm1
 	pxor	%xmm14,%xmm6
 	pxor	%xmm12,%xmm4
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm5,%xmm9
+	pshufd	$0x93,%xmm5,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm3,%xmm10
+	pshufd	$0x93,%xmm3,%xmm10
 	pxor	%xmm9,%xmm5
-	pshufd	$147,%xmm1,%xmm11
+	pshufd	$0x93,%xmm1,%xmm11
 	pxor	%xmm10,%xmm3
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm1
-	pshufd	$147,%xmm2,%xmm13
+	pshufd	$0x93,%xmm2,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm2
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm1,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm3,%xmm11
-	pshufd	$78,%xmm1,%xmm7
+	pshufd	$0x4E,%xmm1,%xmm7
 	pxor	%xmm2,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm5,%xmm10
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm2,%xmm3
+	pshufd	$0x4E,%xmm2,%xmm3
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm12,%xmm8
 	pxor	%xmm1,%xmm10
 	pxor	%xmm14,%xmm6
@@ -1556,20 +1556,20 @@
 	movdqa	%xmm7,(%rax)
 
 	andq	$-16,%r14
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	L$xts_enc_short
 	jmp	L$xts_enc_loop
 
 .p2align	4
 L$xts_enc_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1577,7 +1577,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1586,7 +1586,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1596,7 +1596,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1606,7 +1606,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1616,7 +1616,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1626,7 +1626,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -1670,20 +1670,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	L$xts_enc_loop
 
 L$xts_enc_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	L$xts_enc_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1691,7 +1691,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1702,7 +1702,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	L$xts_enc_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1714,7 +1714,7 @@
 	cmpq	$32,%r14
 	je	L$xts_enc_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1726,7 +1726,7 @@
 	cmpq	$48,%r14
 	je	L$xts_enc_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1738,7 +1738,7 @@
 	cmpq	$64,%r14
 	je	L$xts_enc_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1750,7 +1750,7 @@
 	cmpq	$80,%r14
 	je	L$xts_enc_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2016,20 +2016,20 @@
 	shlq	$4,%rax
 	subq	%rax,%r14
 
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	L$xts_dec_short
 	jmp	L$xts_dec_loop
 
 .p2align	4
 L$xts_dec_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2037,7 +2037,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2046,7 +2046,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2056,7 +2056,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2066,7 +2066,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2076,7 +2076,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2086,7 +2086,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2130,20 +2130,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	L$xts_dec_loop
 
 L$xts_dec_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	L$xts_dec_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2151,7 +2151,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2162,7 +2162,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	L$xts_dec_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2174,7 +2174,7 @@
 	cmpq	$32,%r14
 	je	L$xts_dec_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2186,7 +2186,7 @@
 	cmpq	$48,%r14
 	je	L$xts_dec_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2198,7 +2198,7 @@
 	cmpq	$64,%r14
 	je	L$xts_dec_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2210,7 +2210,7 @@
 	cmpq	$80,%r14
 	je	L$xts_dec_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2387,7 +2387,7 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	movdqa	%xmm6,%xmm5
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
diff --git a/mac-x86_64/crypto/aes/vpaes-x86_64.S b/mac-x86_64/crypto/aes/vpaes-x86_64.S
index 711ea43..997cde8 100644
--- a/mac-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/mac-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@
 	addq	$16,%r11
 	pxor	%xmm0,%xmm3
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	subq	$1,%rax
 	pxor	%xmm3,%xmm0
 
@@ -121,10 +121,10 @@
 	pand	%xmm9,%xmm0
 .byte	102,15,56,0,208
 	movdqa	L$k_dipt+16(%rip),%xmm0
-	xorq	$48,%r11
+	xorq	$0x30,%r11
 	leaq	L$k_dsbd(%rip),%r10
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	pxor	%xmm5,%xmm2
 	movdqa	L$k_mc_forward+48(%rip),%xmm5
 	pxor	%xmm2,%xmm0
@@ -243,7 +243,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	movdqu	%xmm3,(%rdx)
-	xorq	$48,%r8
+	xorq	$0x30,%r8
 
 L$schedule_go:
 	cmpl	$192,%esi
@@ -333,7 +333,7 @@
 	call	_vpaes_schedule_mangle
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 	movdqa	%xmm7,%xmm5
 	movdqa	%xmm6,%xmm7
 	call	_vpaes_schedule_low_round
@@ -400,8 +400,8 @@
 
 .p2align	4
 _vpaes_schedule_192_smear:
-	pshufd	$128,%xmm6,%xmm1
-	pshufd	$254,%xmm7,%xmm0
+	pshufd	$0x80,%xmm6,%xmm1
+	pshufd	$0xFE,%xmm7,%xmm0
 	pxor	%xmm1,%xmm6
 	pxor	%xmm1,%xmm1
 	pxor	%xmm0,%xmm6
@@ -438,7 +438,7 @@
 	pxor	%xmm1,%xmm7
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 .byte	102,15,58,15,192,1
 
 
@@ -597,7 +597,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	addq	$-16,%r8
-	andq	$48,%r8
+	andq	$0x30,%r8
 	movdqu	%xmm3,(%rdx)
 	.byte	0xf3,0xc3
 
@@ -616,7 +616,7 @@
 	movl	%eax,240(%rdx)
 
 	movl	$0,%ecx
-	movl	$48,%r8d
+	movl	$0x30,%r8d
 	call	_vpaes_schedule_core
 	xorl	%eax,%eax
 	.byte	0xf3,0xc3
diff --git a/mac-x86_64/crypto/bn/rsaz-x86_64.S b/mac-x86_64/crypto/bn/rsaz-x86_64.S
index 5e9e82f..337276f 100644
--- a/mac-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/mac-x86_64/crypto/bn/rsaz-x86_64.S
@@ -465,48 +465,94 @@
 	pushq	%r14
 	pushq	%r15
 
-	movl	%r9d,%r9d
-	subq	$128+24,%rsp
+	subq	$152,%rsp
 L$mul_gather4_body:
-	movl	64(%rdx,%r9,4),%eax
-.byte	102,72,15,110,199
-	movl	(%rdx,%r9,4),%ebx
-.byte	102,72,15,110,201
-	movq	%r8,128(%rsp)
+	movd	%r9d,%xmm8
+	movdqa	L$inc+16(%rip),%xmm1
+	movdqa	L$inc(%rip),%xmm0
 
-	shlq	$32,%rax
-	orq	%rax,%rbx
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
+
+	movdqa	0(%rdx),%xmm8
+	movdqa	16(%rdx),%xmm9
+	movdqa	32(%rdx),%xmm10
+	movdqa	48(%rdx),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rdx),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rdx),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rdx),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rdx),%xmm15
+	leaq	128(%rdx),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
+	movq	%r8,128(%rsp)
+	movq	%rdi,128+8(%rsp)
+	movq	%rcx,128+16(%rsp)
+
 	movq	(%rsi),%rax
 	movq	8(%rsi),%rcx
-	leaq	128(%rdx,%r9,4),%rbp
 	mulq	%rbx
 	movq	%rax,(%rsp)
 	movq	%rcx,%rax
 	movq	%rdx,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r8
 	movq	16(%rsi),%rax
 	movq	%rdx,%r9
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r9
 	movq	24(%rsi),%rax
 	movq	%rdx,%r10
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r10
 	movq	32(%rsi),%rax
 	movq	%rdx,%r11
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r11
 	movq	40(%rsi),%rax
 	movq	%rdx,%r12
@@ -519,14 +565,12 @@
 	adcq	$0,%r13
 
 	mulq	%rbx
-	leaq	128(%rbp),%rbp
 	addq	%rax,%r13
 	movq	56(%rsi),%rax
 	movq	%rdx,%r14
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r14
 	movq	(%rsi),%rax
 	movq	%rdx,%r15
@@ -538,6 +582,35 @@
 
 .p2align	5
 L$oop_mul_gather:
+	movdqa	0(%rbp),%xmm8
+	movdqa	16(%rbp),%xmm9
+	movdqa	32(%rbp),%xmm10
+	movdqa	48(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rbp),%xmm15
+	leaq	128(%rbp),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
 	mulq	%rbx
 	addq	%rax,%r8
 	movq	8(%rsi),%rax
@@ -546,7 +619,6 @@
 	adcq	$0,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r9
 	movq	16(%rsi),%rax
 	adcq	$0,%rdx
@@ -555,7 +627,6 @@
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r10
 	movq	24(%rsi),%rax
 	adcq	$0,%rdx
@@ -564,7 +635,6 @@
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r11
 	movq	32(%rsi),%rax
 	adcq	$0,%rdx
@@ -573,7 +643,6 @@
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r12
 	movq	40(%rsi),%rax
 	adcq	$0,%rdx
@@ -598,7 +667,6 @@
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r15
 	movq	(%rsi),%rax
 	adcq	$0,%rdx
@@ -606,7 +674,6 @@
 	movq	%rdx,%r15
 	adcq	$0,%r15
 
-	leaq	128(%rbp),%rbp
 	leaq	8(%rdi),%rdi
 
 	decl	%ecx
@@ -621,8 +688,8 @@
 	movq	%r14,48(%rdi)
 	movq	%r15,56(%rdi)
 
-.byte	102,72,15,126,199
-.byte	102,72,15,126,205
+	movq	128+8(%rsp),%rdi
+	movq	128+16(%rsp),%rbp
 
 	movq	(%rsp),%r8
 	movq	8(%rsp),%r9
@@ -672,7 +739,7 @@
 	movl	%r9d,%r9d
 	subq	$128+24,%rsp
 L$mul_scatter4_body:
-	leaq	(%r8,%r9,4),%r8
+	leaq	(%r8,%r9,8),%r8
 .byte	102,72,15,110,199
 .byte	102,72,15,110,202
 .byte	102,73,15,110,208
@@ -708,30 +775,14 @@
 
 	call	__rsaz_512_subtract
 
-	movl	%r8d,0(%rsi)
-	shrq	$32,%r8
-	movl	%r9d,128(%rsi)
-	shrq	$32,%r9
-	movl	%r10d,256(%rsi)
-	shrq	$32,%r10
-	movl	%r11d,384(%rsi)
-	shrq	$32,%r11
-	movl	%r12d,512(%rsi)
-	shrq	$32,%r12
-	movl	%r13d,640(%rsi)
-	shrq	$32,%r13
-	movl	%r14d,768(%rsi)
-	shrq	$32,%r14
-	movl	%r15d,896(%rsi)
-	shrq	$32,%r15
-	movl	%r8d,64(%rsi)
-	movl	%r9d,192(%rsi)
-	movl	%r10d,320(%rsi)
-	movl	%r11d,448(%rsi)
-	movl	%r12d,576(%rsi)
-	movl	%r13d,704(%rsi)
-	movl	%r14d,832(%rsi)
-	movl	%r15d,960(%rsi)
+	movq	%r8,0(%rsi)
+	movq	%r9,128(%rsi)
+	movq	%r10,256(%rsi)
+	movq	%r11,384(%rsi)
+	movq	%r12,512(%rsi)
+	movq	%r13,640(%rsi)
+	movq	%r14,768(%rsi)
+	movq	%r15,896(%rsi)
 
 	leaq	128+24+48(%rsp),%rax
 	movq	-48(%rax),%r15
@@ -1086,16 +1137,14 @@
 
 .p2align	4
 _rsaz_512_scatter4:
-	leaq	(%rdi,%rdx,4),%rdi
+	leaq	(%rdi,%rdx,8),%rdi
 	movl	$8,%r9d
 	jmp	L$oop_scatter
 .p2align	4
 L$oop_scatter:
 	movq	(%rsi),%rax
 	leaq	8(%rsi),%rsi
-	movl	%eax,(%rdi)
-	shrq	$32,%rax
-	movl	%eax,64(%rdi)
+	movq	%rax,(%rdi)
 	leaq	128(%rdi),%rdi
 	decl	%r9d
 	jnz	L$oop_scatter
@@ -1107,20 +1156,73 @@
 
 .p2align	4
 _rsaz_512_gather4:
-	leaq	(%rsi,%rdx,4),%rsi
+	movd	%edx,%xmm8
+	movdqa	L$inc+16(%rip),%xmm1
+	movdqa	L$inc(%rip),%xmm0
+
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
 	movl	$8,%r9d
 	jmp	L$oop_gather
 .p2align	4
 L$oop_gather:
-	movl	(%rsi),%eax
-	movl	64(%rsi),%r8d
+	movdqa	0(%rsi),%xmm8
+	movdqa	16(%rsi),%xmm9
+	movdqa	32(%rsi),%xmm10
+	movdqa	48(%rsi),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rsi),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rsi),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rsi),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rsi),%xmm15
 	leaq	128(%rsi),%rsi
-	shlq	$32,%r8
-	orq	%r8,%rax
-	movq	%rax,(%rdi)
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,(%rdi)
 	leaq	8(%rdi),%rdi
 	decl	%r9d
 	jnz	L$oop_gather
 	.byte	0xf3,0xc3
+L$SEH_end_rsaz_512_gather4:
 
+
+.p2align	6
+L$inc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 #endif
diff --git a/mac-x86_64/crypto/bn/x86_64-mont.S b/mac-x86_64/crypto/bn/x86_64-mont.S
index 6b9bc05..51e5d19 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont.S
@@ -634,20 +634,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,4),%r11
+	leaq	-64(%rsp,%r9,2),%r11
 	movq	(%r8),%r8
 	subq	%rsi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$sqr8x_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	-64(%rsp,%r9,2),%rsp
 	jmp	L$sqr8x_sp_done
 
 .p2align	5
 L$sqr8x_sp_alt:
-	leaq	4096-64(,%r9,4),%r10
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	4096-64(,%r9,2),%r10
+	leaq	-64(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -657,58 +657,80 @@
 	movq	%r9,%r10
 	negq	%r9
 
-	leaq	64(%rsp,%r9,2),%r11
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 L$sqr8x_body:
 
-	movq	%r9,%rbp
-.byte	102,73,15,110,211
-	shrq	$3+2,%rbp
-	movl	_OPENSSL_ia32cap_P+8(%rip),%eax
-	jmp	L$sqr8x_copy_n
-
-.p2align	5
-L$sqr8x_copy_n:
-	movq	0(%rcx),%xmm0
-	movq	8(%rcx),%xmm1
-	movq	16(%rcx),%xmm3
-	movq	24(%rcx),%xmm4
-	leaq	32(%rcx),%rcx
-	movdqa	%xmm0,0(%r11)
-	movdqa	%xmm1,16(%r11)
-	movdqa	%xmm3,32(%r11)
-	movdqa	%xmm4,48(%r11)
-	leaq	64(%r11),%r11
-	decq	%rbp
-	jnz	L$sqr8x_copy_n
-
+.byte	102,72,15,110,209
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,73,15,110,218
 	call	_bn_sqr8x_internal
 
-	pxor	%xmm0,%xmm0
-	leaq	48(%rsp),%rax
-	leaq	64(%rsp,%r9,2),%rdx
-	shrq	$3+2,%r9
-	movq	40(%rsp),%rsi
-	jmp	L$sqr8x_zero
+
+
+
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+	movq	%r9,%rdx
+.byte	102,72,15,126,207
+	sarq	$3+2,%rcx
+	jmp	L$sqr8x_sub
 
 .p2align	5
-L$sqr8x_zero:
-	movdqa	%xmm0,0(%rax)
-	movdqa	%xmm0,16(%rax)
-	movdqa	%xmm0,32(%rax)
-	movdqa	%xmm0,48(%rax)
-	leaq	64(%rax),%rax
-	movdqa	%xmm0,0(%rdx)
-	movdqa	%xmm0,16(%rdx)
-	movdqa	%xmm0,32(%rdx)
-	movdqa	%xmm0,48(%rdx)
-	leaq	64(%rdx),%rdx
-	decq	%r9
-	jnz	L$sqr8x_zero
+L$sqr8x_sub:
+	movq	0(%rbx),%r12
+	movq	8(%rbx),%r13
+	movq	16(%rbx),%r14
+	movq	24(%rbx),%r15
+	leaq	32(%rbx),%rbx
+	sbbq	0(%rbp),%r12
+	sbbq	8(%rbp),%r13
+	sbbq	16(%rbp),%r14
+	sbbq	24(%rbp),%r15
+	leaq	32(%rbp),%rbp
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	leaq	32(%rdi),%rdi
+	incq	%rcx
+	jnz	L$sqr8x_sub
+
+	sbbq	$0,%rax
+	leaq	(%rbx,%r9,1),%rbx
+	leaq	(%rdi,%r9,1),%rdi
+
+.byte	102,72,15,110,200
+	pxor	%xmm0,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	40(%rsp),%rsi
+	jmp	L$sqr8x_cond_copy
+
+.p2align	5
+L$sqr8x_cond_copy:
+	movdqa	0(%rbx),%xmm2
+	movdqa	16(%rbx),%xmm3
+	leaq	32(%rbx),%rbx
+	movdqu	0(%rdi),%xmm4
+	movdqu	16(%rdi),%xmm5
+	leaq	32(%rdi),%rdi
+	movdqa	%xmm0,-32(%rbx)
+	movdqa	%xmm0,-16(%rbx)
+	movdqa	%xmm0,-32(%rbx,%rdx,1)
+	movdqa	%xmm0,-16(%rbx,%rdx,1)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-32(%rdi)
+	movdqu	%xmm5,-16(%rdi)
+	addq	$32,%r9
+	jnz	L$sqr8x_cond_copy
 
 	movq	$1,%rax
 	movq	-48(%rsi),%r15
diff --git a/mac-x86_64/crypto/bn/x86_64-mont5.S b/mac-x86_64/crypto/bn/x86_64-mont5.S
index 461bfb2..f3ad8d7 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -16,46 +16,151 @@
 L$mul_enter:
 	movl	%r9d,%r9d
 	movq	%rsp,%rax
-	movl	8(%rsp),%r10d
+	movd	8(%rsp),%xmm5
+	leaq	L$inc(%rip),%r10
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 	leaq	2(%r9),%r11
 	negq	%r11
-	leaq	(%rsp,%r11,8),%rsp
+	leaq	-264(%rsp,%r11,8),%rsp
 	andq	$-1024,%rsp
 
 	movq	%rax,8(%rsp,%r9,8)
 L$mul_body:
-	movq	%rdx,%r12
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	L$magic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%r12,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
+	leaq	128(%rdx),%r12
+	movdqa	0(%r10),%xmm0
+	movdqa	16(%r10),%xmm1
+	leaq	24-112(%rsp,%r9,8),%r10
+	andq	$-16,%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+.byte	0x67
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
+.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
 	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 .byte	102,72,15,126,195
 
 	movq	(%r8),%r8
@@ -64,29 +169,14 @@
 	xorq	%r14,%r14
 	xorq	%r15,%r15
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	movq	%r8,%rbp
 	mulq	%rbx
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -119,14 +209,12 @@
 	cmpq	%r9,%r15
 	jne	L$1st
 
-.byte	102,72,15,126,195
 
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r13
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 	movq	%r10,%r11
 
@@ -140,33 +228,78 @@
 	jmp	L$outer
 .p2align	4
 L$outer:
+	leaq	24+128(%rsp,%r9,8),%rdx
+	andq	$-16,%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+
+	movq	(%rsi),%rax
+.byte	102,72,15,126,195
+
 	xorq	%r15,%r15
 	movq	%r8,%rbp
 	movq	(%rsp),%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	mulq	%rbx
 	addq	%rax,%r10
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -202,15 +335,12 @@
 	cmpq	%r9,%r15
 	jne	L$inner
 
-.byte	102,72,15,126,195
-
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r13
-	movq	(%rsp,%r15,8),%r10
+	movq	(%rsp,%r9,8),%r10
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 
 	xorq	%rdx,%rdx
@@ -256,6 +386,7 @@
 
 	movq	8(%rsp,%r9,8),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -278,10 +409,10 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 .byte	0x67
-	movl	%r9d,%r10d
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
 
@@ -291,19 +422,21 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$mul4xsp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$mul4xsp_done
 
 .p2align	5
 L$mul4xsp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -319,6 +452,7 @@
 
 	movq	40(%rsp),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -334,47 +468,141 @@
 .p2align	5
 mul4x_internal:
 	shlq	$5,%r9
-	movl	8(%rax),%r10d
-	leaq	256(%rdx,%r9,1),%r13
+	movd	8(%rax),%xmm5
+	leaq	L$inc(%rip),%rax
+	leaq	128(%rdx,%r9,1),%r13
 	shrq	$5,%r9
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	L$magic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%rdx,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	addq	$7,%r11
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
-	andq	$7,%r11
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	88-112(%rsp,%r9,1),%r10
+	leaq	128(%rdx),%r12
 
-	movq	-96(%r12),%xmm0
-	leaq	256(%r12),%r14
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+.byte	0x67,0x67
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
 .byte	0x67
-	por	%xmm1,%xmm0
-	movq	-96(%r14),%xmm1
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
 .byte	0x67
-	pand	%xmm7,%xmm3
-.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
-	movq	-32(%r14),%xmm2
-.byte	0x67
-	pand	%xmm4,%xmm1
-.byte	0x67
-	por	%xmm3,%xmm0
-	movq	32(%r14),%xmm3
-
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	leaq	256(%r12),%r12
 .byte	102,72,15,126,195
-	movq	96(%r14),%xmm0
+
 	movq	%r13,16+8(%rsp)
 	movq	%rdi,56+8(%rsp)
 
@@ -388,26 +616,10 @@
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	pand	%xmm5,%xmm2
-	pand	%xmm6,%xmm3
-	por	%xmm2,%xmm1
-
 	imulq	%r10,%rbp
-
-
-
-
-
-
-
-	leaq	64+8(%rsp,%r11,8),%r14
+	leaq	64+8(%rsp),%r14
 	movq	%rdx,%r11
 
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
-	leaq	512(%r12),%r12
-	por	%xmm1,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi,%r9,1),%rax
@@ -416,7 +628,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -426,7 +638,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -436,7 +648,7 @@
 L$1st4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -452,7 +664,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -482,7 +694,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -491,7 +703,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -501,7 +713,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -517,7 +729,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -530,8 +742,7 @@
 	movq	%rdi,-16(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -542,6 +753,63 @@
 
 .p2align	5
 L$outer4x:
+	leaq	16+128(%r14),%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+.byte	102,72,15,126,195
+
 	movq	(%r14,%r9,1),%r10
 	movq	%r8,%rbp
 	mulq	%rbx
@@ -549,25 +817,11 @@
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-
 	imulq	%r10,%rbp
-.byte	0x67
 	movq	%rdx,%r11
 	movq	%rdi,(%r14)
 
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	por	%xmm2,%xmm0
 	leaq	(%r14,%r9,1),%r14
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
 
 	mulq	%rbp
 	addq	%rax,%r10
@@ -577,7 +831,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -589,7 +843,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdx,%r13
 	jmp	L$inner4x
@@ -598,7 +852,7 @@
 L$inner4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -616,7 +870,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -650,7 +904,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -661,7 +915,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%r13,-8(%r14)
 	movq	%rdx,%r13
@@ -671,7 +925,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -690,7 +944,7 @@
 	mulq	%rbx
 	addq	%rax,%r11
 	movq	%rbp,%rax
-	movq	-16(%rcx),%rbp
+	movq	-8(%rcx),%rbp
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -705,9 +959,8 @@
 	movq	%r13,-24(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
 	movq	%rdi,-16(%r14)
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -718,16 +971,23 @@
 
 	cmpq	16+8(%rsp),%r12
 	jb	L$outer4x
+	xorq	%rax,%rax
 	subq	%r13,%rbp
 	adcq	%r15,%r15
 	orq	%r15,%rdi
-	xorq	$1,%rdi
+	subq	%rdi,%rax
 	leaq	(%r14,%r9,1),%rbx
-	leaq	(%rcx,%rdi,8),%rbp
+	movq	(%rcx),%r12
+	leaq	(%rcx),%rbp
 	movq	%r9,%rcx
 	sarq	$3+2,%rcx
 	movq	56+8(%rsp),%rdi
-	jmp	L$sqr4x_sub
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	L$sqr4x_sub_entry
 
 .globl	_bn_power5
 .private_extern _bn_power5
@@ -741,9 +1001,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leal	(%r9,%r9,2),%r10d
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -753,19 +1013,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$pwr_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$pwr_sp_done
 
 .p2align	5
 L$pwr_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -793,10 +1054,15 @@
 .byte	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 .byte	102,72,15,126,209
 .byte	102,72,15,126,226
@@ -1341,9 +1607,9 @@
 	movq	%rbx,-16(%rdi)
 	movq	%r8,-8(%rdi)
 .byte	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xorq	%rax,%rax
-	leaq	(%rbp,%r9,2),%rcx
+	leaq	(%r9,%rbp,1),%rcx
 	leaq	48+8(%rsp,%r9,2),%rdx
 	movq	%rcx,0+8(%rsp)
 	leaq	48+8(%rsp,%r9,1),%rdi
@@ -1376,14 +1642,14 @@
 .p2align	5
 L$8x_reduce:
 	mulq	%rbx
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	negq	%r8
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	movq	%rbx,48-8+8(%rsp,%rcx,8)
@@ -1392,7 +1658,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	32+8(%rsp),%rsi
@@ -1401,7 +1667,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	imulq	%r8,%rsi
 	addq	%r11,%r10
@@ -1410,7 +1676,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1418,7 +1684,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1426,7 +1692,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1444,7 +1710,7 @@
 	decl	%ecx
 	jnz	L$8x_reduce
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	xorq	%rax,%rax
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
@@ -1470,14 +1736,14 @@
 L$8x_tail:
 	mulq	%rbx
 	addq	%rax,%r8
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	movq	%r8,(%rdi)
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	leaq	8(%rdi),%rdi
@@ -1486,7 +1752,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	%rdx,%r10
@@ -1494,7 +1760,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r10
 	movq	%rdx,%r11
@@ -1502,7 +1768,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1510,7 +1776,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1518,7 +1784,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1536,7 +1802,7 @@
 	decl	%ecx
 	jnz	L$8x_tail
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
 	jae	L$8x_tail_done
@@ -1582,7 +1848,7 @@
 	adcq	48(%rdi),%r14
 	adcq	56(%rdi),%r15
 	adcq	$0,%rax
-	movq	-16(%rbp),%rcx
+	movq	-8(%rbp),%rcx
 	xorq	%rsi,%rsi
 
 .byte	102,72,15,126,213
@@ -1600,40 +1866,58 @@
 
 	cmpq	%rdx,%rdi
 	jb	L$8x_reduction_loop
+	.byte	0xf3,0xc3
 
-	subq	%r15,%rcx
-	leaq	(%rdi,%r9,1),%rbx
-	adcq	%rsi,%rsi
-	movq	%r9,%rcx
-	orq	%rsi,%rax
-.byte	102,72,15,126,207
-	xorq	$1,%rax
-.byte	102,72,15,126,206
-	leaq	(%rbp,%rax,8),%rbp
-	sarq	$3+2,%rcx
-	jmp	L$sqr4x_sub
 
 .p2align	5
+__bn_post4x_internal:
+	movq	0(%rbp),%r12
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+.byte	102,72,15,126,207
+	negq	%rax
+.byte	102,72,15,126,206
+	sarq	$3+2,%rcx
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	L$sqr4x_sub_entry
+
+.p2align	4
 L$sqr4x_sub:
-.byte	0x66
-	movq	0(%rbx),%r12
-	movq	8(%rbx),%r13
-	sbbq	0(%rbp),%r12
-	movq	16(%rbx),%r14
-	sbbq	16(%rbp),%r13
-	movq	24(%rbx),%r15
-	leaq	32(%rbx),%rbx
-	sbbq	32(%rbp),%r14
+	movq	0(%rbp),%r12
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+L$sqr4x_sub_entry:
+	leaq	32(%rbp),%rbp
+	notq	%r12
+	notq	%r13
+	notq	%r14
+	notq	%r15
+	andq	%rax,%r12
+	andq	%rax,%r13
+	andq	%rax,%r14
+	andq	%rax,%r15
+
+	negq	%r10
+	adcq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	adcq	16(%rbx),%r14
+	adcq	24(%rbx),%r15
 	movq	%r12,0(%rdi)
-	sbbq	48(%rbp),%r15
-	leaq	64(%rbp),%rbp
+	leaq	32(%rbx),%rbx
 	movq	%r13,8(%rdi)
+	sbbq	%r10,%r10
 	movq	%r14,16(%rdi)
 	movq	%r15,24(%rdi)
 	leaq	32(%rdi),%rdi
 
 	incq	%rcx
 	jnz	L$sqr4x_sub
+
 	movq	%r9,%r10
 	negq	%r9
 	.byte	0xf3,0xc3
@@ -1660,10 +1944,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-.byte	0x67
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -1673,19 +1956,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$from_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$from_sp_done
 
 .p2align	5
 L$from_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -1736,7 +2020,8 @@
 .byte	0x67
 	movq	%rcx,%rbp
 .byte	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	%xmm0,%xmm0
 	leaq	48(%rsp),%rax
@@ -1786,46 +2071,170 @@
 .globl	_bn_gather5
 .private_extern _bn_gather5
 
-.p2align	4
+.p2align	5
 _bn_gather5:
-	movl	%ecx,%r11d
-	shrl	$3,%ecx
-	andq	$7,%r11
-	notl	%ecx
-	leaq	L$magic_masks(%rip),%rax
-	andl	$3,%ecx
-	leaq	128(%rdx,%r11,8),%rdx
-	movq	0(%rax,%rcx,8),%xmm4
-	movq	8(%rax,%rcx,8),%xmm5
-	movq	16(%rax,%rcx,8),%xmm6
-	movq	24(%rax,%rcx,8),%xmm7
-	jmp	L$gather
-.p2align	4
-L$gather:
-	movq	-128(%rdx),%xmm0
-	movq	-64(%rdx),%xmm1
-	pand	%xmm4,%xmm0
-	movq	0(%rdx),%xmm2
-	pand	%xmm5,%xmm1
-	movq	64(%rdx),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-.byte	0x67,0x67
-	por	%xmm2,%xmm0
-	leaq	256(%rdx),%rdx
-	por	%xmm3,%xmm0
+L$SEH_begin_bn_gather5:
 
+.byte	0x4c,0x8d,0x14,0x24
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	leaq	L$inc(%rip),%rax
+	andq	$-16,%rsp
+
+	movd	%ecx,%xmm5
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	128(%rdx),%r11
+	leaq	128(%rsp),%rax
+
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-128(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-112(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-96(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-80(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-48(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-16(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,16(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,48(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,80(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,96(%rax)
+	movdqa	%xmm4,%xmm2
+	movdqa	%xmm3,112(%rax)
+	jmp	L$gather
+
+.p2align	5
+L$gather:
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r11),%xmm0
+	movdqa	-112(%r11),%xmm1
+	movdqa	-96(%r11),%xmm2
+	pand	-128(%rax),%xmm0
+	movdqa	-80(%r11),%xmm3
+	pand	-112(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r11),%xmm0
+	movdqa	-48(%r11),%xmm1
+	movdqa	-32(%r11),%xmm2
+	pand	-64(%rax),%xmm0
+	movdqa	-16(%r11),%xmm3
+	pand	-48(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	pand	0(%rax),%xmm0
+	movdqa	48(%r11),%xmm3
+	pand	16(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r11),%xmm0
+	movdqa	80(%r11),%xmm1
+	movdqa	96(%r11),%xmm2
+	pand	64(%rax),%xmm0
+	movdqa	112(%r11),%xmm3
+	pand	80(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	leaq	256(%r11),%r11
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
 	movq	%xmm0,(%rdi)
 	leaq	8(%rdi),%rdi
 	subl	$1,%esi
 	jnz	L$gather
+
+	leaq	(%r10),%rsp
 	.byte	0xf3,0xc3
 L$SEH_end_bn_gather5:
 
 .p2align	6
-L$magic_masks:
-.long	0,0, 0,0, 0,0, -1,-1
-.long	0,0, 0,0, 0,0,  0,0
+L$inc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 .byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 #endif
diff --git a/mac-x86_64/crypto/chacha/chacha-x86_64.S b/mac-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 0000000..c3554c8
--- /dev/null
+++ b/mac-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1584 @@
+#if defined(__x86_64__)
+.text	
+
+
+
+.p2align	6
+L$zero:
+.long	0,0,0,0
+L$one:
+.long	1,0,0,0
+L$inc:
+.long	0,1,2,3
+L$four:
+.long	4,4,4,4
+L$incy:
+.long	0,2,4,6,1,3,5,7
+L$eight:
+.long	8,8,8,8,8,8,8,8
+L$rot16:
+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+L$rot24:
+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+L$sigma:
+.byte	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl	_ChaCha20_ctr32
+.private_extern _ChaCha20_ctr32
+
+.p2align	6
+_ChaCha20_ctr32:
+	cmpq	$0,%rdx
+	je	L$no_data
+	movq	_OPENSSL_ia32cap_P+4(%rip),%r10
+	testl	$512,%r10d
+	jnz	L$ChaCha20_ssse3
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$64+24,%rsp
+
+
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	L$one(%rip),%xmm4
+
+
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movq	%rdx,%rbp
+	jmp	L$oop_outer
+
+.p2align	5
+L$oop_outer:
+	movl	$0x61707865,%eax
+	movl	$0x3320646e,%ebx
+	movl	$0x79622d32,%ecx
+	movl	$0x6b206574,%edx
+	movl	16(%rsp),%r8d
+	movl	20(%rsp),%r9d
+	movl	24(%rsp),%r10d
+	movl	28(%rsp),%r11d
+	movd	%xmm3,%r12d
+	movl	52(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	60(%rsp),%r15d
+
+	movq	%rbp,64+0(%rsp)
+	movl	$10,%ebp
+	movq	%rsi,64+8(%rsp)
+.byte	102,72,15,126,214
+	movq	%rdi,64+16(%rsp)
+	movq	%rsi,%rdi
+	shrq	$32,%rdi
+	jmp	L$oop
+
+.p2align	5
+L$oop:
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$16,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$16,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$12,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$12,%r9d
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$8,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$8,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$7,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$7,%r9d
+	movl	%esi,32(%rsp)
+	movl	%edi,36(%rsp)
+	movl	40(%rsp),%esi
+	movl	44(%rsp),%edi
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$16,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$16,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$12,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$12,%r11d
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$8,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$8,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$7,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$7,%r11d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$16,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$16,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$12,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$12,%r10d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$8,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$8,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$7,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$7,%r10d
+	movl	%esi,40(%rsp)
+	movl	%edi,44(%rsp)
+	movl	32(%rsp),%esi
+	movl	36(%rsp),%edi
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$16,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$16,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$12,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$12,%r8d
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$8,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$8,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$7,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$7,%r8d
+	decl	%ebp
+	jnz	L$oop
+	movl	%edi,36(%rsp)
+	movl	%esi,32(%rsp)
+	movq	64(%rsp),%rbp
+	movdqa	%xmm2,%xmm1
+	movq	64+8(%rsp),%rsi
+	paddd	%xmm4,%xmm3
+	movq	64+16(%rsp),%rdi
+
+	addl	$0x61707865,%eax
+	addl	$0x3320646e,%ebx
+	addl	$0x79622d32,%ecx
+	addl	$0x6b206574,%edx
+	addl	16(%rsp),%r8d
+	addl	20(%rsp),%r9d
+	addl	24(%rsp),%r10d
+	addl	28(%rsp),%r11d
+	addl	48(%rsp),%r12d
+	addl	52(%rsp),%r13d
+	addl	56(%rsp),%r14d
+	addl	60(%rsp),%r15d
+	paddd	32(%rsp),%xmm1
+
+	cmpq	$64,%rbp
+	jb	L$tail
+
+	xorl	0(%rsi),%eax
+	xorl	4(%rsi),%ebx
+	xorl	8(%rsi),%ecx
+	xorl	12(%rsi),%edx
+	xorl	16(%rsi),%r8d
+	xorl	20(%rsi),%r9d
+	xorl	24(%rsi),%r10d
+	xorl	28(%rsi),%r11d
+	movdqu	32(%rsi),%xmm0
+	xorl	48(%rsi),%r12d
+	xorl	52(%rsi),%r13d
+	xorl	56(%rsi),%r14d
+	xorl	60(%rsi),%r15d
+	leaq	64(%rsi),%rsi
+	pxor	%xmm1,%xmm0
+
+	movdqa	%xmm2,32(%rsp)
+	movd	%xmm3,48(%rsp)
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movl	%r12d,48(%rdi)
+	movl	%r13d,52(%rdi)
+	movl	%r14d,56(%rdi)
+	movl	%r15d,60(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rbp
+	jnz	L$oop_outer
+
+	jmp	L$done
+
+.p2align	4
+L$tail:
+	movl	%eax,0(%rsp)
+	movl	%ebx,4(%rsp)
+	xorq	%rbx,%rbx
+	movl	%ecx,8(%rsp)
+	movl	%edx,12(%rsp)
+	movl	%r8d,16(%rsp)
+	movl	%r9d,20(%rsp)
+	movl	%r10d,24(%rsp)
+	movl	%r11d,28(%rsp)
+	movdqa	%xmm1,32(%rsp)
+	movl	%r12d,48(%rsp)
+	movl	%r13d,52(%rsp)
+	movl	%r14d,56(%rsp)
+	movl	%r15d,60(%rsp)
+
+L$oop_tail:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%edx
+	leaq	1(%rbx),%rbx
+	xorl	%edx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rbp
+	jnz	L$oop_tail
+
+L$done:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+L$no_data:
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_ssse3:
+L$ChaCha20_ssse3:
+	cmpq	$128,%rdx
+	ja	L$ChaCha20_4x
+
+L$do_sse3_after_all:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	subq	$64+24,%rsp
+	movdqa	L$sigma(%rip),%xmm0
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	L$rot16(%rip),%xmm6
+	movdqa	L$rot24(%rip),%xmm7
+
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movl	$10,%ebp
+	jmp	L$oop_ssse3
+
+.p2align	5
+L$oop_outer_ssse3:
+	movdqa	L$one(%rip),%xmm3
+	movdqa	0(%rsp),%xmm0
+	movdqa	16(%rsp),%xmm1
+	movdqa	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+	movl	$10,%ebp
+	movdqa	%xmm3,48(%rsp)
+	jmp	L$oop_ssse3
+
+.p2align	5
+L$oop_ssse3:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%ebp
+	jnz	L$oop_ssse3
+	paddd	0(%rsp),%xmm0
+	paddd	16(%rsp),%xmm1
+	paddd	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+
+	cmpq	$64,%rdx
+	jb	L$tail_ssse3
+
+	movdqu	0(%rsi),%xmm4
+	movdqu	16(%rsi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%rsi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%rsi),%xmm5
+	leaq	64(%rsi),%rsi
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm1,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rdx
+	jnz	L$oop_outer_ssse3
+
+	jmp	L$done_ssse3
+
+.p2align	4
+L$tail_ssse3:
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	xorq	%rbx,%rbx
+
+L$oop_tail_ssse3:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%ecx
+	leaq	1(%rbx),%rbx
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rdx
+	jnz	L$oop_tail_ssse3
+
+L$done_ssse3:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_4x:
+L$ChaCha20_4x:
+	movq	%r10,%r11
+	shrq	$32,%r10
+	testq	$32,%r10
+	jnz	L$ChaCha20_8x
+	cmpq	$192,%rdx
+	ja	L$proceed4x
+
+	andq	$71303168,%r11
+	cmpq	$4194304,%r11
+	je	L$do_sse3_after_all
+
+L$proceed4x:
+	leaq	-120(%rsp),%r11
+	subq	$0x148+0,%rsp
+	movdqa	L$sigma(%rip),%xmm11
+	movdqu	(%rcx),%xmm15
+	movdqu	16(%rcx),%xmm7
+	movdqu	(%r8),%xmm3
+	leaq	256(%rsp),%rcx
+	leaq	L$rot16(%rip),%r10
+	leaq	L$rot24(%rip),%r11
+
+	pshufd	$0x00,%xmm11,%xmm8
+	pshufd	$0x55,%xmm11,%xmm9
+	movdqa	%xmm8,64(%rsp)
+	pshufd	$0xaa,%xmm11,%xmm10
+	movdqa	%xmm9,80(%rsp)
+	pshufd	$0xff,%xmm11,%xmm11
+	movdqa	%xmm10,96(%rsp)
+	movdqa	%xmm11,112(%rsp)
+
+	pshufd	$0x00,%xmm15,%xmm12
+	pshufd	$0x55,%xmm15,%xmm13
+	movdqa	%xmm12,128-256(%rcx)
+	pshufd	$0xaa,%xmm15,%xmm14
+	movdqa	%xmm13,144-256(%rcx)
+	pshufd	$0xff,%xmm15,%xmm15
+	movdqa	%xmm14,160-256(%rcx)
+	movdqa	%xmm15,176-256(%rcx)
+
+	pshufd	$0x00,%xmm7,%xmm4
+	pshufd	$0x55,%xmm7,%xmm5
+	movdqa	%xmm4,192-256(%rcx)
+	pshufd	$0xaa,%xmm7,%xmm6
+	movdqa	%xmm5,208-256(%rcx)
+	pshufd	$0xff,%xmm7,%xmm7
+	movdqa	%xmm6,224-256(%rcx)
+	movdqa	%xmm7,240-256(%rcx)
+
+	pshufd	$0x00,%xmm3,%xmm0
+	pshufd	$0x55,%xmm3,%xmm1
+	paddd	L$inc(%rip),%xmm0
+	pshufd	$0xaa,%xmm3,%xmm2
+	movdqa	%xmm1,272-256(%rcx)
+	pshufd	$0xff,%xmm3,%xmm3
+	movdqa	%xmm2,288-256(%rcx)
+	movdqa	%xmm3,304-256(%rcx)
+
+	jmp	L$oop_enter4x
+
+.p2align	5
+L$oop_outer4x:
+	movdqa	64(%rsp),%xmm8
+	movdqa	80(%rsp),%xmm9
+	movdqa	96(%rsp),%xmm10
+	movdqa	112(%rsp),%xmm11
+	movdqa	128-256(%rcx),%xmm12
+	movdqa	144-256(%rcx),%xmm13
+	movdqa	160-256(%rcx),%xmm14
+	movdqa	176-256(%rcx),%xmm15
+	movdqa	192-256(%rcx),%xmm4
+	movdqa	208-256(%rcx),%xmm5
+	movdqa	224-256(%rcx),%xmm6
+	movdqa	240-256(%rcx),%xmm7
+	movdqa	256-256(%rcx),%xmm0
+	movdqa	272-256(%rcx),%xmm1
+	movdqa	288-256(%rcx),%xmm2
+	movdqa	304-256(%rcx),%xmm3
+	paddd	L$four(%rip),%xmm0
+
+L$oop_enter4x:
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm7,48(%rsp)
+	movdqa	(%r10),%xmm7
+	movl	$10,%eax
+	movdqa	%xmm0,256-256(%rcx)
+	jmp	L$oop4x
+
+.p2align	5
+L$oop4x:
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,199
+.byte	102,15,56,0,207
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm6
+	pslld	$12,%xmm12
+	psrld	$20,%xmm6
+	movdqa	%xmm13,%xmm7
+	pslld	$12,%xmm13
+	por	%xmm6,%xmm12
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm13
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,198
+.byte	102,15,56,0,206
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm7
+	pslld	$7,%xmm12
+	psrld	$25,%xmm7
+	movdqa	%xmm13,%xmm6
+	pslld	$7,%xmm13
+	por	%xmm7,%xmm12
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm13
+	movdqa	%xmm4,0(%rsp)
+	movdqa	%xmm5,16(%rsp)
+	movdqa	32(%rsp),%xmm4
+	movdqa	48(%rsp),%xmm5
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,215
+.byte	102,15,56,0,223
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm6
+	pslld	$12,%xmm14
+	psrld	$20,%xmm6
+	movdqa	%xmm15,%xmm7
+	pslld	$12,%xmm15
+	por	%xmm6,%xmm14
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm15
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm7
+	pslld	$7,%xmm14
+	psrld	$25,%xmm7
+	movdqa	%xmm15,%xmm6
+	pslld	$7,%xmm15
+	por	%xmm7,%xmm14
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm15
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,223
+.byte	102,15,56,0,199
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm6
+	pslld	$12,%xmm13
+	psrld	$20,%xmm6
+	movdqa	%xmm14,%xmm7
+	pslld	$12,%xmm14
+	por	%xmm6,%xmm13
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm14
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,222
+.byte	102,15,56,0,198
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm7
+	pslld	$7,%xmm13
+	psrld	$25,%xmm7
+	movdqa	%xmm14,%xmm6
+	pslld	$7,%xmm14
+	por	%xmm7,%xmm13
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm14
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm5,48(%rsp)
+	movdqa	0(%rsp),%xmm4
+	movdqa	16(%rsp),%xmm5
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,207
+.byte	102,15,56,0,215
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm6
+	pslld	$12,%xmm15
+	psrld	$20,%xmm6
+	movdqa	%xmm12,%xmm7
+	pslld	$12,%xmm12
+	por	%xmm6,%xmm15
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm12
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm7
+	pslld	$7,%xmm15
+	psrld	$25,%xmm7
+	movdqa	%xmm12,%xmm6
+	pslld	$7,%xmm12
+	por	%xmm7,%xmm15
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm12
+	decl	%eax
+	jnz	L$oop4x
+
+	paddd	64(%rsp),%xmm8
+	paddd	80(%rsp),%xmm9
+	paddd	96(%rsp),%xmm10
+	paddd	112(%rsp),%xmm11
+
+	movdqa	%xmm8,%xmm6
+	punpckldq	%xmm9,%xmm8
+	movdqa	%xmm10,%xmm7
+	punpckldq	%xmm11,%xmm10
+	punpckhdq	%xmm9,%xmm6
+	punpckhdq	%xmm11,%xmm7
+	movdqa	%xmm8,%xmm9
+	punpcklqdq	%xmm10,%xmm8
+	movdqa	%xmm6,%xmm11
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm10,%xmm9
+	punpckhqdq	%xmm7,%xmm11
+	paddd	128-256(%rcx),%xmm12
+	paddd	144-256(%rcx),%xmm13
+	paddd	160-256(%rcx),%xmm14
+	paddd	176-256(%rcx),%xmm15
+
+	movdqa	%xmm8,0(%rsp)
+	movdqa	%xmm9,16(%rsp)
+	movdqa	32(%rsp),%xmm8
+	movdqa	48(%rsp),%xmm9
+
+	movdqa	%xmm12,%xmm10
+	punpckldq	%xmm13,%xmm12
+	movdqa	%xmm14,%xmm7
+	punpckldq	%xmm15,%xmm14
+	punpckhdq	%xmm13,%xmm10
+	punpckhdq	%xmm15,%xmm7
+	movdqa	%xmm12,%xmm13
+	punpcklqdq	%xmm14,%xmm12
+	movdqa	%xmm10,%xmm15
+	punpcklqdq	%xmm7,%xmm10
+	punpckhqdq	%xmm14,%xmm13
+	punpckhqdq	%xmm7,%xmm15
+	paddd	192-256(%rcx),%xmm4
+	paddd	208-256(%rcx),%xmm5
+	paddd	224-256(%rcx),%xmm8
+	paddd	240-256(%rcx),%xmm9
+
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm11,48(%rsp)
+
+	movdqa	%xmm4,%xmm14
+	punpckldq	%xmm5,%xmm4
+	movdqa	%xmm8,%xmm7
+	punpckldq	%xmm9,%xmm8
+	punpckhdq	%xmm5,%xmm14
+	punpckhdq	%xmm9,%xmm7
+	movdqa	%xmm4,%xmm5
+	punpcklqdq	%xmm8,%xmm4
+	movdqa	%xmm14,%xmm9
+	punpcklqdq	%xmm7,%xmm14
+	punpckhqdq	%xmm8,%xmm5
+	punpckhqdq	%xmm7,%xmm9
+	paddd	256-256(%rcx),%xmm0
+	paddd	272-256(%rcx),%xmm1
+	paddd	288-256(%rcx),%xmm2
+	paddd	304-256(%rcx),%xmm3
+
+	movdqa	%xmm0,%xmm8
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm8
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm8,%xmm3
+	punpcklqdq	%xmm7,%xmm8
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	cmpq	$256,%rdx
+	jb	L$tail4x
+
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	48(%rsp),%xmm6
+	pxor	%xmm15,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$256,%rdx
+	jnz	L$oop_outer4x
+
+	jmp	L$done4x
+
+L$tail4x:
+	cmpq	$192,%rdx
+	jae	L$192_or_more4x
+	cmpq	$128,%rdx
+	jae	L$128_or_more4x
+	cmpq	$64,%rdx
+	jae	L$64_or_more4x
+
+
+	xorq	%r10,%r10
+
+	movdqa	%xmm12,16(%rsp)
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm0,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$64_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	L$done4x
+
+	movdqa	16(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm13,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm5,32(%rsp)
+	subq	$64,%rdx
+	movdqa	%xmm1,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$128_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	je	L$done4x
+
+	movdqa	32(%rsp),%xmm6
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm10,16(%rsp)
+	leaq	128(%rdi),%rdi
+	movdqa	%xmm14,32(%rsp)
+	subq	$128,%rdx
+	movdqa	%xmm8,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$192_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	L$done4x
+
+	movdqa	48(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm15,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm9,32(%rsp)
+	subq	$192,%rdx
+	movdqa	%xmm3,48(%rsp)
+
+L$oop_tail4x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	L$oop_tail4x
+
+L$done4x:
+	addq	$0x148+0,%rsp
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_8x:
+L$ChaCha20_8x:
+	movq	%rsp,%r10
+	subq	$0x280+8,%rsp
+	andq	$-32,%rsp
+	vzeroupper
+	movq	%r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	L$sigma(%rip),%ymm11
+	vbroadcasti128	(%rcx),%ymm3
+	vbroadcasti128	16(%rcx),%ymm15
+	vbroadcasti128	(%r8),%ymm7
+	leaq	256(%rsp),%rcx
+	leaq	512(%rsp),%rax
+	leaq	L$rot16(%rip),%r10
+	leaq	L$rot24(%rip),%r11
+
+	vpshufd	$0x00,%ymm11,%ymm8
+	vpshufd	$0x55,%ymm11,%ymm9
+	vmovdqa	%ymm8,128-256(%rcx)
+	vpshufd	$0xaa,%ymm11,%ymm10
+	vmovdqa	%ymm9,160-256(%rcx)
+	vpshufd	$0xff,%ymm11,%ymm11
+	vmovdqa	%ymm10,192-256(%rcx)
+	vmovdqa	%ymm11,224-256(%rcx)
+
+	vpshufd	$0x00,%ymm3,%ymm0
+	vpshufd	$0x55,%ymm3,%ymm1
+	vmovdqa	%ymm0,256-256(%rcx)
+	vpshufd	$0xaa,%ymm3,%ymm2
+	vmovdqa	%ymm1,288-256(%rcx)
+	vpshufd	$0xff,%ymm3,%ymm3
+	vmovdqa	%ymm2,320-256(%rcx)
+	vmovdqa	%ymm3,352-256(%rcx)
+
+	vpshufd	$0x00,%ymm15,%ymm12
+	vpshufd	$0x55,%ymm15,%ymm13
+	vmovdqa	%ymm12,384-512(%rax)
+	vpshufd	$0xaa,%ymm15,%ymm14
+	vmovdqa	%ymm13,416-512(%rax)
+	vpshufd	$0xff,%ymm15,%ymm15
+	vmovdqa	%ymm14,448-512(%rax)
+	vmovdqa	%ymm15,480-512(%rax)
+
+	vpshufd	$0x00,%ymm7,%ymm4
+	vpshufd	$0x55,%ymm7,%ymm5
+	vpaddd	L$incy(%rip),%ymm4,%ymm4
+	vpshufd	$0xaa,%ymm7,%ymm6
+	vmovdqa	%ymm5,544-512(%rax)
+	vpshufd	$0xff,%ymm7,%ymm7
+	vmovdqa	%ymm6,576-512(%rax)
+	vmovdqa	%ymm7,608-512(%rax)
+
+	jmp	L$oop_enter8x
+
+.p2align	5
+L$oop_outer8x:
+	vmovdqa	128-256(%rcx),%ymm8
+	vmovdqa	160-256(%rcx),%ymm9
+	vmovdqa	192-256(%rcx),%ymm10
+	vmovdqa	224-256(%rcx),%ymm11
+	vmovdqa	256-256(%rcx),%ymm0
+	vmovdqa	288-256(%rcx),%ymm1
+	vmovdqa	320-256(%rcx),%ymm2
+	vmovdqa	352-256(%rcx),%ymm3
+	vmovdqa	384-512(%rax),%ymm12
+	vmovdqa	416-512(%rax),%ymm13
+	vmovdqa	448-512(%rax),%ymm14
+	vmovdqa	480-512(%rax),%ymm15
+	vmovdqa	512-512(%rax),%ymm4
+	vmovdqa	544-512(%rax),%ymm5
+	vmovdqa	576-512(%rax),%ymm6
+	vmovdqa	608-512(%rax),%ymm7
+	vpaddd	L$eight(%rip),%ymm4,%ymm4
+
+L$oop_enter8x:
+	vmovdqa	%ymm14,64(%rsp)
+	vmovdqa	%ymm15,96(%rsp)
+	vbroadcasti128	(%r10),%ymm15
+	vmovdqa	%ymm4,512-512(%rax)
+	movl	$10,%eax
+	jmp	L$oop8x
+
+.p2align	5
+L$oop8x:
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$12,%ymm0,%ymm14
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$12,%ymm1,%ymm15
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$7,%ymm0,%ymm15
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$7,%ymm1,%ymm14
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vmovdqa	%ymm12,0(%rsp)
+	vmovdqa	%ymm13,32(%rsp)
+	vmovdqa	64(%rsp),%ymm12
+	vmovdqa	96(%rsp),%ymm13
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$12,%ymm2,%ymm14
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$12,%ymm3,%ymm15
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$7,%ymm2,%ymm15
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$7,%ymm3,%ymm14
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$12,%ymm1,%ymm14
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$12,%ymm2,%ymm15
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$7,%ymm1,%ymm15
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$7,%ymm2,%ymm14
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vmovdqa	%ymm12,64(%rsp)
+	vmovdqa	%ymm13,96(%rsp)
+	vmovdqa	0(%rsp),%ymm12
+	vmovdqa	32(%rsp),%ymm13
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$12,%ymm3,%ymm14
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$12,%ymm0,%ymm15
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$7,%ymm3,%ymm15
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$7,%ymm0,%ymm14
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	decl	%eax
+	jnz	L$oop8x
+
+	leaq	512(%rsp),%rax
+	vpaddd	128-256(%rcx),%ymm8,%ymm8
+	vpaddd	160-256(%rcx),%ymm9,%ymm9
+	vpaddd	192-256(%rcx),%ymm10,%ymm10
+	vpaddd	224-256(%rcx),%ymm11,%ymm11
+
+	vpunpckldq	%ymm9,%ymm8,%ymm14
+	vpunpckldq	%ymm11,%ymm10,%ymm15
+	vpunpckhdq	%ymm9,%ymm8,%ymm8
+	vpunpckhdq	%ymm11,%ymm10,%ymm10
+	vpunpcklqdq	%ymm15,%ymm14,%ymm9
+	vpunpckhqdq	%ymm15,%ymm14,%ymm14
+	vpunpcklqdq	%ymm10,%ymm8,%ymm11
+	vpunpckhqdq	%ymm10,%ymm8,%ymm8
+	vpaddd	256-256(%rcx),%ymm0,%ymm0
+	vpaddd	288-256(%rcx),%ymm1,%ymm1
+	vpaddd	320-256(%rcx),%ymm2,%ymm2
+	vpaddd	352-256(%rcx),%ymm3,%ymm3
+
+	vpunpckldq	%ymm1,%ymm0,%ymm10
+	vpunpckldq	%ymm3,%ymm2,%ymm15
+	vpunpckhdq	%ymm1,%ymm0,%ymm0
+	vpunpckhdq	%ymm3,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm10,%ymm1
+	vpunpckhqdq	%ymm15,%ymm10,%ymm10
+	vpunpcklqdq	%ymm2,%ymm0,%ymm3
+	vpunpckhqdq	%ymm2,%ymm0,%ymm0
+	vperm2i128	$0x20,%ymm1,%ymm9,%ymm15
+	vperm2i128	$0x31,%ymm1,%ymm9,%ymm1
+	vperm2i128	$0x20,%ymm10,%ymm14,%ymm9
+	vperm2i128	$0x31,%ymm10,%ymm14,%ymm10
+	vperm2i128	$0x20,%ymm3,%ymm11,%ymm14
+	vperm2i128	$0x31,%ymm3,%ymm11,%ymm3
+	vperm2i128	$0x20,%ymm0,%ymm8,%ymm11
+	vperm2i128	$0x31,%ymm0,%ymm8,%ymm0
+	vmovdqa	%ymm15,0(%rsp)
+	vmovdqa	%ymm9,32(%rsp)
+	vmovdqa	64(%rsp),%ymm15
+	vmovdqa	96(%rsp),%ymm9
+
+	vpaddd	384-512(%rax),%ymm12,%ymm12
+	vpaddd	416-512(%rax),%ymm13,%ymm13
+	vpaddd	448-512(%rax),%ymm15,%ymm15
+	vpaddd	480-512(%rax),%ymm9,%ymm9
+
+	vpunpckldq	%ymm13,%ymm12,%ymm2
+	vpunpckldq	%ymm9,%ymm15,%ymm8
+	vpunpckhdq	%ymm13,%ymm12,%ymm12
+	vpunpckhdq	%ymm9,%ymm15,%ymm15
+	vpunpcklqdq	%ymm8,%ymm2,%ymm13
+	vpunpckhqdq	%ymm8,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm12,%ymm9
+	vpunpckhqdq	%ymm15,%ymm12,%ymm12
+	vpaddd	512-512(%rax),%ymm4,%ymm4
+	vpaddd	544-512(%rax),%ymm5,%ymm5
+	vpaddd	576-512(%rax),%ymm6,%ymm6
+	vpaddd	608-512(%rax),%ymm7,%ymm7
+
+	vpunpckldq	%ymm5,%ymm4,%ymm15
+	vpunpckldq	%ymm7,%ymm6,%ymm8
+	vpunpckhdq	%ymm5,%ymm4,%ymm4
+	vpunpckhdq	%ymm7,%ymm6,%ymm6
+	vpunpcklqdq	%ymm8,%ymm15,%ymm5
+	vpunpckhqdq	%ymm8,%ymm15,%ymm15
+	vpunpcklqdq	%ymm6,%ymm4,%ymm7
+	vpunpckhqdq	%ymm6,%ymm4,%ymm4
+	vperm2i128	$0x20,%ymm5,%ymm13,%ymm8
+	vperm2i128	$0x31,%ymm5,%ymm13,%ymm5
+	vperm2i128	$0x20,%ymm15,%ymm2,%ymm13
+	vperm2i128	$0x31,%ymm15,%ymm2,%ymm15
+	vperm2i128	$0x20,%ymm7,%ymm9,%ymm2
+	vperm2i128	$0x31,%ymm7,%ymm9,%ymm7
+	vperm2i128	$0x20,%ymm4,%ymm12,%ymm9
+	vperm2i128	$0x31,%ymm4,%ymm12,%ymm4
+	vmovdqa	0(%rsp),%ymm6
+	vmovdqa	32(%rsp),%ymm12
+
+	cmpq	$512,%rdx
+	jb	L$tail8x
+
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm12,%ymm12
+	vpxor	32(%rsi),%ymm13,%ymm13
+	vpxor	64(%rsi),%ymm10,%ymm10
+	vpxor	96(%rsi),%ymm15,%ymm15
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm12,0(%rdi)
+	vmovdqu	%ymm13,32(%rdi)
+	vmovdqu	%ymm10,64(%rdi)
+	vmovdqu	%ymm15,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm14,%ymm14
+	vpxor	32(%rsi),%ymm2,%ymm2
+	vpxor	64(%rsi),%ymm3,%ymm3
+	vpxor	96(%rsi),%ymm7,%ymm7
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm14,0(%rdi)
+	vmovdqu	%ymm2,32(%rdi)
+	vmovdqu	%ymm3,64(%rdi)
+	vmovdqu	%ymm7,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm11,%ymm11
+	vpxor	32(%rsi),%ymm9,%ymm9
+	vpxor	64(%rsi),%ymm0,%ymm0
+	vpxor	96(%rsi),%ymm4,%ymm4
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm11,0(%rdi)
+	vmovdqu	%ymm9,32(%rdi)
+	vmovdqu	%ymm0,64(%rdi)
+	vmovdqu	%ymm4,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$512,%rdx
+	jnz	L$oop_outer8x
+
+	jmp	L$done8x
+
+L$tail8x:
+	cmpq	$448,%rdx
+	jae	L$448_or_more8x
+	cmpq	$384,%rdx
+	jae	L$384_or_more8x
+	cmpq	$320,%rdx
+	jae	L$320_or_more8x
+	cmpq	$256,%rdx
+	jae	L$256_or_more8x
+	cmpq	$192,%rdx
+	jae	L$192_or_more8x
+	cmpq	$128,%rdx
+	jae	L$128_or_more8x
+	cmpq	$64,%rdx
+	jae	L$64_or_more8x
+
+	xorq	%r10,%r10
+	vmovdqa	%ymm6,0(%rsp)
+	vmovdqa	%ymm8,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$64_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	je	L$done8x
+
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm1,0(%rsp)
+	leaq	64(%rdi),%rdi
+	subq	$64,%rdx
+	vmovdqa	%ymm5,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$128_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	je	L$done8x
+
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm12,0(%rsp)
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	vmovdqa	%ymm13,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$192_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	je	L$done8x
+
+	leaq	192(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm10,0(%rsp)
+	leaq	192(%rdi),%rdi
+	subq	$192,%rdx
+	vmovdqa	%ymm15,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$256_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	je	L$done8x
+
+	leaq	256(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm14,0(%rsp)
+	leaq	256(%rdi),%rdi
+	subq	$256,%rdx
+	vmovdqa	%ymm2,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$320_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	je	L$done8x
+
+	leaq	320(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm3,0(%rsp)
+	leaq	320(%rdi),%rdi
+	subq	$320,%rdx
+	vmovdqa	%ymm7,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$384_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	je	L$done8x
+
+	leaq	384(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm11,0(%rsp)
+	leaq	384(%rdi),%rdi
+	subq	$384,%rdx
+	vmovdqa	%ymm9,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$448_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vpxor	384(%rsi),%ymm11,%ymm11
+	vpxor	416(%rsi),%ymm9,%ymm9
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	vmovdqu	%ymm11,384(%rdi)
+	vmovdqu	%ymm9,416(%rdi)
+	je	L$done8x
+
+	leaq	448(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm0,0(%rsp)
+	leaq	448(%rdi),%rdi
+	subq	$448,%rdx
+	vmovdqa	%ymm4,32(%rsp)
+
+L$oop_tail8x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	L$oop_tail8x
+
+L$done8x:
+	vzeroall
+	movq	640(%rsp),%rsp
+	.byte	0xf3,0xc3
+
+#endif
diff --git a/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
index bed1130..1cd0cc3 100644
--- a/mac-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -893,6 +893,7 @@
 	pushq	%r15
 	subq	$160+8,%rsp
 
+L$point_double_shortcutq:
 	movdqu	0(%rsi),%xmm0
 	movq	%rsi,%rbx
 	movdqu	16(%rsi),%xmm1
@@ -1114,7 +1115,7 @@
 	por	%xmm1,%xmm3
 
 	movdqu	0(%rsi),%xmm0
-	pshufd	$177,%xmm3,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm5
 	movdqu	16(%rsi),%xmm1
 	movdqu	32(%rsi),%xmm2
 	por	%xmm3,%xmm5
@@ -1124,7 +1125,7 @@
 	movq	64+16(%rsi),%r15
 	movq	64+24(%rsi),%r8
 	movdqa	%xmm0,480(%rsp)
-	pshufd	$30,%xmm5,%xmm4
+	pshufd	$0x1e,%xmm5,%xmm4
 	movdqa	%xmm1,480+16(%rsp)
 	por	%xmm0,%xmm1
 .byte	102,72,15,110,199
@@ -1144,10 +1145,10 @@
 	call	__ecp_nistz256_sqr_montq
 
 	pcmpeqd	%xmm4,%xmm5
-	pshufd	$177,%xmm3,%xmm4
+	pshufd	$0xb1,%xmm3,%xmm4
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
-	pshufd	$30,%xmm4,%xmm3
+	pshufd	$0x1e,%xmm4,%xmm3
 	por	%xmm3,%xmm4
 	pxor	%xmm3,%xmm3
 	pcmpeqd	%xmm3,%xmm4
@@ -1156,6 +1157,7 @@
 	movq	64+8(%rbx),%r14
 	movq	64+16(%rbx),%r15
 	movq	64+24(%rbx),%r8
+.byte	102,72,15,110,203
 
 	leaq	64-0(%rbx),%rsi
 	leaq	32(%rsp),%rdi
@@ -1247,7 +1249,7 @@
 	testq	%r8,%r8
 	jnz	L$add_proceedq
 	testq	%r9,%r9
-	jz	L$add_proceedq
+	jz	L$add_doubleq
 
 .byte	102,72,15,126,199
 	pxor	%xmm0,%xmm0
@@ -1260,6 +1262,13 @@
 	jmp	L$add_doneq
 
 .p2align	5
+L$add_doubleq:
+.byte	102,72,15,126,206
+.byte	102,72,15,126,199
+	addq	$416,%rsp
+	jmp	L$point_double_shortcutq
+
+.p2align	5
 L$add_proceedq:
 	movq	0+64(%rsp),%rax
 	movq	8+64(%rsp),%r14
@@ -1507,13 +1516,13 @@
 	por	%xmm1,%xmm3
 
 	movdqu	0(%rbx),%xmm0
-	pshufd	$177,%xmm3,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm5
 	movdqu	16(%rbx),%xmm1
 	movdqu	32(%rbx),%xmm2
 	por	%xmm3,%xmm5
 	movdqu	48(%rbx),%xmm3
 	movdqa	%xmm0,416(%rsp)
-	pshufd	$30,%xmm5,%xmm4
+	pshufd	$0x1e,%xmm5,%xmm4
 	movdqa	%xmm1,416+16(%rsp)
 	por	%xmm0,%xmm1
 .byte	102,72,15,110,199
@@ -1529,13 +1538,13 @@
 	call	__ecp_nistz256_sqr_montq
 
 	pcmpeqd	%xmm4,%xmm5
-	pshufd	$177,%xmm3,%xmm4
+	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rax
 
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
-	pshufd	$30,%xmm4,%xmm3
+	pshufd	$0x1e,%xmm4,%xmm3
 	movq	%r13,%r10
 	por	%xmm3,%xmm4
 	pxor	%xmm3,%xmm3
diff --git a/mac-x86_64/crypto/md5/md5-x86_64.S b/mac-x86_64/crypto/md5/md5-x86_64.S
index 1e61479..16fd2cc 100644
--- a/mac-x86_64/crypto/md5/md5-x86_64.S
+++ b/mac-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@
 	movl	%ecx,%r11d
 	addl	%ecx,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	xorl	%edx,%r11d
 	leal	-198630844(%rax,%r10,1),%eax
 	orl	%ebx,%r11d
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	28(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -511,7 +511,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	56(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -520,7 +520,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	20(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -529,7 +529,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	48(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -538,7 +538,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	12(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -547,7 +547,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	40(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -556,7 +556,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	4(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -565,7 +565,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	32(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -574,7 +574,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	60(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -583,7 +583,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	24(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -592,7 +592,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	52(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -601,7 +601,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	16(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -610,7 +610,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	44(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -619,7 +619,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	8(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -628,7 +628,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	36(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -637,7 +637,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
diff --git a/mac-x86_64/crypto/modes/ghash-x86_64.S b/mac-x86_64/crypto/modes/ghash-x86_64.S
index 305a91c..1072c7f 100644
--- a/mac-x86_64/crypto/modes/ghash-x86_64.S
+++ b/mac-x86_64/crypto/modes/ghash-x86_64.S
@@ -22,14 +22,14 @@
 	movq	$14,%rcx
 	movq	8(%rsi,%rax,1),%r8
 	movq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	movq	%r8,%rdx
 	jmp	L$oop1
 
 .p2align	4
 L$oop1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	movb	(%rdi,%rcx,1),%al
 	shrq	$4,%r9
@@ -45,13 +45,13 @@
 	js	L$break1
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
@@ -60,19 +60,19 @@
 .p2align	4
 L$break1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rbx,1),%r8
@@ -880,20 +880,20 @@
 	movdqu	32(%rsi),%xmm7
 .byte	102,65,15,56,0,194
 
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	L$odd_tail
 
 	movdqu	16(%rsi),%xmm6
 	movl	_OPENSSL_ia32cap_P+4(%rip),%eax
-	cmpq	$48,%rcx
+	cmpq	$0x30,%rcx
 	jb	L$skip4x
 
 	andl	$71303168,%eax
 	cmpl	$4194304,%eax
 	je	L$skip4x
 
-	subq	$48,%rcx
-	movq	$11547335547999543296,%rax
+	subq	$0x30,%rcx
+	movq	$0xA040608020C0E000,%rax
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
@@ -940,7 +940,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jc	L$tail4x
 
 	jmp	L$mod4_loop
@@ -1023,7 +1023,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jnc	L$mod4_loop
 
 L$tail4x:
@@ -1067,10 +1067,10 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-	addq	$64,%rcx
+	addq	$0x40,%rcx
 	jz	L$done
 	movdqu	32(%rsi),%xmm7
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	L$odd_tail
 L$skip4x:
 
@@ -1093,7 +1093,7 @@
 
 	leaq	32(%rdx),%rdx
 	nop
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	jbe	L$even_tail
 	nop
 	jmp	L$mod_loop
@@ -1156,7 +1156,7 @@
 .byte	102,15,58,68,231,0
 	pxor	%xmm1,%xmm0
 
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	ja	L$mod_loop
 
 L$even_tail:
diff --git a/sources.mk b/sources.mk
index e82f3d5..1ffa657 100644
--- a/sources.mk
+++ b/sources.mk
@@ -45,7 +45,6 @@
   src/crypto/asn1/f_int.c\
   src/crypto/asn1/f_string.c\
   src/crypto/asn1/t_bitst.c\
-  src/crypto/asn1/t_pkey.c\
   src/crypto/asn1/tasn_dec.c\
   src/crypto/asn1/tasn_enc.c\
   src/crypto/asn1/tasn_fre.c\
@@ -87,11 +86,11 @@
   src/crypto/bn/shift.c\
   src/crypto/bn/sqrt.c\
   src/crypto/buf/buf.c\
+  src/crypto/bytestring/asn1_compat.c\
   src/crypto/bytestring/ber.c\
   src/crypto/bytestring/cbb.c\
   src/crypto/bytestring/cbs.c\
-  src/crypto/chacha/chacha_generic.c\
-  src/crypto/chacha/chacha_vec.c\
+  src/crypto/chacha/chacha.c\
   src/crypto/cipher/aead.c\
   src/crypto/cipher/cipher.c\
   src/crypto/cipher/derive_key.c\
@@ -106,10 +105,13 @@
   src/crypto/cipher/tls_cbc.c\
   src/crypto/cmac/cmac.c\
   src/crypto/conf/conf.c\
+  src/crypto/cpu-aarch64-linux.c\
+  src/crypto/cpu-arm-linux.c\
   src/crypto/cpu-arm.c\
   src/crypto/cpu-intel.c\
   src/crypto/crypto.c\
   src/crypto/curve25519/curve25519.c\
+  src/crypto/curve25519/spake25519.c\
   src/crypto/curve25519/x25519-x86_64.c\
   src/crypto/des/des.c\
   src/crypto/dh/check.c\
@@ -118,8 +120,6 @@
   src/crypto/dh/params.c\
   src/crypto/digest/digest.c\
   src/crypto/digest/digests.c\
-  src/crypto/directory_posix.c\
-  src/crypto/directory_win.c\
   src/crypto/dsa/dsa.c\
   src/crypto/dsa/dsa_asn1.c\
   src/crypto/ec/ec.c\
@@ -138,7 +138,6 @@
   src/crypto/ecdsa/ecdsa_asn1.c\
   src/crypto/engine/engine.c\
   src/crypto/err/err.c\
-  src/crypto/evp/algorithm.c\
   src/crypto/evp/digestsign.c\
   src/crypto/evp/evp.c\
   src/crypto/evp/evp_asn1.c\
@@ -149,6 +148,7 @@
   src/crypto/evp/p_rsa.c\
   src/crypto/evp/p_rsa_asn1.c\
   src/crypto/evp/pbkdf.c\
+  src/crypto/evp/print.c\
   src/crypto/evp/sign.c\
   src/crypto/ex_data.c\
   src/crypto/hkdf/hkdf.c\
@@ -162,6 +162,12 @@
   src/crypto/modes/ctr.c\
   src/crypto/modes/gcm.c\
   src/crypto/modes/ofb.c\
+  src/crypto/newhope/error_correction.c\
+  src/crypto/newhope/newhope.c\
+  src/crypto/newhope/ntt.c\
+  src/crypto/newhope/poly.c\
+  src/crypto/newhope/precomp.c\
+  src/crypto/newhope/reduce.c\
   src/crypto/obj/obj.c\
   src/crypto/obj/obj_xref.c\
   src/crypto/pem/pem_all.c\
@@ -179,6 +185,7 @@
   src/crypto/poly1305/poly1305.c\
   src/crypto/poly1305/poly1305_arm.c\
   src/crypto/poly1305/poly1305_vec.c\
+  src/crypto/rand/deterministic.c\
   src/crypto/rand/rand.c\
   src/crypto/rand/urandom.c\
   src/crypto/rand/windows.c\
@@ -203,11 +210,13 @@
   src/crypto/x509/a_sign.c\
   src/crypto/x509/a_strex.c\
   src/crypto/x509/a_verify.c\
+  src/crypto/x509/algorithm.c\
   src/crypto/x509/asn1_gen.c\
   src/crypto/x509/by_dir.c\
   src/crypto/x509/by_file.c\
   src/crypto/x509/i2d_pr.c\
   src/crypto/x509/pkcs7.c\
+  src/crypto/x509/rsa_pss.c\
   src/crypto/x509/t_crl.c\
   src/crypto/x509/t_req.c\
   src/crypto/x509/t_x509.c\
@@ -332,6 +341,7 @@
 linux_aarch64_sources := \
   linux-aarch64/crypto/aes/aesv8-armx64.S\
   linux-aarch64/crypto/bn/armv8-mont.S\
+  linux-aarch64/crypto/chacha/chacha-armv8.S\
   linux-aarch64/crypto/modes/ghashv8-armx64.S\
   linux-aarch64/crypto/sha/sha1-armv8.S\
   linux-aarch64/crypto/sha/sha256-armv8.S\
@@ -342,13 +352,12 @@
   linux-arm/crypto/aes/aesv8-armx32.S\
   linux-arm/crypto/aes/bsaes-armv7.S\
   linux-arm/crypto/bn/armv4-mont.S\
+  linux-arm/crypto/chacha/chacha-armv4.S\
   linux-arm/crypto/modes/ghash-armv4.S\
   linux-arm/crypto/modes/ghashv8-armx32.S\
   linux-arm/crypto/sha/sha1-armv4-large.S\
   linux-arm/crypto/sha/sha256-armv4.S\
   linux-arm/crypto/sha/sha512-armv4.S\
-  src/crypto/chacha/chacha_vec_arm.S\
-  src/crypto/cpu-arm-asm.S\
   src/crypto/curve25519/asm/x25519-asm-arm.S\
   src/crypto/poly1305/poly1305_arm_asm.S\
 
@@ -359,6 +368,7 @@
   linux-x86/crypto/bn/bn-586.S\
   linux-x86/crypto/bn/co-586.S\
   linux-x86/crypto/bn/x86-mont.S\
+  linux-x86/crypto/chacha/chacha-x86.S\
   linux-x86/crypto/md5/md5-586.S\
   linux-x86/crypto/modes/ghash-x86.S\
   linux-x86/crypto/rc4/rc4-586.S\
@@ -375,6 +385,7 @@
   linux-x86_64/crypto/bn/rsaz-x86_64.S\
   linux-x86_64/crypto/bn/x86_64-mont.S\
   linux-x86_64/crypto/bn/x86_64-mont5.S\
+  linux-x86_64/crypto/chacha/chacha-x86_64.S\
   linux-x86_64/crypto/ec/p256-x86_64-asm.S\
   linux-x86_64/crypto/md5/md5-x86_64.S\
   linux-x86_64/crypto/modes/aesni-gcm-x86_64.S\
@@ -384,6 +395,7 @@
   linux-x86_64/crypto/sha/sha1-x86_64.S\
   linux-x86_64/crypto/sha/sha256-x86_64.S\
   linux-x86_64/crypto/sha/sha512-x86_64.S\
+  src/crypto/curve25519/asm/x25519-asm-x86_64.S\
 
 mac_x86_sources := \
   mac-x86/crypto/aes/aes-586.S\
@@ -392,6 +404,7 @@
   mac-x86/crypto/bn/bn-586.S\
   mac-x86/crypto/bn/co-586.S\
   mac-x86/crypto/bn/x86-mont.S\
+  mac-x86/crypto/chacha/chacha-x86.S\
   mac-x86/crypto/md5/md5-586.S\
   mac-x86/crypto/modes/ghash-x86.S\
   mac-x86/crypto/rc4/rc4-586.S\
@@ -408,6 +421,7 @@
   mac-x86_64/crypto/bn/rsaz-x86_64.S\
   mac-x86_64/crypto/bn/x86_64-mont.S\
   mac-x86_64/crypto/bn/x86_64-mont5.S\
+  mac-x86_64/crypto/chacha/chacha-x86_64.S\
   mac-x86_64/crypto/ec/p256-x86_64-asm.S\
   mac-x86_64/crypto/md5/md5-x86_64.S\
   mac-x86_64/crypto/modes/aesni-gcm-x86_64.S\
@@ -425,6 +439,7 @@
   win-x86/crypto/bn/bn-586.asm\
   win-x86/crypto/bn/co-586.asm\
   win-x86/crypto/bn/x86-mont.asm\
+  win-x86/crypto/chacha/chacha-x86.asm\
   win-x86/crypto/md5/md5-586.asm\
   win-x86/crypto/modes/ghash-x86.asm\
   win-x86/crypto/rc4/rc4-586.asm\
@@ -441,6 +456,7 @@
   win-x86_64/crypto/bn/rsaz-x86_64.asm\
   win-x86_64/crypto/bn/x86_64-mont.asm\
   win-x86_64/crypto/bn/x86_64-mont5.asm\
+  win-x86_64/crypto/chacha/chacha-x86_64.asm\
   win-x86_64/crypto/ec/p256-x86_64-asm.asm\
   win-x86_64/crypto/md5/md5-x86_64.asm\
   win-x86_64/crypto/modes/aesni-gcm-x86_64.asm\
diff --git a/src/.clang-format b/src/.clang-format
index 43032d4..5865a70 100644
--- a/src/.clang-format
+++ b/src/.clang-format
@@ -2,3 +2,6 @@
 MaxEmptyLinesToKeep: 3
 AllowShortIfStatementsOnASingleLine: false
 AllowShortLoopsOnASingleLine: false
+DerivePointerAlignment: false
+PointerAlignment: Right
+
diff --git a/src/.github/PULL_REQUEST_TEMPLATE b/src/.github/PULL_REQUEST_TEMPLATE
new file mode 100644
index 0000000..6c101ea
--- /dev/null
+++ b/src/.github/PULL_REQUEST_TEMPLATE
@@ -0,0 +1,7 @@
+Please do not send pull requests to the BoringSSL repository.
+
+We do, however, take contributions gladly.
+
+See https://boringssl.googlesource.com/boringssl/+/master/CONTRIBUTING.md
+
+Thanks!
diff --git a/src/BUILDING.md b/src/BUILDING.md
index 02f8f11..e111310 100644
--- a/src/BUILDING.md
+++ b/src/BUILDING.md
@@ -2,14 +2,18 @@
 
 ## Build Prerequisites
 
-  * [CMake](http://www.cmake.org/download/) 2.8.8 or later is required.
+  * [CMake](https://cmake.org/download/) 2.8.8 or later is required.
 
   * Perl 5.6.1 or later is required. On Windows,
-    [Strawberry Perl](http://strawberryperl.com/) and MSYS Perl have both been
-    reported to work. If not found by CMake, it may be configured explicitly by
-    setting `PERL_EXECUTABLE`.
+    [Active State Perl](http://www.activestate.com/activeperl/) has been
+    reported to work, as has MSYS Perl.
+    [Strawberry Perl](http://strawberryperl.com/) also works but it adds GCC
+    to `PATH`, which can confuse some build tools when identifying the compiler
+    (removing `C:\Strawberry\c\bin` from `PATH` should resolve any problems).
+    If Perl is not found by CMake, it may be configured explicitly by setting
+    `PERL_EXECUTABLE`.
 
-  * On Windows you currently must use [Ninja](https://martine.github.io/ninja/)
+  * On Windows you currently must use [Ninja](https://ninja-build.org/)
     to build; on other platforms, it is not required, but recommended, because
     it makes builds faster.
 
@@ -21,22 +25,12 @@
     `CMAKE_ASM_NASM_COMPILER`.
 
   * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
-    with Platform SDK 8.1 or later are supported. Recent versions of GCC and
-    Clang should work on non-Windows platforms, and maybe on Windows too.
+    with Platform SDK 8.1 or later are supported. Recent versions of GCC (4.8+)
+    and Clang should work on non-Windows platforms, and maybe on Windows too.
 
   * [Go](https://golang.org/dl/) is required. If not found by CMake, the go
     executable may be configured explicitly by setting `GO_EXECUTABLE`.
 
-  * If you change crypto/chacha/chacha\_vec.c, you will need the
-    arm-linux-gnueabihf-gcc compiler:
-
-    ```
-    wget https://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
-    echo bc4ca2ced084d2dc12424815a4442e19cb1422db87068830305d90075feb1a3b  gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz | sha256sum -c && \
-    tar xf gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
-    sudo mv gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf /opt/
-    ```
-
 ## Building
 
 Using Ninja (note the 'N' is capitalized in the cmake invocation):
@@ -58,7 +52,8 @@
 themselves automatically.
 
 Note that the default build flags in the top-level `CMakeLists.txt` are for
-debugging—optimisation isn't enabled.
+debugging—optimisation isn't enabled. Pass `-DCMAKE_BUILD_TYPE=Release` to
+`cmake` to configure a release build.
 
 If you want to cross-compile then there is an example toolchain file for 32-bit
 Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
@@ -75,6 +70,9 @@
 where performance is the overriding concern, `OPENSSL_SMALL` can be defined to
 remove some code that is especially large.
 
+See [CMake's documentation](https://cmake.org/cmake/help/v3.4/manual/cmake-variables.7.html)
+for other variables which may be used to configure the build.
+
 ### Building for Android
 
 It's possible to build BoringSSL with the Android NDK using CMake. This has
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e07be54..adf2021 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,16 @@
 cmake_minimum_required (VERSION 2.8.10)
 
-project (BoringSSL)
+# Defer enabling C and CXX languages.
+project (BoringSSL NONE)
+
+if(WIN32)
+  # On Windows, prefer cl over gcc if both are available. By default most of
+  # the CMake generators prefer gcc, even on Windows.
+  set(CMAKE_GENERATOR_CC cl)
+endif()
+
+enable_language(C)
+enable_language(CXX)
 
 if(ANDROID)
   # Android-NDK CMake files reconfigure the path and so Go and Perl won't be
@@ -17,8 +27,9 @@
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wsign-compare -Wmissing-field-initializers -ggdb -std=c++0x -fvisibility=hidden")
+  set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ${C_CXX_FLAGS} -Wmissing-declarations")
 elseif(MSVC)
   set(MSVC_DISABLED_WARNINGS_LIST
       "C4100" # 'exarg' : unreferenced formal parameter
@@ -60,10 +71,25 @@
       "C4996" # 'read': The POSIX name for this item is deprecated. Instead,
               # use the ISO C++ conformant name: _read.
      )
+  if(NOT(CMAKE_C_COMPILER_VERSION VERSION_LESS "19.0.23506"))
+    # MSVC 2015 Update 1.
+    set(MSVC_DISABLED_WARNINGS_LIST
+        ${MSVC_DISABLED_WARNINGS_LIST}
+        "C4464" # relative include path contains '..'
+        "C4623" # default constructor was implicitly defined as deleted
+        "C5027" # move assignment operator was implicitly defined as deleted
+       )
+    set(MSVC_LEVEL4_WARNINGS_LIST
+        # See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header
+        "C4265" # class has virtual functions, but destructor is not virtual
+        )
+    string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR
+                              ${MSVC_LEVEL4_WARNINGS_LIST})
+  endif()
   string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
                             ${MSVC_DISABLED_WARNINGS_LIST})
-  set(CMAKE_C_FLAGS   "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
-  set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
+  set(CMAKE_C_FLAGS   "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
+  set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
   add_definitions(-D_HAS_EXCEPTIONS=0)
   add_definitions(-DWIN32_LEAN_AND_MEAN)
   add_definitions(-DNOMINMAX)
@@ -85,8 +111,11 @@
     message("You need to build with Clang for fuzzing to work")
   endif()
 
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
+  add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
+  set(RUNNER_ARGS "-fuzzer")
+
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
   link_directories(.)
 endif()
@@ -173,6 +202,7 @@
             ${CMAKE_BINARY_DIR}
     COMMAND cd ssl/test/runner
     COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
+            ${RUNNER_ARGS}
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS all_tests bssl_shim
     ${MAYBE_USES_TERMINAL})
diff --git a/src/CONTRIBUTING.md b/src/CONTRIBUTING.md
new file mode 100644
index 0000000..8907cc9
--- /dev/null
+++ b/src/CONTRIBUTING.md
@@ -0,0 +1,49 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+### Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first via email with your idea so that we can help out and possibly guide
+you. Coordinating up front makes it much easier to avoid frustration later on.
+
+### Code reviews
+All submissions, including submissions by project members, require review. We
+use [Gerrit](https://boringssl-review.googlesource.com) for this purpose.
+
+#### Setup
+If you have not done so on this machine, you will need to set up a password for
+Gerrit. Sign in with a Google account, visit
+[this link](https://boringssl.googlesource.com/), and click the "Generate
+Password" link in the top right. You will also need to prepare your checkout to
+[add Change-Ids](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html)
+on commit. Run:
+
+    curl -Lo .git/hooks/commit-msg https://boringssl-review.googlesource.com/tools/hooks/commit-msg
+    chmod u+x .git/hooks/commit-msg
+
+#### Uploading changes
+To upload a change, push it to the special `refs/for/master` target:
+
+    git push origin HEAD:refs/for/master
+
+The output will then give you a link to the change. Add `agl@google.com` and
+`davidben@google.com` as reviewers.
+
+Pushing a commit with the same Change-Id as an existing change will upload a new
+version of it. (Use the `git rebase` or `git commit --amend` commands.)
+
+For more detailed instructions, see the
+[Gerrit User Guide](https://gerrit-review.googlesource.com/Documentation/intro-user.html).
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the
+[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
diff --git a/src/FUZZING.md b/src/FUZZING.md
index 4bd15a3..86d0930 100644
--- a/src/FUZZING.md
+++ b/src/FUZZING.md
@@ -13,9 +13,9 @@
 In order for the fuzz tests to link, the linker needs to find libFuzzer. This is not commonly provided and you may need to download the [Clang source code](http://llvm.org/releases/download.html) and do the following:
 
 ```
-cd llvm-3.7.0.src/lib
-clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
-ar q libFuzzer.a *.o
+svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
+clang++ -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
+ar ruv libFuzzer.a Fuzzer*.o
 ```
 
 Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
@@ -23,18 +23,41 @@
 From the `build/` directory, you can then run the fuzzers. For example:
 
 ```
-./fuzz/cert -max_len=4000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
+./fuzz/cert -max_len=3072 -jobs=32 -workers=32 ../fuzz/cert_corpus/
 ```
 
-The `max_len` argument is often important because, without it, libFuzzer defaults to limiting all test cases to 64 bytes, which is often insufficient for the formats that we wish to fuzz. The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing.
+The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
 
-There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
-
-Here are the recommended values of `max_len` for each test.
+The recommended values of `max_len` for each test are:
 
 | Test      | `max_len` value |
 |-----------|-----------------|
-| `privkey` | 2048            |
 | `cert`    | 3072            |
-| `server`  | 1024            |
-| `client`  | 4096            |
+| `client`  | 20000           |
+| `pkcs8`   | 2048            |
+| `privkey` | 2048            |
+| `server`  | 4096            |
+| `spki`    | 1024            |
+
+
+These were determined by rounding up the length of the largest case in the corpus.
+
+There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
+
+## Minimising the corpuses
+
+When a large number of new seeds are available, it's a good idea to minimise the corpus so that different seeds that trigger the same code paths can be deduplicated.
+
+In order to minimise all the corpuses, build for fuzzing and run `./fuzz/minimise_corpuses.sh`. Note that minimisation is, oddly, often not idempotent for unknown reasons.
+
+## Fuzzer mode
+
+When `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` defined. This modifies the library, particularly the TLS stack, to be more friendly to fuzzers. It will:
+
+* Replace `RAND_bytes` with a deterministic PRNG. Call `RAND_reset_for_fuzzing()` at the start of fuzzers which use `RAND_bytes` to reset the PRNG state.
+
+* Modify the TLS stack to perform all signature checks (CertificateVerify and ServerKeyExchange) and the Finished check, but always act as if the check succeeded.
+
+* Treat every cipher as the NULL cipher.
+
+This is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
diff --git a/src/INCORPORATING.md b/src/INCORPORATING.md
new file mode 100644
index 0000000..58f37db
--- /dev/null
+++ b/src/INCORPORATING.md
@@ -0,0 +1,85 @@
+# Incorporating BoringSSL into a project
+
+**Note**: if your target project is not a Google project then first read the
+[main README](/README.md) about the purpose of BoringSSL.
+
+## Directory layout
+
+Typically projects create a `third_party/boringssl` directory to put
+BoringSSL-specific files into. The source code of BoringSSL itself goes into
+`third_party/boringssl/src`, either by copying or as a
+[submodule](https://git-scm.com/docs/git-submodule).
+
+It's generally a mistake to put BoringSSL's source code into
+`third_party/boringssl` directly because pre-built files and custom build files
+need to go somewhere and merging these with the BoringSSL source code makes
+updating things more complex.
+
+## Build support
+
+BoringSSL is designed to work with many different build systems. Currently,
+different projects use [GYP](https://gyp.gsrc.io/),
+[GN](https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/quick_start.md),
+[Bazel](http://bazel.io/) and [Make](https://www.gnu.org/software/make/)  to
+build BoringSSL, without too much pain.
+
+The development build system is CMake and the CMake build knows how to
+automatically generate the intermediate files that BoringSSL needs. However,
+outside of the CMake environment, these intermediates are generated once and
+checked into the incorporating project's source repository. This avoids
+incorporating projects needing to support Perl and Go in their build systems.
+
+The script [`util/generate_build_files.py`](/util/generate_build_files.py)
+expects to be run from the `third_party/boringssl` directory and to find the
+BoringSSL source code in `src/`. You should pass it a single argument: the name
+of the build system that you're using. If you don't use any of the supported
+build systems then you should augment `generate_build_files.py` with support
+for it.
+
+The script will pregenerate the intermediate files (see
+[BUILDING.md](/BUILDING.md) for details about which tools will need to be
+installed) and output helper files for that build system. It doesn't generate a
+complete build script, just file and test lists, which change often. For
+example, see the
+[file](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated.gni)
+and
+[test](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated_tests.gni)
+lists generated for GN in Chromium.
+
+## Defines
+
+BoringSSL does not present a lot of configurability in order to reduce the
+number of configurations that need to be tested. But there are a couple of
+\#defines that you may wish to set:
+
+`OPENSSL_NO_ASM` prevents the use of assembly code (although it's up to you to
+ensure that the build system doesn't link it in if you wish to reduce binary
+size). This will have a significant performance impact but can be useful if you
+wish to use tools like
+[AddressSanitizer](http://clang.llvm.org/docs/AddressSanitizer.html) that
+interact poorly with assembly code.
+
+`OPENSSL_SMALL` removes some code that is especially large at some performance
+cost.
+
+## Symbols
+
+You cannot link multiple versions of BoringSSL or OpenSSL into a single binary
+without dealing with symbol conflicts. If you are statically linking multiple
+versions together, there's not a lot that can be done because C doesn't have a
+module system.
+
+If you are using multiple versions in a single binary, in different shared
+objects, ensure you build BoringSSL with `-fvisibility=hidden` and do not
+export any of BoringSSL's symbols. This will prevent any collisions with other
+verisons that may be included in other shared objects. Note that this requires
+that all callers of BoringSSL APIs live in the same shared object as BoringSSL.
+
+If you require that BoringSSL APIs be used across shared object boundaries,
+continue to build with `-fvisibility=hidden` but define
+`BORINGSSL_SHARED_LIBRARY` in both BoringSSL and consumers. BoringSSL's own
+source files (but *not* consumers' source files) must also build with
+`BORINGSSL_IMPLEMENTATION` defined. This will export BoringSSL's public symbols
+in the resulting shared object while hiding private symbols. However note that,
+as with a static link, this precludes dynamically linking with another version
+of BoringSSL or OpenSSL.
diff --git a/src/LICENSE b/src/LICENSE
index b242dcb..a25996f 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -14,6 +14,13 @@
 licenses. In case of any license issues related to OpenSSL please contact
 openssl-core@openssl.org.
 
+The following are Google-internal bug numbers where explicit permission from
+some authors is recorded for use of their work. (This is purely for our own
+record keeping.)
+  27287199
+  27287880
+  27287883
+
   OpenSSL License
   ---------------
 
diff --git a/src/PORTING.md b/src/PORTING.md
index b3e50d7..f953e74 100644
--- a/src/PORTING.md
+++ b/src/PORTING.md
@@ -130,6 +130,23 @@
 uppercase. Some code may require changes to avoid being sensitive to this
 difference.
 
+### Legacy ASN.1 functions
+
+OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form:
+
+    RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+
+In addition to returning the result, OpenSSL places it in `*out` if `out` is
+not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not
+always) reuse that object rather than allocating a new one. In BoringSSL, these
+functions are compatibility wrappers over a newer ASN.1 stack. Even if `*out`
+is not `NULL`, these wrappers will always allocate a new object and free the
+previous one.
+
+Ensure that callers do not rely on this object reuse behavior. It is
+recommended to avoid the `out` parameter completely and always pass in `NULL`.
+Note that less error-prone APIs are available for BoringSSL-specific code (see
+below).
 
 ## Optional BoringSSL-specific simplifications
 
@@ -162,3 +179,9 @@
 these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
 corresponding Windows APIs internally and is always thread-safe where the API
 guarantees it.
+
+### ASN.1
+
+BoringSSL is in the process of deprecating OpenSSL's `d2i` and `i2d` in favor of
+new functions using the much less error-prone `CBS` and `CBB` types.
+BoringSSL-only code should use those functions where available.
diff --git a/src/README.md b/src/README.md
index d8a65c2..4caedb7 100644
--- a/src/README.md
+++ b/src/README.md
@@ -25,6 +25,8 @@
 
   * [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
   * [BUILDING.md](/BUILDING.md): how to build BoringSSL
+  * [INCORPORATING.md](/INCORPORATING.md): how to incorporate BoringSSL into a project.
   * [STYLE.md](/STYLE.md): rules and guidelines for coding style.
   * include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
   * [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
+  * [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6651f29..3b4413c 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -22,6 +22,7 @@
   endif()
   set(ASM_EXT S)
   enable_language(ASM)
+  set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack")
 else()
   if (CMAKE_CL_64)
     message("Using nasm")
@@ -53,39 +54,6 @@
   )
 endfunction()
 
-if (${ARCH} STREQUAL "x86_64")
-  set(
-    CRYPTO_ARCH_SOURCES
-
-    cpu-intel.c
-  )
-endif()
-
-if (${ARCH} STREQUAL "x86")
-  set(
-    CRYPTO_ARCH_SOURCES
-
-    cpu-intel.c
-  )
-endif()
-
-if (${ARCH} STREQUAL "arm")
-  set(
-    CRYPTO_ARCH_SOURCES
-
-    cpu-arm.c
-    cpu-arm-asm.S
-  )
-endif()
-
-if (${ARCH} STREQUAL "aarch64")
-  set(
-    CRYPTO_ARCH_SOURCES
-
-    cpu-arm.c
-  )
-endif()
-
 # Level 0.1 - depends on nothing outside this set.
 add_subdirectory(stack)
 add_subdirectory(lhash)
@@ -106,6 +74,7 @@
 add_subdirectory(chacha)
 add_subdirectory(poly1305)
 add_subdirectory(curve25519)
+add_subdirectory(newhope)
 
 # Level 1, depends only on 0.*
 add_subdirectory(digest)
@@ -143,9 +112,11 @@
 add_library(
   crypto
 
+  cpu-aarch64-linux.c
+  cpu-arm.c
+  cpu-arm-linux.c
+  cpu-intel.c
   crypto.c
-  directory_posix.c
-  directory_win.c
   ex_data.c
   mem.c
   refcount_c11.c
@@ -156,8 +127,6 @@
   thread_win.c
   time_support.c
 
-  ${CRYPTO_ARCH_SOURCES}
-
   $<TARGET_OBJECTS:stack>
   $<TARGET_OBJECTS:lhash>
   $<TARGET_OBJECTS:err>
@@ -196,7 +165,8 @@
   $<TARGET_OBJECTS:pem>
   $<TARGET_OBJECTS:x509>
   $<TARGET_OBJECTS:x509v3>
-  $<TARGET_OBJECTS:pkcs8>
+  $<TARGET_OBJECTS:pkcs8_lib>
+  $<TARGET_OBJECTS:newhope>
 )
 
 if(NOT MSVC AND NOT ANDROID)
diff --git a/src/crypto/aes/asm/aes-armv4.pl b/src/crypto/aes/asm/aes-armv4.pl
index 882017a..a60ed4c 100644
--- a/src/crypto/aes/asm/aes-armv4.pl
+++ b/src/crypto/aes/asm/aes-armv4.pl
@@ -191,7 +191,6 @@
 @ void asm_AES_encrypt(const unsigned char *in, unsigned char *out,
 @ 		       const AES_KEY *key) {
 .global asm_AES_encrypt
-.hidden asm_AES_encrypt
 .type   asm_AES_encrypt,%function
 .align	5
 asm_AES_encrypt:
@@ -441,7 +440,6 @@
 .size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
 
 .global asm_AES_set_encrypt_key
-.hidden asm_AES_set_encrypt_key
 .type   asm_AES_set_encrypt_key,%function
 .align	5
 asm_AES_set_encrypt_key:
@@ -748,7 +746,6 @@
 .size	asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
 
 .global asm_AES_set_decrypt_key
-.hidden asm_AES_set_decrypt_key
 .type   asm_AES_set_decrypt_key,%function
 .align	5
 asm_AES_set_decrypt_key:
@@ -765,7 +762,6 @@
 
 @ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
 .global	AES_set_enc2dec_key
-.hidden	AES_set_enc2dec_key
 .type	AES_set_enc2dec_key,%function
 .align	5
 AES_set_enc2dec_key:
@@ -971,7 +967,6 @@
 @ void asm_AES_decrypt(const unsigned char *in, unsigned char *out,
 @ 		       const AES_KEY *key) {
 .global asm_AES_decrypt
-.hidden asm_AES_decrypt
 .type   asm_AES_decrypt,%function
 .align	5
 asm_AES_decrypt:
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 2617fef..22362f5 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -1006,7 +1006,6 @@
 			# used for benchmarking...
 $code.=<<___;
 .globl	bsaes_enc_key_convert
-.hidden	bsaes_enc_key_convert
 .type	bsaes_enc_key_convert,%function
 .align	4
 bsaes_enc_key_convert:
@@ -1025,7 +1024,6 @@
 .size	bsaes_enc_key_convert,.-bsaes_enc_key_convert
 
 .globl	bsaes_encrypt_128
-.hidden	bsaes_encrypt_128
 .type	bsaes_encrypt_128,%function
 .align	4
 bsaes_encrypt_128:
@@ -1056,7 +1054,6 @@
 .size	bsaes_encrypt_128,.-bsaes_encrypt_128
 
 .globl	bsaes_dec_key_convert
-.hidden	bsaes_dec_key_convert
 .type	bsaes_dec_key_convert,%function
 .align	4
 bsaes_dec_key_convert:
@@ -1077,7 +1074,6 @@
 .size	bsaes_dec_key_convert,.-bsaes_dec_key_convert
 
 .globl	bsaes_decrypt_128
-.hidden	bsaes_decrypt_128
 .type	bsaes_decrypt_128,%function
 .align	4
 bsaes_decrypt_128:
@@ -1117,7 +1113,6 @@
 .extern AES_decrypt
 
 .global	bsaes_cbc_encrypt
-.hidden	bsaes_cbc_encrypt
 .type	bsaes_cbc_encrypt,%function
 .align	5
 bsaes_cbc_encrypt:
@@ -1393,7 +1388,6 @@
 $code.=<<___;
 .extern	AES_encrypt
 .global	bsaes_ctr32_encrypt_blocks
-.hidden	bsaes_ctr32_encrypt_blocks
 .type	bsaes_ctr32_encrypt_blocks,%function
 .align	5
 bsaes_ctr32_encrypt_blocks:
@@ -1635,7 +1629,6 @@
 
 $code.=<<___;
 .globl	bsaes_xts_encrypt
-.hidden	bsaes_xts_encrypt
 .type	bsaes_xts_encrypt,%function
 .align	4
 bsaes_xts_encrypt:
@@ -2050,7 +2043,6 @@
 .size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
 
 .globl	bsaes_xts_decrypt
-.hidden	bsaes_xts_decrypt
 .type	bsaes_xts_decrypt,%function
 .align	4
 bsaes_xts_decrypt:
diff --git a/src/crypto/aes/mode_wrappers.c b/src/crypto/aes/mode_wrappers.c
index dc657dc..4929920 100644
--- a/src/crypto/aes/mode_wrappers.c
+++ b/src/crypto/aes/mode_wrappers.c
@@ -96,13 +96,17 @@
 
 void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
                         const AES_KEY *key, uint8_t *ivec, int *num) {
-  CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+  unsigned num_u = (unsigned)(*num);
+  CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u,
                         (block128_f)AES_encrypt);
+  *num = (int)num_u;
 }
 
 void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
                         const AES_KEY *key, uint8_t *ivec, int *num,
                         int enc) {
-  CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+  unsigned num_u = (unsigned)(*num);
+  CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc,
                         (block128_f)AES_encrypt);
+  *num = (int)num_u;
 }
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index 41e3122..f0667fc 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -32,7 +32,6 @@
   f_int.c
   f_string.c
   t_bitst.c
-  t_pkey.c
   tasn_dec.c
   tasn_enc.c
   tasn_fre.c
@@ -43,3 +42,14 @@
   x_bignum.c
   x_long.c
 )
+
+add_executable(
+  asn1_test
+
+  asn1_test.cc
+
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(asn1_test crypto)
+add_dependencies(all_tests asn1_test)
diff --git a/src/crypto/asn1/a_bitstr.c b/src/crypto/asn1/a_bitstr.c
index 8bad339..2705ea5 100644
--- a/src/crypto/asn1/a_bitstr.c
+++ b/src/crypto/asn1/a_bitstr.c
@@ -33,7 +33,7 @@
  *     Eric Young (eay@cryptsoft.com)"
  *    The word 'cryptographic' can be left out if the rouines from the library
  *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
+ * 4. If you include any Windows specific code (or a derivative thereof) from
  *    the apps directory (application code) you must include an acknowledgement:
  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  *
@@ -61,195 +61,203 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
-{ return M_ASN1_BIT_STRING_set(x, d, len); }
+{
+    return M_ASN1_BIT_STRING_set(x, d, len);
+}
 
 int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
-	{
-	int ret,j,bits,len;
-	unsigned char *p,*d;
+{
+    int ret, j, bits, len;
+    unsigned char *p, *d;
 
-	if (a == NULL) return(0);
+    if (a == NULL)
+        return (0);
 
-	len=a->length;
+    len = a->length;
 
-	if (len > 0)
-		{
-		if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
-			{
-			bits=(int)a->flags&0x07;
-			}
-		else
-			{
-			for ( ; len > 0; len--)
-				{
-				if (a->data[len-1]) break;
-				}
-			j=a->data[len-1];
-			if      (j & 0x01) bits=0;
-			else if (j & 0x02) bits=1;
-			else if (j & 0x04) bits=2;
-			else if (j & 0x08) bits=3;
-			else if (j & 0x10) bits=4;
-			else if (j & 0x20) bits=5;
-			else if (j & 0x40) bits=6;
-			else if (j & 0x80) bits=7;
-			else bits=0; /* should not happen */
-			}
-		}
-	else
-		bits=0;
+    if (len > 0) {
+        if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+            bits = (int)a->flags & 0x07;
+        } else {
+            for (; len > 0; len--) {
+                if (a->data[len - 1])
+                    break;
+            }
+            j = a->data[len - 1];
+            if (j & 0x01)
+                bits = 0;
+            else if (j & 0x02)
+                bits = 1;
+            else if (j & 0x04)
+                bits = 2;
+            else if (j & 0x08)
+                bits = 3;
+            else if (j & 0x10)
+                bits = 4;
+            else if (j & 0x20)
+                bits = 5;
+            else if (j & 0x40)
+                bits = 6;
+            else if (j & 0x80)
+                bits = 7;
+            else
+                bits = 0;       /* should not happen */
+        }
+    } else
+        bits = 0;
 
-	ret=1+len;
-	if (pp == NULL) return(ret);
+    ret = 1 + len;
+    if (pp == NULL)
+        return (ret);
 
-	p= *pp;
+    p = *pp;
 
-	*(p++)=(unsigned char)bits;
-	d=a->data;
-	memcpy(p,d,len);
-	p+=len;
-	if (len > 0) p[-1]&=(0xff<<bits);
-	*pp=p;
-	return(ret);
-	}
+    *(p++) = (unsigned char)bits;
+    d = a->data;
+    memcpy(p, d, len);
+    p += len;
+    if (len > 0)
+        p[-1] &= (0xff << bits);
+    *pp = p;
+    return (ret);
+}
 
 ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
-	const unsigned char **pp, long len)
-	{
-	ASN1_BIT_STRING *ret=NULL;
-	const unsigned char *p;
-	unsigned char *s;
-	int padding;
+                                     const unsigned char **pp, long len)
+{
+    ASN1_BIT_STRING *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    int padding;
 
-	if (len < 1)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
-		goto err;
-		}
+    if (len < 1) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
+        goto err;
+    }
 
-	if ((a == NULL) || ((*a) == NULL))
-		{
-		if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
-		}
-	else
-		ret=(*a);
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
 
-	p= *pp;
-	padding = *(p++);
-	if (padding > 7)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
-		goto err;
-		}
+    p = *pp;
+    padding = *(p++);
+    if (padding > 7) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+        goto err;
+    }
 
-	/* We do this to preserve the settings.  If we modify
-	 * the settings, via the _set_bit function, we will recalculate
-	 * on output */
-	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
-	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|padding); /* set */
+    /*
+     * We do this to preserve the settings.  If we modify the settings, via
+     * the _set_bit function, we will recalculate on output
+     */
+    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
+    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */
 
-	if (len-- > 1) /* using one because of the bits left byte */
-		{
-		s=(unsigned char *)OPENSSL_malloc((int)len);
-		if (s == NULL)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		memcpy(s,p,(int)len);
-		s[len-1]&=(0xff<<padding);
-		p+=len;
-		}
-	else
-		s=NULL;
+    if (len-- > 1) {            /* using one because of the bits left byte */
+        s = (unsigned char *)OPENSSL_malloc((int)len);
+        if (s == NULL) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        memcpy(s, p, (int)len);
+        s[len - 1] &= (0xff << padding);
+        p += len;
+    } else
+        s = NULL;
 
-	ret->length=(int)len;
-	if (ret->data != NULL) OPENSSL_free(ret->data);
-	ret->data=s;
-	ret->type=V_ASN1_BIT_STRING;
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		M_ASN1_BIT_STRING_free(ret);
-	return(NULL);
-	}
-
-/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
- */
-int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
-	{
-	int w,v,iv;
-	unsigned char *c;
-
-	w=n/8;
-	v=1<<(7-(n&0x07));
-	iv= ~v;
-	if (!value) v=0;
-
-	if (a == NULL)
-		return 0;
-
-	a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
-
-	if ((a->length < (w+1)) || (a->data == NULL))
-		{
-		if (!value) return(1); /* Don't need to set */
-		if (a->data == NULL)
-			c=(unsigned char *)OPENSSL_malloc(w+1);
-		else
-			c=(unsigned char *)OPENSSL_realloc_clean(a->data,
-								 a->length,
-								 w+1);
-		if (c == NULL)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return 0;
-			}
-  		if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
-		a->data=c;
-		a->length=w+1;
-	}
-	a->data[w]=((a->data[w])&iv)|v;
-	while ((a->length > 0) && (a->data[a->length-1] == 0))
-		a->length--;
-	return(1);
-	}
-
-int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
-	{
-	int w,v;
-
-	w=n/8;
-	v=1<<(7-(n&0x07));
-	if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
-		return(0);
-	return((a->data[w]&v) != 0);
-	}
+    ret->length = (int)len;
+    if (ret->data != NULL)
+        OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->type = V_ASN1_BIT_STRING;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        M_ASN1_BIT_STRING_free(ret);
+    return (NULL);
+}
 
 /*
- * Checks if the given bit string contains only bits specified by 
+ * These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
+ */
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+{
+    int w, v, iv;
+    unsigned char *c;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    iv = ~v;
+    if (!value)
+        v = 0;
+
+    if (a == NULL)
+        return 0;
+
+    a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+    if ((a->length < (w + 1)) || (a->data == NULL)) {
+        if (!value)
+            return (1);         /* Don't need to set */
+        if (a->data == NULL)
+            c = (unsigned char *)OPENSSL_malloc(w + 1);
+        else
+            c = (unsigned char *)OPENSSL_realloc_clean(a->data,
+                                                       a->length, w + 1);
+        if (c == NULL) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        if (w + 1 - a->length > 0)
+            memset(c + a->length, 0, w + 1 - a->length);
+        a->data = c;
+        a->length = w + 1;
+    }
+    a->data[w] = ((a->data[w]) & iv) | v;
+    while ((a->length > 0) && (a->data[a->length - 1] == 0))
+        a->length--;
+    return (1);
+}
+
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
+{
+    int w, v;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+        return (0);
+    return ((a->data[w] & v) != 0);
+}
+
+/*
+ * Checks if the given bit string contains only bits specified by
  * the flags vector. Returns 0 if there is at least one bit set in 'a'
  * which is not specified in 'flags', 1 otherwise.
  * 'len' is the length of 'flags'.
  */
 int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
-			  unsigned char *flags, int flags_len)
-	{
-	int i, ok;
-	/* Check if there is one bit set at all. */
-	if (!a || !a->data) return 1;
+                          unsigned char *flags, int flags_len)
+{
+    int i, ok;
+    /* Check if there is one bit set at all. */
+    if (!a || !a->data)
+        return 1;
 
-	/* Check each byte of the internal representation of the bit string. */
-	ok = 1;
-	for (i = 0; i < a->length && ok; ++i)
-		{
-		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
-		/* We are done if there is an unneeded bit set. */
-		ok = (a->data[i] & mask) == 0;
-		}
-	return ok;
-	}
+    /*
+     * Check each byte of the internal representation of the bit string.
+     */
+    ok = 1;
+    for (i = 0; i < a->length && ok; ++i) {
+        unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+        /* We are done if there is an unneeded bit set. */
+        ok = (a->data[i] & mask) == 0;
+    }
+    return ok;
+}
diff --git a/src/crypto/asn1/a_bool.c b/src/crypto/asn1/a_bool.c
index 826bcf4..64a079e 100644
--- a/src/crypto/asn1/a_bool.c
+++ b/src/crypto/asn1/a_bool.c
@@ -33,7 +33,7 @@
  *     Eric Young (eay@cryptsoft.com)"
  *    The word 'cryptographic' can be left out if the rouines from the library
  *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
+ * 4. If you include any Windows specific code (or a derivative thereof) from
  *    the apps directory (application code) you must include an acknowledgement:
  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  *
@@ -59,54 +59,52 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
-	{
-	int r;
-	unsigned char *p;
+{
+    int r;
+    unsigned char *p;
 
-	r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
-	if (pp == NULL) return(r);
-	p= *pp;
+    r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
+    if (pp == NULL)
+        return (r);
+    p = *pp;
 
-	ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
-	*(p++)= (unsigned char)a;
-	*pp=p;
-	return(r);
-	}
+    ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
+    *(p++) = (unsigned char)a;
+    *pp = p;
+    return (r);
+}
 
 int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
-	{
-	int ret= -1;
-	const unsigned char *p;
-	long len;
-	int inf,tag,xclass;
-	int i=0;
+{
+    int ret = -1;
+    const unsigned char *p;
+    long len;
+    int inf, tag, xclass;
+    int i = 0;
 
-	p= *pp;
-	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
-	if (inf & 0x80)
-		{
-		i=ASN1_R_BAD_OBJECT_HEADER;
-		goto err;
-		}
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
 
-	if (tag != V_ASN1_BOOLEAN)
-		{
-		i=ASN1_R_EXPECTING_A_BOOLEAN;
-		goto err;
-		}
+    if (tag != V_ASN1_BOOLEAN) {
+        i = ASN1_R_EXPECTING_A_BOOLEAN;
+        goto err;
+    }
 
-	if (len != 1)
-		{
-		i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
-		goto err;
-		}
-	ret= (int)*(p++);
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	return(ret);
-	}
+    if (len != 1) {
+        i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
+        goto err;
+    }
+    ret = (int)*(p++);
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    return (ret);
+}
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
index 1904375..7e2f85d 100644
--- a/src/crypto/asn1/a_bytes.c
+++ b/src/crypto/asn1/a_bytes.c
@@ -62,256 +62,247 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
-/* type is a 'bitmap' of acceptable string types.
+/*
+ * type is a 'bitmap' of acceptable string types.
  */
 ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
-	     long length, int type)
-	{
-	ASN1_STRING *ret=NULL;
-	const unsigned char *p;
-	unsigned char *s;
-	long len;
-	int inf,tag,xclass;
-	int i=0;
+                                 long length, int type)
+{
+    ASN1_STRING *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    long len;
+    int inf, tag, xclass;
+    int i = 0;
 
-	p= *pp;
-	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
-	if (inf & 0x80) goto err;
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80)
+        goto err;
 
-	if (tag >= 32)
-		{
-		i=ASN1_R_TAG_VALUE_TOO_HIGH;
-		goto err;
-		}
-	if (!(ASN1_tag2bit(tag) & type))
-		{
-		i=ASN1_R_WRONG_TYPE;
-		goto err;
-		}
+    if (tag >= 32) {
+        i = ASN1_R_TAG_VALUE_TOO_HIGH;
+        goto err;
+    }
+    if (!(ASN1_tag2bit(tag) & type)) {
+        i = ASN1_R_WRONG_TYPE;
+        goto err;
+    }
 
-	/* If a bit-string, exit early */
-	if (tag == V_ASN1_BIT_STRING)
-		return(d2i_ASN1_BIT_STRING(a,pp,length));
+    /* If a bit-string, exit early */
+    if (tag == V_ASN1_BIT_STRING)
+        return (d2i_ASN1_BIT_STRING(a, pp, length));
 
-	if ((a == NULL) || ((*a) == NULL))
-		{
-		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
-		}
-	else
-		ret=(*a);
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_STRING_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
 
-	if (len != 0)
-		{
-		s=(unsigned char *)OPENSSL_malloc((int)len+1);
-		if (s == NULL)
-			{
-			i=ERR_R_MALLOC_FAILURE;
-			goto err;
-			}
-		memcpy(s,p,(int)len);
-		s[len]='\0';
-		p+=len;
-		}
-	else
-		s=NULL;
+    if (len != 0) {
+        s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+        if (s == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        memcpy(s, p, (int)len);
+        s[len] = '\0';
+        p += len;
+    } else
+        s = NULL;
 
-	if (ret->data != NULL) OPENSSL_free(ret->data);
-	ret->length=(int)len;
-	ret->data=s;
-	ret->type=tag;
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		ASN1_STRING_free(ret);
-	return(NULL);
-	}
+    if (ret->data != NULL)
+        OPENSSL_free(ret->data);
+    ret->length = (int)len;
+    ret->data = s;
+    ret->type = tag;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        ASN1_STRING_free(ret);
+    return (NULL);
+}
 
 int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
-	{
-	int ret,r,constructed;
-	unsigned char *p;
+{
+    int ret, r, constructed;
+    unsigned char *p;
 
-	if (a == NULL)  return(0);
+    if (a == NULL)
+        return (0);
 
-	if (tag == V_ASN1_BIT_STRING)
-		return(i2d_ASN1_BIT_STRING(a,pp));
-		
-	ret=a->length;
-	r=ASN1_object_size(0,ret,tag);
-	if (pp == NULL) return(r);
-	p= *pp;
+    if (tag == V_ASN1_BIT_STRING)
+        return (i2d_ASN1_BIT_STRING(a, pp));
 
-	if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
-		constructed=1;
-	else
-		constructed=0;
-	ASN1_put_object(&p,constructed,ret,tag,xclass);
-	memcpy(p,a->data,a->length);
-	p+=a->length;
-	*pp= p;
-	return(r);
-	}
+    ret = a->length;
+    r = ASN1_object_size(0, ret, tag);
+    if (pp == NULL)
+        return (r);
+    p = *pp;
+
+    if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
+        constructed = 1;
+    else
+        constructed = 0;
+    ASN1_put_object(&p, constructed, ret, tag, xclass);
+    memcpy(p, a->data, a->length);
+    p += a->length;
+    *pp = p;
+    return (r);
+}
 
 ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
-	     long length, int Ptag, int Pclass)
-	{
-	ASN1_STRING *ret=NULL;
-	const unsigned char *p;
-	unsigned char *s;
-	long len;
-	int inf,tag,xclass;
-	int i=0;
+                            long length, int Ptag, int Pclass)
+{
+    ASN1_STRING *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    long len;
+    int inf, tag, xclass;
+    int i = 0;
 
-	if ((a == NULL) || ((*a) == NULL))
-		{
-		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
-		}
-	else
-		ret=(*a);
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_STRING_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
 
-	p= *pp;
-	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
-	if (inf & 0x80)
-		{
-		i=ASN1_R_BAD_OBJECT_HEADER;
-		goto err;
-		}
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
 
-	if (tag != Ptag)
-		{
-		i=ASN1_R_WRONG_TAG;
-		goto err;
-		}
+    if (tag != Ptag) {
+        i = ASN1_R_WRONG_TAG;
+        goto err;
+    }
 
-	if (inf & V_ASN1_CONSTRUCTED)
-		{
-		ASN1_const_CTX c;
+    if (inf & V_ASN1_CONSTRUCTED) {
+        ASN1_const_CTX c;
 
-		c.pp=pp;
-		c.p=p;
-		c.inf=inf;
-		c.slen=len;
-		c.tag=Ptag;
-		c.xclass=Pclass;
-		c.max=(length == 0)?0:(p+length);
-		if (!asn1_collate_primitive(ret,&c)) 
-			goto err; 
-		else
-			{
-			p=c.p;
-			}
-		}
-	else
-		{
-		if (len != 0)
-			{
-			if ((ret->length < len) || (ret->data == NULL))
-				{
-				if (ret->data != NULL) OPENSSL_free(ret->data);
-				s=(unsigned char *)OPENSSL_malloc((int)len + 1);
-				if (s == NULL)
-					{
-					i=ERR_R_MALLOC_FAILURE;
-					goto err;
-					}
-				}
-			else
-				s=ret->data;
-			memcpy(s,p,(int)len);
-			s[len] = '\0';
-			p+=len;
-			}
-		else
-			{
-			s=NULL;
-			if (ret->data != NULL) OPENSSL_free(ret->data);
-			}
+        c.pp = pp;
+        c.p = p;
+        c.inf = inf;
+        c.slen = len;
+        c.tag = Ptag;
+        c.xclass = Pclass;
+        c.max = (length == 0) ? 0 : (p + length);
+        if (!asn1_collate_primitive(ret, &c))
+            goto err;
+        else {
+            p = c.p;
+        }
+    } else {
+        if (len != 0) {
+            if ((ret->length < len) || (ret->data == NULL)) {
+                if (ret->data != NULL)
+                    OPENSSL_free(ret->data);
+                s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+                if (s == NULL) {
+                    i = ERR_R_MALLOC_FAILURE;
+                    goto err;
+                }
+            } else
+                s = ret->data;
+            memcpy(s, p, (int)len);
+            s[len] = '\0';
+            p += len;
+        } else {
+            s = NULL;
+            if (ret->data != NULL)
+                OPENSSL_free(ret->data);
+        }
 
-		ret->length=(int)len;
-		ret->data=s;
-		ret->type=Ptag;
-		}
+        ret->length = (int)len;
+        ret->data = s;
+        ret->type = Ptag;
+    }
 
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		ASN1_STRING_free(ret);
-	OPENSSL_PUT_ERROR(ASN1, i);
-	return(NULL);
-	}
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        ASN1_STRING_free(ret);
+    OPENSSL_PUT_ERROR(ASN1, i);
+    return (NULL);
+}
 
-
-/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
- * them into the one structure that is then returned */
-/* There have been a few bug fixes for this function from
- * Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
+/*
+ * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
+ * into the one structure that is then returned
+ */
+/*
+ * There have been a few bug fixes for this function from Paul Keogh
+ * <paul.keogh@sse.ie>, many thanks to him
+ */
 static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
-	{
-	ASN1_STRING *os=NULL;
-	BUF_MEM b;
-	int num;
+{
+    ASN1_STRING *os = NULL;
+    BUF_MEM b;
+    int num;
 
-	b.length=0;
-	b.max=0;
-	b.data=NULL;
+    b.length = 0;
+    b.max = 0;
+    b.data = NULL;
 
-	if (a == NULL)
-		{
-		c->error=ERR_R_PASSED_NULL_PARAMETER;
-		goto err;
-		}
+    if (a == NULL) {
+        c->error = ERR_R_PASSED_NULL_PARAMETER;
+        goto err;
+    }
 
-	num=0;
-	for (;;)
-		{
-		if (c->inf & 1)
-			{
-			c->eos=ASN1_const_check_infinite_end(&c->p,
-				(long)(c->max-c->p));
-			if (c->eos) break;
-			}
-		else
-			{
-			if (c->slen <= 0) break;
-			}
+    num = 0;
+    for (;;) {
+        if (c->inf & 1) {
+            c->eos = ASN1_const_check_infinite_end(&c->p,
+                                                   (long)(c->max - c->p));
+            if (c->eos)
+                break;
+        } else {
+            if (c->slen <= 0)
+                break;
+        }
 
-		c->q=c->p;
-		if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
-			== NULL)
-			{
-			c->error=ERR_R_ASN1_LIB;
-			goto err;
-			}
+        c->q = c->p;
+        if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
+            == NULL) {
+            c->error = ERR_R_ASN1_LIB;
+            goto err;
+        }
 
-		if (!BUF_MEM_grow_clean(&b,num+os->length))
-			{
-			c->error=ERR_R_BUF_LIB;
-			goto err;
-			}
-		memcpy(&(b.data[num]),os->data,os->length);
-		if (!(c->inf & 1))
-			c->slen-=(c->p-c->q);
-		num+=os->length;
-		}
+        if (!BUF_MEM_grow_clean(&b, num + os->length)) {
+            c->error = ERR_R_BUF_LIB;
+            goto err;
+        }
+        memcpy(&(b.data[num]), os->data, os->length);
+        if (!(c->inf & 1))
+            c->slen -= (c->p - c->q);
+        num += os->length;
+    }
 
-	if (!asn1_const_Finish(c)) goto err;
+    if (!asn1_const_Finish(c))
+        goto err;
 
-	a->length=num;
-	if (a->data != NULL) OPENSSL_free(a->data);
-	a->data=(unsigned char *)b.data;
-	if (os != NULL) ASN1_STRING_free(os);
-	return(1);
-err:
-	OPENSSL_PUT_ERROR(ASN1, c->error);
-	if (os != NULL) ASN1_STRING_free(os);
-	if (b.data != NULL) OPENSSL_free(b.data);
-	return(0);
-	}
-
+    a->length = num;
+    if (a->data != NULL)
+        OPENSSL_free(a->data);
+    a->data = (unsigned char *)b.data;
+    if (os != NULL)
+        ASN1_STRING_free(os);
+    return (1);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, c->error);
+    if (os != NULL)
+        ASN1_STRING_free(os);
+    if (b.data != NULL)
+        OPENSSL_free(b.data);
+    return (0);
+}
diff --git a/src/crypto/asn1/a_d2i_fp.c b/src/crypto/asn1/a_d2i_fp.c
index 97ec75b..b544971 100644
--- a/src/crypto/asn1/a_d2i_fp.c
+++ b/src/crypto/asn1/a_d2i_fp.c
@@ -62,225 +62,221 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
 
 #ifndef NO_OLD_ASN1
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
 
-void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
-        {
-        BIO *b;
-        void *ret;
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
+{
+    BIO *b;
+    void *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
-                return(NULL);
-		}
-        BIO_set_fp(b,in,BIO_NOCLOSE);
-        ret=ASN1_d2i_bio(xnew,d2i,b,x);
-        BIO_free(b);
-        return(ret);
-        }
-#endif
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+        return (NULL);
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_d2i_bio(xnew, d2i, b, x);
+    BIO_free(b);
+    return (ret);
+}
+# endif
 
-void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
-	{
-	BUF_MEM *b = NULL;
-	const unsigned char *p;
-	void *ret=NULL;
-	int len;
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
 
-	len = asn1_d2i_read_bio(in, &b);
-	if(len < 0) goto err;
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
 
-	p=(unsigned char *)b->data;
-	ret=d2i(x,&p,len);
-err:
-	if (b != NULL) BUF_MEM_free(b);
-	return(ret);
-	}
+    p = (unsigned char *)b->data;
+    ret = d2i(x, &p, len);
+ err:
+    if (b != NULL)
+        BUF_MEM_free(b);
+    return (ret);
+}
 
 #endif
 
 void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
-	{
-	BUF_MEM *b = NULL;
-	const unsigned char *p;
-	void *ret=NULL;
-	int len;
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
 
-	len = asn1_d2i_read_bio(in, &b);
-	if(len < 0) goto err;
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
 
-	p=(const unsigned char *)b->data;
-	ret=ASN1_item_d2i(x,&p,len, it);
-err:
-	if (b != NULL) BUF_MEM_free(b);
-	return(ret);
-	}
+    p = (const unsigned char *)b->data;
+    ret = ASN1_item_d2i(x, &p, len, it);
+ err:
+    if (b != NULL)
+        BUF_MEM_free(b);
+    return (ret);
+}
 
 #ifndef OPENSSL_NO_FP_API
 void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
-        {
-        BIO *b;
-        char *ret;
+{
+    BIO *b;
+    char *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
-                return(NULL);
-		}
-        BIO_set_fp(b,in,BIO_NOCLOSE);
-        ret=ASN1_item_d2i_bio(it,b,x);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+        return (NULL);
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_item_d2i_bio(it, b, x);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 #define HEADER_SIZE   8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
 static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
-	{
-	BUF_MEM *b;
-	unsigned char *p;
-	int i;
-	ASN1_const_CTX c;
-	size_t want=HEADER_SIZE;
-	int eos=0;
-	size_t off=0;
-	size_t len=0;
+{
+    BUF_MEM *b;
+    unsigned char *p;
+    int i;
+    ASN1_const_CTX c;
+    size_t want = HEADER_SIZE;
+    int eos = 0;
+    size_t off = 0;
+    size_t len = 0;
 
-	b=BUF_MEM_new();
-	if (b == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return -1;
-		}
+    b = BUF_MEM_new();
+    if (b == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
 
-	ERR_clear_error();
-	for (;;)
-		{
-		if (want >= (len-off))
-			{
-			want-=(len-off);
+    ERR_clear_error();
+    for (;;) {
+        if (want >= (len - off)) {
+            want -= (len - off);
 
-			if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			i=BIO_read(in,&(b->data[len]),want);
-			if ((i < 0) && ((len-off) == 0))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
-				goto err;
-				}
-			if (i > 0)
-				{
-				if (len+i < len)
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-					goto err;
-					}
-				len+=i;
-				}
-			}
-		/* else data already loaded */
+            if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            i = BIO_read(in, &(b->data[len]), want);
+            if ((i < 0) && ((len - off) == 0)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
+                goto err;
+            }
+            if (i > 0) {
+                if (len + i < len) {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                len += i;
+            }
+        }
+        /* else data already loaded */
 
-		p=(unsigned char *)&(b->data[off]);
-		c.p=p;
-		c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
-			len-off);
-		if (c.inf & 0x80)
-			{
-			uint32_t e;
+        p = (unsigned char *)&(b->data[off]);
+        c.p = p;
+        c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
+                                len - off);
+        if (c.inf & 0x80) {
+            uint32_t e;
 
-			e=ERR_GET_REASON(ERR_peek_error());
-			if (e != ASN1_R_TOO_LONG)
-				goto err;
-			else
-				ERR_clear_error(); /* clear error */
-			}
-		i=c.p-p;/* header length */
-		off+=i;	/* end of data */
+            e = ERR_GET_REASON(ERR_peek_error());
+            if (e != ASN1_R_TOO_LONG)
+                goto err;
+            else
+                ERR_clear_error(); /* clear error */
+        }
+        i = c.p - p;            /* header length */
+        off += i;               /* end of data */
 
-		if (c.inf & 1)
-			{
-			/* no data body so go round again */
-			eos++;
-			if (eos < 0)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
-				goto err;
-				}
-			want=HEADER_SIZE;
-			}
-		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
-			{
-			/* eos value, so go back and read another header */
-			eos--;
-			if (eos <= 0)
-				break;
-			else
-				want=HEADER_SIZE;
-			}
-		else 
-			{
-			/* suck in c.slen bytes of data */
-			want=c.slen;
-			if (want > (len-off))
-				{
-				want-=(len-off);
-				if (want > INT_MAX /* BIO_read takes an int length */ ||
-					len+want < len)
-						{
-						OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-						goto err;
-						}
-				if (!BUF_MEM_grow_clean(b,len+want))
-					{
-					OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-					goto err;
-					}
-				while (want > 0)
-					{
-					i=BIO_read(in,&(b->data[len]),want);
-					if (i <= 0)
-						{
-						OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
-						goto err;
-						}
-					/* This can't overflow because
-					 * |len+want| didn't overflow. */
-					len+=i;
-					want-=i;
-					}
-				}
-			if (off + c.slen < off)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-				goto err;
-				}
-			off+=c.slen;
-			if (eos <= 0)
-				{
-				break;
-				}
-			else
-				want=HEADER_SIZE;
-			}
-		}
+        if (c.inf & 1) {
+            /* no data body so go round again */
+            eos++;
+            if (eos < 0) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
+                goto err;
+            }
+            want = HEADER_SIZE;
+        } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
+            /* eos value, so go back and read another header */
+            eos--;
+            if (eos <= 0)
+                break;
+            else
+                want = HEADER_SIZE;
+        } else {
+            /* suck in c.slen bytes of data */
+            want = c.slen;
+            if (want > (len - off)) {
+                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+                want -= (len - off);
+                if (want > INT_MAX /* BIO_read takes an int length */  ||
+                    len + want < len) {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                while (want > 0) {
+                    /*
+                     * Read content in chunks of increasing size
+                     * so we can return an error for EOF without
+                     * having to allocate the entire content length
+                     * in one go.
+                     */
+                    size_t chunk = want > chunk_max ? chunk_max : want;
 
-	if (off > INT_MAX)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-		goto err;
-		}
+                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
+                        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                        goto err;
+                    }
+                    want -= chunk;
+                    while (chunk > 0) {
+                        i = BIO_read(in, &(b->data[len]), chunk);
+                        if (i <= 0) {
+                            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
+                            goto err;
+                        }
+                        /*
+                         * This can't overflow because |len+want| didn't
+                         * overflow.
+                         */
+                        len += i;
+                        chunk -= i;
+                    }
+                    if (chunk_max < INT_MAX/2)
+                        chunk_max *= 2;
+                }
+            }
+            if (off + c.slen < off) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+                goto err;
+            }
+            off += c.slen;
+            if (eos <= 0) {
+                break;
+            } else
+                want = HEADER_SIZE;
+        }
+    }
 
-	*pb = b;
-	return off;
-err:
-	if (b != NULL) BUF_MEM_free(b);
-	return -1;
-	}
+    if (off > INT_MAX) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+        goto err;
+    }
+
+    *pb = b;
+    return off;
+ err:
+    if (b != NULL)
+        BUF_MEM_free(b);
+    return -1;
+}
diff --git a/src/crypto/asn1/a_dup.c b/src/crypto/asn1/a_dup.c
index 5e87457..57394f5 100644
--- a/src/crypto/asn1/a_dup.c
+++ b/src/crypto/asn1/a_dup.c
@@ -59,45 +59,53 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
-	{
-	unsigned char *b,*p;
-	const unsigned char *p2;
-	int i;
-	char *ret;
+{
+    unsigned char *b, *p;
+    const unsigned char *p2;
+    int i;
+    char *ret;
 
-	if (x == NULL) return(NULL);
+    if (x == NULL)
+        return (NULL);
 
-	i=i2d(x,NULL);
-	b=OPENSSL_malloc(i+10);
-	if (b == NULL)
-		{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
-	p= b;
-	i=i2d(x,&p);
-	p2= b;
-	ret=d2i(NULL,&p2,i);
-	OPENSSL_free(b);
-	return(ret);
-	}
+    i = i2d(x, NULL);
+    b = OPENSSL_malloc(i + 10);
+    if (b == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    p = b;
+    i = i2d(x, &p);
+    p2 = b;
+    ret = d2i(NULL, &p2, i);
+    OPENSSL_free(b);
+    return (ret);
+}
 
-/* ASN1_ITEM version of dup: this follows the model above except we don't need
- * to allocate the buffer. At some point this could be rewritten to directly dup
- * the underlying structure instead of doing and encode and decode. */
+/*
+ * ASN1_ITEM version of dup: this follows the model above except we don't
+ * need to allocate the buffer. At some point this could be rewritten to
+ * directly dup the underlying structure instead of doing and encode and
+ * decode.
+ */
 void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
-	{
-	unsigned char *b = NULL;
-	const unsigned char *p;
-	long i;
-	void *ret;
+{
+    unsigned char *b = NULL;
+    const unsigned char *p;
+    long i;
+    void *ret;
 
-	if (x == NULL) return(NULL);
+    if (x == NULL)
+        return (NULL);
 
-	i=ASN1_item_i2d(x,&b,it);
-	if (b == NULL)
-		{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
-	p= b;
-	ret=ASN1_item_d2i(NULL,&p,i, it);
-	OPENSSL_free(b);
-	return(ret);
-	}
+    i = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    p = b;
+    ret = ASN1_item_d2i(NULL, &p, i, it);
+    OPENSSL_free(b);
+    return (ret);
+}
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index 579dafd..0b95fc9 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -61,123 +61,121 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
-/* 
+/*
  * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
  * for comments on encoding see a_int.c
  */
 
 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
-	{
-	int j,k;
-	unsigned int i;
-	unsigned char buf[sizeof(long)+1];
-	long d;
+{
+    int j, k;
+    unsigned int i;
+    unsigned char buf[sizeof(long) + 1];
+    long d;
 
-	a->type=V_ASN1_ENUMERATED;
-	if (a->length < (int)(sizeof(long)+1))
-		{
-		if (a->data != NULL)
-			OPENSSL_free(a->data);
-		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
-			memset((char *)a->data,0,sizeof(long)+1);
-		}
-	if (a->data == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	d=v;
-	if (d < 0)
-		{
-		d= -d;
-		a->type=V_ASN1_NEG_ENUMERATED;
-		}
+    a->type = V_ASN1_ENUMERATED;
+    if (a->length < (int)(sizeof(long) + 1)) {
+        if (a->data != NULL)
+            OPENSSL_free(a->data);
+        if ((a->data =
+             (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+            memset((char *)a->data, 0, sizeof(long) + 1);
+    }
+    if (a->data == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    d = v;
+    if (d < 0) {
+        d = -d;
+        a->type = V_ASN1_NEG_ENUMERATED;
+    }
 
-	for (i=0; i<sizeof(long); i++)
-		{
-		if (d == 0) break;
-		buf[i]=(int)d&0xff;
-		d>>=8;
-		}
-	j=0;
-	for (k=i-1; k >=0; k--)
-		a->data[j++]=buf[k];
-	a->length=j;
-	return(1);
-	}
+    for (i = 0; i < sizeof(long); i++) {
+        if (d == 0)
+            break;
+        buf[i] = (int)d & 0xff;
+        d >>= 8;
+    }
+    j = 0;
+    for (k = i - 1; k >= 0; k--)
+        a->data[j++] = buf[k];
+    a->length = j;
+    return (1);
+}
 
 long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
-	{
-	int neg=0,i;
-	long r=0;
+{
+    int neg = 0, i;
+    long r = 0;
 
-	if (a == NULL) return(0L);
-	i=a->type;
-	if (i == V_ASN1_NEG_ENUMERATED)
-		neg=1;
-	else if (i != V_ASN1_ENUMERATED)
-		return -1;
-	
-	if (a->length > (int)sizeof(long))
-		{
-		/* hmm... a bit ugly */
-		return(0xffffffffL);
-		}
-	if (a->data == NULL)
-		return 0;
+    if (a == NULL)
+        return (0L);
+    i = a->type;
+    if (i == V_ASN1_NEG_ENUMERATED)
+        neg = 1;
+    else if (i != V_ASN1_ENUMERATED)
+        return -1;
 
-	for (i=0; i<a->length; i++)
-		{
-		r<<=8;
-		r|=(unsigned char)a->data[i];
-		}
-	if (neg) r= -r;
-	return(r);
-	}
+    if (a->length > (int)sizeof(long)) {
+        /* hmm... a bit ugly */
+        return (0xffffffffL);
+    }
+    if (a->data == NULL)
+        return 0;
+
+    for (i = 0; i < a->length; i++) {
+        r <<= 8;
+        r |= (unsigned char)a->data[i];
+    }
+    if (neg)
+        r = -r;
+    return (r);
+}
 
 ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
-	{
-	ASN1_ENUMERATED *ret;
-	int len,j;
+{
+    ASN1_ENUMERATED *ret;
+    int len, j;
 
-	if (ai == NULL)
-		ret=M_ASN1_ENUMERATED_new();
-	else
-		ret=ai;
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-		goto err;
-		}
-	if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
-	else ret->type=V_ASN1_ENUMERATED;
-	j=BN_num_bits(bn);
-	len=((j == 0)?0:((j/8)+1));
-	if (ret->length < len+4)
-		{
-		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
-		if (!new_data)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		ret->data=new_data;
-		}
+    if (ai == NULL)
+        ret = M_ASN1_ENUMERATED_new();
+    else
+        ret = ai;
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+        goto err;
+    }
+    if (BN_is_negative(bn))
+        ret->type = V_ASN1_NEG_ENUMERATED;
+    else
+        ret->type = V_ASN1_ENUMERATED;
+    j = BN_num_bits(bn);
+    len = ((j == 0) ? 0 : ((j / 8) + 1));
+    if (ret->length < len + 4) {
+        unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+        if (!new_data) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ret->data = new_data;
+    }
 
-	ret->length=BN_bn2bin(bn,ret->data);
-	return(ret);
-err:
-	if (ret != ai) M_ASN1_ENUMERATED_free(ret);
-	return(NULL);
-	}
+    ret->length = BN_bn2bin(bn, ret->data);
+    return (ret);
+ err:
+    if (ret != ai)
+        M_ASN1_ENUMERATED_free(ret);
+    return (NULL);
+}
 
 BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
-	{
-	BIGNUM *ret;
+{
+    BIGNUM *ret;
 
-	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
-	else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
-	return(ret);
-	}
+    if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
+    else if (ai->type == V_ASN1_NEG_ENUMERATED)
+        BN_set_negative(ret, 1);
+    return (ret);
+}
diff --git a/src/crypto/asn1/a_gentm.c b/src/crypto/asn1/a_gentm.c
index 7cb18a9..ee6b3db 100644
--- a/src/crypto/asn1/a_gentm.c
+++ b/src/crypto/asn1/a_gentm.c
@@ -63,193 +63,194 @@
 #include <openssl/mem.h>
 #include <openssl/time_support.h>
 
+#include "asn1_locl.h"
 
 int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
-	{
-	static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
-	static const int max[9]={99, 99,12,31,23,59,59,12,59};
-	char *a;
-	int n,i,l,o;
+{
+    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+    char *a;
+    int n, i, l, o;
 
-	if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
-	l=d->length;
-	a=(char *)d->data;
-	o=0;
-	/* GENERALIZEDTIME is similar to UTCTIME except the year is
-         * represented as YYYY. This stuff treats everything as a two digit
-         * field so make first two fields 00 to 99
-         */
-	if (l < 13) goto err;
-	for (i=0; i<7; i++)
-		{
-		if ((i == 6) && ((a[o] == 'Z') ||
-			(a[o] == '+') || (a[o] == '-')))
-			{
-			i++;
-			if (tm)
-				tm->tm_sec = 0;
-			break;
-			}
-		if ((a[o] < '0') || (a[o] > '9')) goto err;
-		n= a[o]-'0';
-		if (++o > l) goto err;
+    if (d->type != V_ASN1_GENERALIZEDTIME)
+        return (0);
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
+    /*
+     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+     * as YYYY. This stuff treats everything as a two digit field so make
+     * first two fields 00 to 99
+     */
+    if (l < 13)
+        goto err;
+    for (i = 0; i < 7; i++) {
+        if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+            i++;
+            if (tm)
+                tm->tm_sec = 0;
+            break;
+        }
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = a[o] - '0';
+        if (++o > l)
+            goto err;
 
-		if ((a[o] < '0') || (a[o] > '9')) goto err;
-		n=(n*10)+ a[o]-'0';
-		if (++o > l) goto err;
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = (n * 10) + a[o] - '0';
+        if (++o > l)
+            goto err;
 
-		if ((n < min[i]) || (n > max[i])) goto err;
-		if (tm)
-			{
-			switch(i)
-				{
-			case 0:
-				tm->tm_year = n * 100 - 1900;
-				break;
-			case 1:
-				tm->tm_year += n;
-				break;
-			case 2:
-				tm->tm_mon = n - 1;
-				break;
-			case 3:
-				tm->tm_mday = n;
-				break;
-			case 4:
-				tm->tm_hour = n;
-				break;
-			case 5:
-				tm->tm_min = n;
-				break;
-			case 6:
-				tm->tm_sec = n;
-				break;
-				}
-			}
-		}
-	/* Optional fractional seconds: decimal point followed by one
-	 * or more digits.
-	 */
-	if (a[o] == '.')
-		{
-		if (++o > l) goto err;
-		i = o;
-		while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
-			o++;
-		/* Must have at least one digit after decimal point */
-		if (i == o) goto err;
-		}
+        if ((n < min[i]) || (n > max[i]))
+            goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n * 100 - 1900;
+                break;
+            case 1:
+                tm->tm_year += n;
+                break;
+            case 2:
+                tm->tm_mon = n - 1;
+                break;
+            case 3:
+                tm->tm_mday = n;
+                break;
+            case 4:
+                tm->tm_hour = n;
+                break;
+            case 5:
+                tm->tm_min = n;
+                break;
+            case 6:
+                tm->tm_sec = n;
+                break;
+            }
+        }
+    }
+    /*
+     * Optional fractional seconds: decimal point followed by one or more
+     * digits.
+     */
+    if (a[o] == '.') {
+        if (++o > l)
+            goto err;
+        i = o;
+        while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+            o++;
+        /* Must have at least one digit after decimal point */
+        if (i == o)
+            goto err;
+    }
 
-	if (a[o] == 'Z')
-		o++;
-	else if ((a[o] == '+') || (a[o] == '-'))
-		{
-		int offsign = a[o] == '-' ? -1 : 1, offset = 0;
-		o++;
-		if (o+4 > l) goto err;
-		for (i=7; i<9; i++)
-			{
-			if ((a[o] < '0') || (a[o] > '9')) goto err;
-			n= a[o]-'0';
-			o++;
-			if ((a[o] < '0') || (a[o] > '9')) goto err;
-			n=(n*10)+ a[o]-'0';
-			if ((n < min[i]) || (n > max[i])) goto err;
-			if (tm)
-				{
-				if (i == 7)
-					offset = n * 3600;
-				else if (i == 8)
-					offset += n * 60;
-				}
-			o++;
-			}
-		if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
-			return 0;
-		}
-	else if (a[o])
-		{
-		/* Missing time zone information. */
-		goto err;
-		}
-	return(o == l);
-err:
-	return(0);
-	}
+    if (a[o] == 'Z')
+        o++;
+    else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+        o++;
+        if (o + 4 > l)
+            goto err;
+        for (i = 7; i < 9; i++) {
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = a[o] - '0';
+            o++;
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = (n * 10) + a[o] - '0';
+            if ((n < min[i]) || (n > max[i]))
+                goto err;
+            if (tm) {
+                if (i == 7)
+                    offset = n * 3600;
+                else if (i == 8)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
+    } else if (a[o]) {
+        /* Missing time zone information. */
+        goto err;
+    }
+    return (o == l);
+ err:
+    return (0);
+}
 
 int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
-	{
-	return asn1_generalizedtime_to_tm(NULL, d);
-	}
+{
+    return asn1_generalizedtime_to_tm(NULL, d);
+}
 
 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
-	{
-	ASN1_GENERALIZEDTIME t;
+{
+    ASN1_GENERALIZEDTIME t;
 
-	t.type=V_ASN1_GENERALIZEDTIME;
-	t.length=strlen(str);
-	t.data=(unsigned char *)str;
-	if (ASN1_GENERALIZEDTIME_check(&t))
-		{
-		if (s != NULL)
-			{
-			if (!ASN1_STRING_set((ASN1_STRING *)s,
-				(unsigned char *)str,t.length))
-				return 0;
-			s->type=V_ASN1_GENERALIZEDTIME;
-			}
-		return(1);
-		}
-	else
-		return(0);
-	}
+    t.type = V_ASN1_GENERALIZEDTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    if (ASN1_GENERALIZEDTIME_check(&t)) {
+        if (s != NULL) {
+            if (!ASN1_STRING_set((ASN1_STRING *)s,
+                                 (unsigned char *)str, t.length))
+                return 0;
+            s->type = V_ASN1_GENERALIZEDTIME;
+        }
+        return (1);
+    } else
+        return (0);
+}
 
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
-	     time_t t)
-	{
-		return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
-	}
+                                               time_t t)
+{
+    return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+}
 
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
-	     time_t t, int offset_day, long offset_sec)
-	{
-	char *p;
-	struct tm *ts;
-	struct tm data;
-	size_t len = 20; 
+                                               time_t t, int offset_day,
+                                               long offset_sec)
+{
+    char *p;
+    struct tm *ts;
+    struct tm data;
+    size_t len = 20;
 
-	if (s == NULL)
-		s=M_ASN1_GENERALIZEDTIME_new();
-	if (s == NULL)
-		return(NULL);
+    if (s == NULL)
+        s = M_ASN1_GENERALIZEDTIME_new();
+    if (s == NULL)
+        return (NULL);
 
-	ts=OPENSSL_gmtime(&t, &data);
-	if (ts == NULL)
-		return(NULL);
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        return (NULL);
 
-	if (offset_day || offset_sec)
-		{ 
-		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-			return NULL;
-		}
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
 
-	p=(char *)s->data;
-	if ((p == NULL) || ((size_t)s->length < len))
-		{
-		p=OPENSSL_malloc(len);
-		if (p == NULL)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return(NULL);
-			}
-		if (s->data != NULL)
-			OPENSSL_free(s->data);
-		s->data=(unsigned char *)p;
-		}
+    p = (char *)s->data;
+    if ((p == NULL) || ((size_t)s->length < len)) {
+        p = OPENSSL_malloc(len);
+        if (p == NULL) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        if (s->data != NULL)
+            OPENSSL_free(s->data);
+        s->data = (unsigned char *)p;
+    }
 
-	BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
-		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
-	s->length=strlen(p);
-	s->type=V_ASN1_GENERALIZEDTIME;
-	return(s);
-	}
+    BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+                 ts->tm_sec);
+    s->length = strlen(p);
+    s->type = V_ASN1_GENERALIZEDTIME;
+    return (s);
+}
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 74ded78..486207e 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -59,96 +59,89 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
-        {
-        BIO *b;
-        int ret;
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,out,BIO_NOCLOSE);
-        ret=ASN1_i2d_bio(i2d,b,x);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_i2d_bio(i2d, b, x);
+    BIO_free(b);
+    return (ret);
+}
 
 int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
-	{
-	char *b;
-	unsigned char *p;
-	int i,j=0,n,ret=1;
+{
+    char *b;
+    unsigned char *p;
+    int i, j = 0, n, ret = 1;
 
-	n=i2d(x,NULL);
-	b=(char *)OPENSSL_malloc(n);
-	if (b == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
+    n = i2d(x, NULL);
+    b = (char *)OPENSSL_malloc(n);
+    if (b == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
 
-	p=(unsigned char *)b;
-	i2d(x,&p);
-	
-	for (;;)
-		{
-		i=BIO_write(out,&(b[j]),n);
-		if (i == n) break;
-		if (i <= 0)
-			{
-			ret=0;
-			break;
-			}
-		j+=i;
-		n-=i;
-		}
-	OPENSSL_free(b);
-	return(ret);
-	}
+    p = (unsigned char *)b;
+    i2d(x, &p);
+
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return (ret);
+}
 
 int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
-        {
-        BIO *b;
-        int ret;
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,out,BIO_NOCLOSE);
-        ret=ASN1_item_i2d_bio(it,b,x);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_item_i2d_bio(it, b, x);
+    BIO_free(b);
+    return (ret);
+}
 
 int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
-	{
-	unsigned char *b = NULL;
-	int i,j=0,n,ret=1;
+{
+    unsigned char *b = NULL;
+    int i, j = 0, n, ret = 1;
 
-	n = ASN1_item_i2d(x, &b, it);
-	if (b == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
+    n = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
 
-	for (;;)
-		{
-		i=BIO_write(out,&(b[j]),n);
-		if (i == n) break;
-		if (i <= 0)
-			{
-			ret=0;
-			break;
-			}
-		j+=i;
-		n-=i;
-		}
-	OPENSSL_free(b);
-	return(ret);
-	}
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return (ret);
+}
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 9a56534..38a01bc 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -61,47 +61,46 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
-{ return M_ASN1_INTEGER_dup(x);}
+{
+    return M_ASN1_INTEGER_dup(x);
+}
 
 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
-	{ 
-	int neg, ret;
-	/* Compare signs */
-	neg = x->type & V_ASN1_NEG;
-	if (neg != (y->type & V_ASN1_NEG))
-		{
-		if (neg)
-			return -1;
-		else
-			return 1;
-		}
+{
+    int neg, ret;
+    /* Compare signs */
+    neg = x->type & V_ASN1_NEG;
+    if (neg != (y->type & V_ASN1_NEG)) {
+        if (neg)
+            return -1;
+        else
+            return 1;
+    }
 
-	ret = ASN1_STRING_cmp(x, y);
+    ret = ASN1_STRING_cmp(x, y);
 
-	if (neg)
-		return -ret;
-	else
-		return ret;
-	}
-	
+    if (neg)
+        return -ret;
+    else
+        return ret;
+}
 
-/* 
+/*
  * This converts an ASN1 INTEGER into its content encoding.
  * The internal representation is an ASN1_STRING whose data is a big endian
  * representation of the value, ignoring the sign. The sign is determined by
- * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. 
+ * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
  *
  * Positive integers are no problem: they are almost the same as the DER
  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
  *
  * Negative integers are a bit trickier...
  * The DER representation of negative integers is in 2s complement form.
- * The internal form is converted by complementing each octet and finally 
+ * The internal form is converted by complementing each octet and finally
  * adding one to the result. This can be done less messily with a little trick.
  * If the internal form has trailing zeroes then they will become FF by the
- * complement and 0 by the add one (due to carry) so just copy as many trailing 
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
  * zeros to the destination as there are in the source. The carry will add one
  * to the last none zero octet: so complement this octet and add one and finally
  * complement any left over until you get to the start of the string.
@@ -113,344 +112,349 @@
  */
 
 int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
-	{
-	int pad=0,ret,i,neg;
-	unsigned char *p,*n,pb=0;
+{
+    int pad = 0, ret, i, neg;
+    unsigned char *p, *n, pb = 0;
 
-	if (a == NULL) return(0);
-	neg=a->type & V_ASN1_NEG;
-	if (a->length == 0)
-		ret=1;
-	else
-		{
-		ret=a->length;
-		i=a->data[0];
-		if (!neg && (i > 127)) {
-			pad=1;
-			pb=0;
-		} else if(neg) {
-			if(i>128) {
-				pad=1;
-				pb=0xFF;
-			} else if(i == 128) {
-			/*
-			 * Special case: if any other bytes non zero we pad:
-			 * otherwise we don't.
-			 */
-				for(i = 1; i < a->length; i++) if(a->data[i]) {
-						pad=1;
-						pb=0xFF;
-						break;
-				}
-			}
-		}
-		ret+=pad;
-		}
-	if (pp == NULL) return(ret);
-	p= *pp;
+    if (a == NULL)
+        return (0);
+    neg = a->type & V_ASN1_NEG;
+    if (a->length == 0)
+        ret = 1;
+    else {
+        ret = a->length;
+        i = a->data[0];
+        if (ret == 1 && i == 0)
+            neg = 0;
+        if (!neg && (i > 127)) {
+            pad = 1;
+            pb = 0;
+        } else if (neg) {
+            if (i > 128) {
+                pad = 1;
+                pb = 0xFF;
+            } else if (i == 128) {
+                /*
+                 * Special case: if any other bytes non zero we pad:
+                 * otherwise we don't.
+                 */
+                for (i = 1; i < a->length; i++)
+                    if (a->data[i]) {
+                        pad = 1;
+                        pb = 0xFF;
+                        break;
+                    }
+            }
+        }
+        ret += pad;
+    }
+    if (pp == NULL)
+        return (ret);
+    p = *pp;
 
-	if (pad) *(p++)=pb;
-	if (a->length == 0) *(p++)=0;
-	else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
-	else {
-		/* Begin at the end of the encoding */
-		n=a->data + a->length - 1;
-		p += a->length - 1;
-		i = a->length;
-		/* Copy zeros to destination as long as source is zero */
-		while(!*n) {
-			*(p--) = 0;
-			n--;
-			i--;
-		}
-		/* Complement and increment next octet */
-		*(p--) = ((*(n--)) ^ 0xff) + 1;
-		i--;
-		/* Complement any octets left */
-		for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
-	}
+    if (pad)
+        *(p++) = pb;
+    if (a->length == 0)
+        *(p++) = 0;
+    else if (!neg)
+        memcpy(p, a->data, (unsigned int)a->length);
+    else {
+        /* Begin at the end of the encoding */
+        n = a->data + a->length - 1;
+        p += a->length - 1;
+        i = a->length;
+        /* Copy zeros to destination as long as source is zero */
+        while (!*n && i > 1) {
+            *(p--) = 0;
+            n--;
+            i--;
+        }
+        /* Complement and increment next octet */
+        *(p--) = ((*(n--)) ^ 0xff) + 1;
+        i--;
+        /* Complement any octets left */
+        for (; i > 0; i--)
+            *(p--) = *(n--) ^ 0xff;
+    }
 
-	*pp+=ret;
-	return(ret);
-	}
+    *pp += ret;
+    return (ret);
+}
 
 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
 
 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
-	     long len)
-	{
-	ASN1_INTEGER *ret=NULL;
-	const unsigned char *p, *pend;
-	unsigned char *to,*s;
-	int i;
+                               long len)
+{
+    ASN1_INTEGER *ret = NULL;
+    const unsigned char *p, *pend;
+    unsigned char *to, *s;
+    int i;
 
-	if ((a == NULL) || ((*a) == NULL))
-		{
-		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
-		ret->type=V_ASN1_INTEGER;
-		}
-	else
-		ret=(*a);
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = M_ASN1_INTEGER_new()) == NULL)
+            return (NULL);
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = (*a);
 
-	p= *pp;
-	pend = p + len;
+    p = *pp;
+    pend = p + len;
 
-	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
-	 * signifies a missing NULL parameter. */
-	s=(unsigned char *)OPENSSL_malloc((int)len+1);
-	if (s == NULL)
-		{
-		i=ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
-	to=s;
-	if(!len) {
-		/* Strictly speaking this is an illegal INTEGER but we
-		 * tolerate it.
-		 */
-		ret->type=V_ASN1_INTEGER;
-	} else if (*p & 0x80) /* a negative number */
-		{
-		ret->type=V_ASN1_NEG_INTEGER;
-		if ((*p == 0xff) && (len != 1)) {
-			p++;
-			len--;
-		}
-		i = len;
-		p += i - 1;
-		to += i - 1;
-		while((!*p) && i) {
-			*(to--) = 0;
-			i--;
-			p--;
-		}
-		/* Special case: if all zeros then the number will be of
-		 * the form FF followed by n zero bytes: this corresponds to
-		 * 1 followed by n zero bytes. We've already written n zeros
-		 * so we just append an extra one and set the first byte to
-		 * a 1. This is treated separately because it is the only case
-		 * where the number of bytes is larger than len.
-		 */
-		if(!i) {
-			*s = 1;
-			s[len] = 0;
-			len++;
-		} else {
-			*(to--) = (*(p--) ^ 0xff) + 1;
-			i--;
-			for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
-		}
-	} else {
-		ret->type=V_ASN1_INTEGER;
-		if ((*p == 0) && (len != 1))
-			{
-			p++;
-			len--;
-			}
-		memcpy(s,p,(int)len);
-	}
+    /*
+     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+     * a missing NULL parameter.
+     */
+    s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+    if (s == NULL) {
+        i = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+    to = s;
+    if (!len) {
+        /*
+         * Strictly speaking this is an illegal INTEGER but we tolerate it.
+         */
+        ret->type = V_ASN1_INTEGER;
+    } else if (*p & 0x80) {     /* a negative number */
+        ret->type = V_ASN1_NEG_INTEGER;
+        if ((*p == 0xff) && (len != 1)) {
+            p++;
+            len--;
+        }
+        i = len;
+        p += i - 1;
+        to += i - 1;
+        while ((!*p) && i) {
+            *(to--) = 0;
+            i--;
+            p--;
+        }
+        /*
+         * Special case: if all zeros then the number will be of the form FF
+         * followed by n zero bytes: this corresponds to 1 followed by n zero
+         * bytes. We've already written n zeros so we just append an extra
+         * one and set the first byte to a 1. This is treated separately
+         * because it is the only case where the number of bytes is larger
+         * than len.
+         */
+        if (!i) {
+            *s = 1;
+            s[len] = 0;
+            len++;
+        } else {
+            *(to--) = (*(p--) ^ 0xff) + 1;
+            i--;
+            for (; i > 0; i--)
+                *(to--) = *(p--) ^ 0xff;
+        }
+    } else {
+        ret->type = V_ASN1_INTEGER;
+        if ((*p == 0) && (len != 1)) {
+            p++;
+            len--;
+        }
+        memcpy(s, p, (int)len);
+    }
 
-	if (ret->data != NULL) OPENSSL_free(ret->data);
-	ret->data=s;
-	ret->length=(int)len;
-	if (a != NULL) (*a)=ret;
-	*pp=pend;
-	return(ret);
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		M_ASN1_INTEGER_free(ret);
-	return(NULL);
-	}
+    if (ret->data != NULL)
+        OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->length = (int)len;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = pend;
+    return (ret);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        M_ASN1_INTEGER_free(ret);
+    return (NULL);
+}
 
-
-/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
- * ASN1 integers: some broken software can encode a positive INTEGER
- * with its MSB set as negative (it doesn't add a padding zero).
+/*
+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
+ * integers: some broken software can encode a positive INTEGER with its MSB
+ * set as negative (it doesn't add a padding zero).
  */
 
 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
-	     long length)
-	{
-	ASN1_INTEGER *ret=NULL;
-	const unsigned char *p;
-	unsigned char *s;
-	long len;
-	int inf,tag,xclass;
-	int i;
+                                long length)
+{
+    ASN1_INTEGER *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    long len;
+    int inf, tag, xclass;
+    int i;
 
-	if ((a == NULL) || ((*a) == NULL))
-		{
-		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
-		ret->type=V_ASN1_INTEGER;
-		}
-	else
-		ret=(*a);
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = M_ASN1_INTEGER_new()) == NULL)
+            return (NULL);
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = (*a);
 
-	p= *pp;
-	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
-	if (inf & 0x80)
-		{
-		i=ASN1_R_BAD_OBJECT_HEADER;
-		goto err;
-		}
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
 
-	if (tag != V_ASN1_INTEGER)
-		{
-		i=ASN1_R_EXPECTING_AN_INTEGER;
-		goto err;
-		}
+    if (tag != V_ASN1_INTEGER) {
+        i = ASN1_R_EXPECTING_AN_INTEGER;
+        goto err;
+    }
 
-	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
-	 * signifies a missing NULL parameter. */
-	s=(unsigned char *)OPENSSL_malloc((int)len+1);
-	if (s == NULL)
-		{
-		i=ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
-	ret->type=V_ASN1_INTEGER;
-	if(len) {
-		if ((*p == 0) && (len != 1))
-			{
-			p++;
-			len--;
-			}
-		memcpy(s,p,(int)len);
-		p+=len;
-	}
+    /*
+     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+     * a missing NULL parameter.
+     */
+    s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+    if (s == NULL) {
+        i = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+    ret->type = V_ASN1_INTEGER;
+    if (len) {
+        if ((*p == 0) && (len != 1)) {
+            p++;
+            len--;
+        }
+        memcpy(s, p, (int)len);
+        p += len;
+    }
 
-	if (ret->data != NULL) OPENSSL_free(ret->data);
-	ret->data=s;
-	ret->length=(int)len;
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		M_ASN1_INTEGER_free(ret);
-	return(NULL);
-	}
+    if (ret->data != NULL)
+        OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->length = (int)len;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        M_ASN1_INTEGER_free(ret);
+    return (NULL);
+}
 
 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
-	{
-	int j,k;
-	unsigned int i;
-	unsigned char buf[sizeof(long)+1];
-	long d;
+{
+    int j, k;
+    unsigned int i;
+    unsigned char buf[sizeof(long) + 1];
+    long d;
 
-	a->type=V_ASN1_INTEGER;
-	if (a->length < (int)(sizeof(long)+1))
-		{
-		if (a->data != NULL)
-			OPENSSL_free(a->data);
-		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
-			memset((char *)a->data,0,sizeof(long)+1);
-		}
-	if (a->data == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	d=v;
-	if (d < 0)
-		{
-		d= -d;
-		a->type=V_ASN1_NEG_INTEGER;
-		}
+    a->type = V_ASN1_INTEGER;
+    if (a->length < (int)(sizeof(long) + 1)) {
+        if (a->data != NULL)
+            OPENSSL_free(a->data);
+        if ((a->data =
+             (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+            memset((char *)a->data, 0, sizeof(long) + 1);
+    }
+    if (a->data == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    d = v;
+    if (d < 0) {
+        d = -d;
+        a->type = V_ASN1_NEG_INTEGER;
+    }
 
-	for (i=0; i<sizeof(long); i++)
-		{
-		if (d == 0) break;
-		buf[i]=(int)d&0xff;
-		d>>=8;
-		}
-	j=0;
-	for (k=i-1; k >=0; k--)
-		a->data[j++]=buf[k];
-	a->length=j;
-	return(1);
-	}
+    for (i = 0; i < sizeof(long); i++) {
+        if (d == 0)
+            break;
+        buf[i] = (int)d & 0xff;
+        d >>= 8;
+    }
+    j = 0;
+    for (k = i - 1; k >= 0; k--)
+        a->data[j++] = buf[k];
+    a->length = j;
+    return (1);
+}
 
 long ASN1_INTEGER_get(const ASN1_INTEGER *a)
-	{
-	int neg=0,i;
-	long r=0;
+{
+    int neg = 0, i;
+    long r = 0;
 
-	if (a == NULL) return(0L);
-	i=a->type;
-	if (i == V_ASN1_NEG_INTEGER)
-		neg=1;
-	else if (i != V_ASN1_INTEGER)
-		return -1;
-	
-	if (a->length > (int)sizeof(long))
-		{
-		/* hmm... a bit ugly, return all ones */
-		return -1;
-		}
-	if (a->data == NULL)
-		return 0;
+    if (a == NULL)
+        return (0L);
+    i = a->type;
+    if (i == V_ASN1_NEG_INTEGER)
+        neg = 1;
+    else if (i != V_ASN1_INTEGER)
+        return -1;
 
-	for (i=0; i<a->length; i++)
-		{
-		r<<=8;
-		r|=(unsigned char)a->data[i];
-		}
-	if (neg) r= -r;
-	return(r);
-	}
+    if (a->length > (int)sizeof(long)) {
+        /* hmm... a bit ugly, return all ones */
+        return -1;
+    }
+    if (a->data == NULL)
+        return 0;
+
+    for (i = 0; i < a->length; i++) {
+        r <<= 8;
+        r |= (unsigned char)a->data[i];
+    }
+    if (neg)
+        r = -r;
+    return (r);
+}
 
 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
-	{
-	ASN1_INTEGER *ret;
-	int len,j;
+{
+    ASN1_INTEGER *ret;
+    int len, j;
 
-	if (ai == NULL)
-		ret=M_ASN1_INTEGER_new();
-	else
-		ret=ai;
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-		goto err;
-		}
-	if (BN_is_negative(bn) && !BN_is_zero(bn))
-		ret->type = V_ASN1_NEG_INTEGER;
-	else ret->type=V_ASN1_INTEGER;
-	j=BN_num_bits(bn);
-	len=((j == 0)?0:((j/8)+1));
-	if (ret->length < len+4)
-		{
-		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
-		if (!new_data)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		ret->data=new_data;
-		}
-	ret->length=BN_bn2bin(bn,ret->data);
-	/* Correct zero case */
-	if(!ret->length)
-		{
-		ret->data[0] = 0;
-		ret->length = 1;
-		}
-	return(ret);
-err:
-	if (ret != ai) M_ASN1_INTEGER_free(ret);
-	return(NULL);
-	}
+    if (ai == NULL)
+        ret = M_ASN1_INTEGER_new();
+    else
+        ret = ai;
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+        goto err;
+    }
+    if (BN_is_negative(bn) && !BN_is_zero(bn))
+        ret->type = V_ASN1_NEG_INTEGER;
+    else
+        ret->type = V_ASN1_INTEGER;
+    j = BN_num_bits(bn);
+    len = ((j == 0) ? 0 : ((j / 8) + 1));
+    if (ret->length < len + 4) {
+        unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+        if (!new_data) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ret->data = new_data;
+    }
+    ret->length = BN_bn2bin(bn, ret->data);
+    /* Correct zero case */
+    if (!ret->length) {
+        ret->data[0] = 0;
+        ret->length = 1;
+    }
+    return (ret);
+ err:
+    if (ret != ai)
+        M_ASN1_INTEGER_free(ret);
+    return (NULL);
+}
 
 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
-	{
-	BIGNUM *ret;
+{
+    BIGNUM *ret;
 
-	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
-	else if(ai->type == V_ASN1_NEG_INTEGER)
-		BN_set_negative(ret, 1);
-	return(ret);
-	}
+    if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
+    else if (ai->type == V_ASN1_NEG_INTEGER)
+        BN_set_negative(ret, 1);
+    return (ret);
+}
diff --git a/src/crypto/asn1/a_mbstr.c b/src/crypto/asn1/a_mbstr.c
index 42806d1..30fff82 100644
--- a/src/crypto/asn1/a_mbstr.c
+++ b/src/crypto/asn1/a_mbstr.c
@@ -61,9 +61,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 static int traverse_string(const unsigned char *p, int len, int inform,
-		 int (*rfunc)(unsigned long value, void *in), void *arg);
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg);
 static int in_utf8(unsigned long value, void *arg);
 static int out_utf8(unsigned long value, void *arg);
 static int type_str(unsigned long value, void *arg);
@@ -73,208 +73,219 @@
 static int cpy_utf8(unsigned long value, void *arg);
 static int is_printable(unsigned long value);
 
-/* These functions take a string in UTF8, ASCII or multibyte form and
- * a mask of permissible ASN1 string types. It then works out the minimal
- * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
- * and creates a string of the correct type with the supplied data.
- * Yes this is horrible: it has to be :-(
- * The 'ncopy' form checks minimum and maximum size limits too.
+/*
+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
+ * of permissible ASN1 string types. It then works out the minimal type
+ * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
+ * creates a string of the correct type with the supplied data. Yes this is
+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
+ * size limits too.
  */
 
 int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
-					int inform, unsigned long mask)
+                       int inform, unsigned long mask)
 {
-	return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
 }
 
 int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
-					int inform, unsigned long mask, 
-					long minsize, long maxsize)
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize)
 {
-	int str_type;
-	int ret;
-	char free_out;
-	int outform, outlen = 0;
-	ASN1_STRING *dest;
-	unsigned char *p;
-	int nchar;
-	char strbuf[32];
-	int (*cpyfunc)(unsigned long,void *) = NULL;
-	if(len == -1) len = strlen((const char *)in);
-	if(!mask) mask = DIRSTRING_TYPE;
+    int str_type;
+    int ret;
+    char free_out;
+    int outform, outlen = 0;
+    ASN1_STRING *dest;
+    unsigned char *p;
+    int nchar;
+    char strbuf[32];
+    int (*cpyfunc) (unsigned long, void *) = NULL;
+    if (len == -1)
+        len = strlen((const char *)in);
+    if (!mask)
+        mask = DIRSTRING_TYPE;
 
-	/* First do a string check and work out the number of characters */
-	switch(inform) {
+    /* First do a string check and work out the number of characters */
+    switch (inform) {
 
-		case MBSTRING_BMP:
-		if(len & 1) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
-			return -1;
-		}
-		nchar = len >> 1;
-		break;
+    case MBSTRING_BMP:
+        if (len & 1) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 1;
+        break;
 
-		case MBSTRING_UNIV:
-		if(len & 3) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
-			return -1;
-		}
-		nchar = len >> 2;
-		break;
+    case MBSTRING_UNIV:
+        if (len & 3) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 2;
+        break;
 
-		case MBSTRING_UTF8:
-		nchar = 0;
-		/* This counts the characters and does utf8 syntax checking */
-		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
-		if(ret < 0) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
-			return -1;
-		}
-		break;
+    case MBSTRING_UTF8:
+        nchar = 0;
+        /* This counts the characters and does utf8 syntax checking */
+        ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+        if (ret < 0) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
+            return -1;
+        }
+        break;
 
-		case MBSTRING_ASC:
-		nchar = len;
-		break;
+    case MBSTRING_ASC:
+        nchar = len;
+        break;
 
-		default:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
-		return -1;
-	}
+    default:
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+        return -1;
+    }
 
-	if((minsize > 0) && (nchar < minsize)) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
-		BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
-		ERR_add_error_data(2, "minsize=", strbuf);
-		return -1;
-	}
+    if ((minsize > 0) && (nchar < minsize)) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
+        ERR_add_error_data(2, "minsize=", strbuf);
+        return -1;
+    }
 
-	if((maxsize > 0) && (nchar > maxsize)) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
-		BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
-		ERR_add_error_data(2, "maxsize=", strbuf);
-		return -1;
-	}
+    if ((maxsize > 0) && (nchar > maxsize)) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
+        ERR_add_error_data(2, "maxsize=", strbuf);
+        return -1;
+    }
 
-	/* Now work out minimal type (if any) */
-	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
-		return -1;
-	}
+    /* Now work out minimal type (if any) */
+    if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
+        return -1;
+    }
 
+    /* Now work out output format and string type */
+    outform = MBSTRING_ASC;
+    if (mask & B_ASN1_PRINTABLESTRING)
+        str_type = V_ASN1_PRINTABLESTRING;
+    else if (mask & B_ASN1_IA5STRING)
+        str_type = V_ASN1_IA5STRING;
+    else if (mask & B_ASN1_T61STRING)
+        str_type = V_ASN1_T61STRING;
+    else if (mask & B_ASN1_BMPSTRING) {
+        str_type = V_ASN1_BMPSTRING;
+        outform = MBSTRING_BMP;
+    } else if (mask & B_ASN1_UNIVERSALSTRING) {
+        str_type = V_ASN1_UNIVERSALSTRING;
+        outform = MBSTRING_UNIV;
+    } else {
+        str_type = V_ASN1_UTF8STRING;
+        outform = MBSTRING_UTF8;
+    }
+    if (!out)
+        return str_type;
+    if (*out) {
+        free_out = 0;
+        dest = *out;
+        if (dest->data) {
+            dest->length = 0;
+            OPENSSL_free(dest->data);
+            dest->data = NULL;
+        }
+        dest->type = str_type;
+    } else {
+        free_out = 1;
+        dest = ASN1_STRING_type_new(str_type);
+        if (!dest) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        *out = dest;
+    }
+    /* If both the same type just copy across */
+    if (inform == outform) {
+        if (!ASN1_STRING_set(dest, in, len)) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        return str_type;
+    }
 
-	/* Now work out output format and string type */
-	outform = MBSTRING_ASC;
-	if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
-	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
-	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
-	else if(mask & B_ASN1_BMPSTRING) {
-		str_type = V_ASN1_BMPSTRING;
-		outform = MBSTRING_BMP;
-	} else if(mask & B_ASN1_UNIVERSALSTRING) {
-		str_type = V_ASN1_UNIVERSALSTRING;
-		outform = MBSTRING_UNIV;
-	} else {
-		str_type = V_ASN1_UTF8STRING;
-		outform = MBSTRING_UTF8;
-	}
-	if(!out) return str_type;
-	if(*out) {
-		free_out = 0;
-		dest = *out;
-		if(dest->data) {
-			dest->length = 0;
-			OPENSSL_free(dest->data);
-			dest->data = NULL;
-		}
-		dest->type = str_type;
-	} else {
-		free_out = 1;
-		dest = ASN1_STRING_type_new(str_type);
-		if(!dest) {
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return -1;
-		}
-		*out = dest;
-	}
-	/* If both the same type just copy across */
-	if(inform == outform) {
-		if(!ASN1_STRING_set(dest, in, len)) {
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return -1;
-		}
-		return str_type;
-	} 
+    /* Work out how much space the destination will need */
+    switch (outform) {
+    case MBSTRING_ASC:
+        outlen = nchar;
+        cpyfunc = cpy_asc;
+        break;
 
-	/* Work out how much space the destination will need */
-	switch(outform) {
-		case MBSTRING_ASC:
-		outlen = nchar;
-		cpyfunc = cpy_asc;
-		break;
+    case MBSTRING_BMP:
+        outlen = nchar << 1;
+        cpyfunc = cpy_bmp;
+        break;
 
-		case MBSTRING_BMP:
-		outlen = nchar << 1;
-		cpyfunc = cpy_bmp;
-		break;
+    case MBSTRING_UNIV:
+        outlen = nchar << 2;
+        cpyfunc = cpy_univ;
+        break;
 
-		case MBSTRING_UNIV:
-		outlen = nchar << 2;
-		cpyfunc = cpy_univ;
-		break;
-
-		case MBSTRING_UTF8:
-		outlen = 0;
-		traverse_string(in, len, inform, out_utf8, &outlen);
-		cpyfunc = cpy_utf8;
-		break;
-	}
-	if(!(p = OPENSSL_malloc(outlen + 1))) {
-		if(free_out) ASN1_STRING_free(dest);
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return -1;
-	}
-	dest->length = outlen;
-	dest->data = p;
-	p[outlen] = 0;
-	traverse_string(in, len, inform, cpyfunc, &p);
-	return str_type;	
+    case MBSTRING_UTF8:
+        outlen = 0;
+        traverse_string(in, len, inform, out_utf8, &outlen);
+        cpyfunc = cpy_utf8;
+        break;
+    }
+    if (!(p = OPENSSL_malloc(outlen + 1))) {
+        if (free_out)
+            ASN1_STRING_free(dest);
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    dest->length = outlen;
+    dest->data = p;
+    p[outlen] = 0;
+    traverse_string(in, len, inform, cpyfunc, &p);
+    return str_type;
 }
 
-/* This function traverses a string and passes the value of each character
- * to an optional function along with a void * argument.
+/*
+ * This function traverses a string and passes the value of each character to
+ * an optional function along with a void * argument.
  */
 
 static int traverse_string(const unsigned char *p, int len, int inform,
-		 int (*rfunc)(unsigned long value, void *in), void *arg)
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg)
 {
-	unsigned long value;
-	int ret;
-	while(len) {
-		if(inform == MBSTRING_ASC) {
-			value = *p++;
-			len--;
-		} else if(inform == MBSTRING_BMP) {
-			value = *p++ << 8;
-			value |= *p++;
-			len -= 2;
-		} else if(inform == MBSTRING_UNIV) {
-			value = ((unsigned long)*p++) << 24;
-			value |= ((unsigned long)*p++) << 16;
-			value |= *p++ << 8;
-			value |= *p++;
-			len -= 4;
-		} else {
-			ret = UTF8_getc(p, len, &value);
-			if(ret < 0) return -1;
-			len -= ret;
-			p += ret;
-		}
-		if(rfunc) {
-			ret = rfunc(value, arg);
-			if(ret <= 0) return ret;
-		}
-	}
-	return 1;
+    unsigned long value;
+    int ret;
+    while (len) {
+        if (inform == MBSTRING_ASC) {
+            value = *p++;
+            len--;
+        } else if (inform == MBSTRING_BMP) {
+            value = *p++ << 8;
+            value |= *p++;
+            len -= 2;
+        } else if (inform == MBSTRING_UNIV) {
+            value = ((unsigned long)*p++) << 24;
+            value |= ((unsigned long)*p++) << 16;
+            value |= *p++ << 8;
+            value |= *p++;
+            len -= 4;
+        } else {
+            ret = UTF8_getc(p, len, &value);
+            if (ret < 0)
+                return -1;
+            len -= ret;
+            p += ret;
+        }
+        if (rfunc) {
+            ret = rfunc(value, arg);
+            if (ret <= 0)
+                return ret;
+        }
+    }
+    return 1;
 }
 
 /* Various utility functions for traverse_string */
@@ -283,108 +294,116 @@
 
 static int in_utf8(unsigned long value, void *arg)
 {
-	int *nchar;
-	nchar = arg;
-	(*nchar)++;
-	return 1;
+    int *nchar;
+    nchar = arg;
+    (*nchar)++;
+    return 1;
 }
 
 /* Determine size of output as a UTF8 String */
 
 static int out_utf8(unsigned long value, void *arg)
 {
-	int *outlen;
-	outlen = arg;
-	*outlen += UTF8_putc(NULL, -1, value);
-	return 1;
+    int *outlen;
+    outlen = arg;
+    *outlen += UTF8_putc(NULL, -1, value);
+    return 1;
 }
 
-/* Determine the "type" of a string: check each character against a
- * supplied "mask".
+/*
+ * Determine the "type" of a string: check each character against a supplied
+ * "mask".
  */
 
 static int type_str(unsigned long value, void *arg)
 {
-	unsigned long types;
-	types = *((unsigned long *)arg);
-	if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
-					types &= ~B_ASN1_PRINTABLESTRING;
-	if((types & B_ASN1_IA5STRING) && (value > 127))
-					types &= ~B_ASN1_IA5STRING;
-	if((types & B_ASN1_T61STRING) && (value > 0xff))
-					types &= ~B_ASN1_T61STRING;
-	if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
-					types &= ~B_ASN1_BMPSTRING;
-	if(!types) return -1;
-	*((unsigned long *)arg) = types;
-	return 1;
+    unsigned long types;
+    types = *((unsigned long *)arg);
+    if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+        types &= ~B_ASN1_PRINTABLESTRING;
+    if ((types & B_ASN1_IA5STRING) && (value > 127))
+        types &= ~B_ASN1_IA5STRING;
+    if ((types & B_ASN1_T61STRING) && (value > 0xff))
+        types &= ~B_ASN1_T61STRING;
+    if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+        types &= ~B_ASN1_BMPSTRING;
+    if (!types)
+        return -1;
+    *((unsigned long *)arg) = types;
+    return 1;
 }
 
 /* Copy one byte per character ASCII like strings */
 
 static int cpy_asc(unsigned long value, void *arg)
 {
-	unsigned char **p, *q;
-	p = arg;
-	q = *p;
-	*q = (unsigned char) value;
-	(*p)++;
-	return 1;
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q = (unsigned char)value;
+    (*p)++;
+    return 1;
 }
 
 /* Copy two byte per character BMPStrings */
 
 static int cpy_bmp(unsigned long value, void *arg)
 {
-	unsigned char **p, *q;
-	p = arg;
-	q = *p;
-	*q++ = (unsigned char) ((value >> 8) & 0xff);
-	*q = (unsigned char) (value & 0xff);
-	*p += 2;
-	return 1;
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 2;
+    return 1;
 }
 
 /* Copy four byte per character UniversalStrings */
 
 static int cpy_univ(unsigned long value, void *arg)
 {
-	unsigned char **p, *q;
-	p = arg;
-	q = *p;
-	*q++ = (unsigned char) ((value >> 24) & 0xff);
-	*q++ = (unsigned char) ((value >> 16) & 0xff);
-	*q++ = (unsigned char) ((value >> 8) & 0xff);
-	*q = (unsigned char) (value & 0xff);
-	*p += 4;
-	return 1;
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 24) & 0xff);
+    *q++ = (unsigned char)((value >> 16) & 0xff);
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 4;
+    return 1;
 }
 
 /* Copy to a UTF8String */
 
 static int cpy_utf8(unsigned long value, void *arg)
 {
-	unsigned char **p;
-	int ret;
-	p = arg;
-	/* We already know there is enough room so pass 0xff as the length */
-	ret = UTF8_putc(*p, 0xff, value);
-	*p += ret;
-	return 1;
+    unsigned char **p;
+    int ret;
+    p = arg;
+    /* We already know there is enough room so pass 0xff as the length */
+    ret = UTF8_putc(*p, 0xff, value);
+    *p += ret;
+    return 1;
 }
 
 /* Return 1 if the character is permitted in a PrintableString */
 static int is_printable(unsigned long value)
 {
-	int ch;
-	if(value > 0x7f) return 0;
-	ch = (int) value;
-	/* Note: we can't use 'isalnum' because certain accented 
-	 * characters may count as alphanumeric in some environments.
-	 */
-	if((ch >= 'a') && (ch <= 'z')) return 1;
-	if((ch >= 'A') && (ch <= 'Z')) return 1;
-	if((ch >= '0') && (ch <= '9')) return 1;
-	if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
-	return 0;
+    int ch;
+    if (value > 0x7f)
+        return 0;
+    ch = (int)value;
+    /*
+     * Note: we can't use 'isalnum' because certain accented characters may
+     * count as alphanumeric in some environments.
+     */
+    if ((ch >= 'a') && (ch <= 'z'))
+        return 1;
+    if ((ch >= 'A') && (ch <= 'Z'))
+        return 1;
+    if ((ch >= '0') && (ch <= '9'))
+        return 1;
+    if ((ch == ' ') || strchr("'()+,-./:=?", ch))
+        return 1;
+    return 0;
 }
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 6ddfca9..10f3839 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -63,350 +63,334 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
-
 int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
-	{
-	unsigned char *p;
-	int objsize;
+{
+    unsigned char *p;
+    int objsize;
 
-	if ((a == NULL) || (a->data == NULL)) return(0);
+    if ((a == NULL) || (a->data == NULL))
+        return (0);
 
-	objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
-	if (pp == NULL) return objsize;
+    objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+    if (pp == NULL)
+        return objsize;
 
-	p= *pp;
-	ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
-	memcpy(p,a->data,a->length);
-	p+=a->length;
+    p = *pp;
+    ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+    memcpy(p, a->data, a->length);
+    p += a->length;
 
-	*pp=p;
-	return(objsize);
-	}
+    *pp = p;
+    return (objsize);
+}
 
 int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
-	{
-	int i,first,len=0,c, use_bn;
-	char ftmp[24], *tmp = ftmp;
-	int tmpsize = sizeof ftmp;
-	const char *p;
-	unsigned long l;
-	BIGNUM *bl = NULL;
+{
+    int i, first, len = 0, c, use_bn;
+    char ftmp[24], *tmp = ftmp;
+    int tmpsize = sizeof ftmp;
+    const char *p;
+    unsigned long l;
+    BIGNUM *bl = NULL;
 
-	if (num == 0)
-		return(0);
-	else if (num == -1)
-		num=strlen(buf);
+    if (num == 0)
+        return (0);
+    else if (num == -1)
+        num = strlen(buf);
 
-	p=buf;
-	c= *(p++);
-	num--;
-	if ((c >= '0') && (c <= '2'))
-		{
-		first= c-'0';
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
-		goto err;
-		}
+    p = buf;
+    c = *(p++);
+    num--;
+    if ((c >= '0') && (c <= '2')) {
+        first = c - '0';
+    } else {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
+        goto err;
+    }
 
-	if (num <= 0)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
-		goto err;
-		}
-	c= *(p++);
-	num--;
-	for (;;)
-		{
-		if (num <= 0) break;
-		if ((c != '.') && (c != ' '))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
-			goto err;
-			}
-		l=0;
-		use_bn = 0;
-		for (;;)
-			{
-			if (num <= 0) break;
-			num--;
-			c= *(p++);
-			if ((c == ' ') || (c == '.'))
-				break;
-			if ((c < '0') || (c > '9'))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
-				goto err;
-				}
-			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
-				{
-				use_bn = 1;
-				if (!bl)
-					bl = BN_new();
-				if (!bl || !BN_set_word(bl, l))
-					goto err;
-				}
-			if (use_bn)
-				{
-				if (!BN_mul_word(bl, 10L)
-					|| !BN_add_word(bl, c-'0'))
-					goto err;
-				}
-			else
-				l=l*10L+(long)(c-'0');
-			}
-		if (len == 0)
-			{
-			if ((first < 2) && (l >= 40))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
-				goto err;
-				}
-			if (use_bn)
-				{
-				if (!BN_add_word(bl, first * 40))
-					goto err;
-				}
-			else
-				l+=(long)first*40;
-			}
-		i=0;
-		if (use_bn)
-			{
-			int blsize;
-			blsize = BN_num_bits(bl);
-			blsize = (blsize + 6)/7;
-			if (blsize > tmpsize)
-				{
-				if (tmp != ftmp)
-					OPENSSL_free(tmp);
-				tmpsize = blsize + 32;
-				tmp = OPENSSL_malloc(tmpsize);
-				if (!tmp)
-					goto err;
-				}
-			while(blsize--)
-				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
-			}
-		else
-			{
-					
-			for (;;)
-				{
-				tmp[i++]=(unsigned char)l&0x7f;
-				l>>=7L;
-				if (l == 0L) break;
-				}
+    if (num <= 0) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
+        goto err;
+    }
+    c = *(p++);
+    num--;
+    for (;;) {
+        if (num <= 0)
+            break;
+        if ((c != '.') && (c != ' ')) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
+            goto err;
+        }
+        l = 0;
+        use_bn = 0;
+        for (;;) {
+            if (num <= 0)
+                break;
+            num--;
+            c = *(p++);
+            if ((c == ' ') || (c == '.'))
+                break;
+            if ((c < '0') || (c > '9')) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
+                goto err;
+            }
+            if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+                use_bn = 1;
+                if (!bl)
+                    bl = BN_new();
+                if (!bl || !BN_set_word(bl, l))
+                    goto err;
+            }
+            if (use_bn) {
+                if (!BN_mul_word(bl, 10L)
+                    || !BN_add_word(bl, c - '0'))
+                    goto err;
+            } else
+                l = l * 10L + (long)(c - '0');
+        }
+        if (len == 0) {
+            if ((first < 2) && (l >= 40)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
+                goto err;
+            }
+            if (use_bn) {
+                if (!BN_add_word(bl, first * 40))
+                    goto err;
+            } else
+                l += (long)first *40;
+        }
+        i = 0;
+        if (use_bn) {
+            int blsize;
+            blsize = BN_num_bits(bl);
+            blsize = (blsize + 6) / 7;
+            if (blsize > tmpsize) {
+                if (tmp != ftmp)
+                    OPENSSL_free(tmp);
+                tmpsize = blsize + 32;
+                tmp = OPENSSL_malloc(tmpsize);
+                if (!tmp)
+                    goto err;
+            }
+            while (blsize--)
+                tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+        } else {
 
-			}
-		if (out != NULL)
-			{
-			if (len+i > olen)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
-				goto err;
-				}
-			while (--i > 0)
-				out[len++]=tmp[i]|0x80;
-			out[len++]=tmp[0];
-			}
-		else
-			len+=i;
-		}
-	if (tmp != ftmp)
-		OPENSSL_free(tmp);
-	if (bl)
-		BN_free(bl);
-	return(len);
-err:
-	if (tmp != ftmp)
-		OPENSSL_free(tmp);
-	if (bl)
-		BN_free(bl);
-	return(0);
-	}
+            for (;;) {
+                tmp[i++] = (unsigned char)l & 0x7f;
+                l >>= 7L;
+                if (l == 0L)
+                    break;
+            }
+
+        }
+        if (out != NULL) {
+            if (len + i > olen) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
+                goto err;
+            }
+            while (--i > 0)
+                out[len++] = tmp[i] | 0x80;
+            out[len++] = tmp[0];
+        } else
+            len += i;
+    }
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    if (bl)
+        BN_free(bl);
+    return (len);
+ err:
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    if (bl)
+        BN_free(bl);
+    return (0);
+}
 
 int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
 {
-	return OBJ_obj2txt(buf, buf_len, a, 0);
+    return OBJ_obj2txt(buf, buf_len, a, 0);
 }
 
 int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
-	{
-	char buf[80], *p = buf;
-	int i;
+{
+    char buf[80], *p = buf;
+    int i;
 
-	if ((a == NULL) || (a->data == NULL))
-		return(BIO_write(bp,"NULL",4));
-	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
-	if (i > (int)(sizeof(buf) - 1))
-		{
-		p = OPENSSL_malloc(i + 1);
-		if (!p)
-			return -1;
-		i2t_ASN1_OBJECT(p,i + 1,a);
-		}
-	if (i <= 0)
-		return BIO_write(bp, "<INVALID>", 9);
-	BIO_write(bp,p,i);
-	if (p != buf)
-		OPENSSL_free(p);
-	return(i);
-	}
+    if ((a == NULL) || (a->data == NULL))
+        return (BIO_write(bp, "NULL", 4));
+    i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
+    if (i > (int)(sizeof(buf) - 1)) {
+        p = OPENSSL_malloc(i + 1);
+        if (!p)
+            return -1;
+        i2t_ASN1_OBJECT(p, i + 1, a);
+    }
+    if (i <= 0)
+        return BIO_write(bp, "<INVALID>", 9);
+    BIO_write(bp, p, i);
+    if (p != buf)
+        OPENSSL_free(p);
+    return (i);
+}
 
 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-	     long length)
+                             long length)
 {
-	const unsigned char *p;
-	long len;
-	int tag,xclass;
-	int inf,i;
-	ASN1_OBJECT *ret = NULL;
-	p= *pp;
-	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
-	if (inf & 0x80)
-		{
-		i=ASN1_R_BAD_OBJECT_HEADER;
-		goto err;
-		}
+    const unsigned char *p;
+    long len;
+    int tag, xclass;
+    int inf, i;
+    ASN1_OBJECT *ret = NULL;
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
 
-	if (tag != V_ASN1_OBJECT)
-		{
-		i=ASN1_R_EXPECTING_AN_OBJECT;
-		goto err;
-		}
-	ret = c2i_ASN1_OBJECT(a, &p, len);
-	if(ret) *pp = p;
-	return ret;
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	return(NULL);
+    if (tag != V_ASN1_OBJECT) {
+        i = ASN1_R_EXPECTING_AN_OBJECT;
+        goto err;
+    }
+    ret = c2i_ASN1_OBJECT(a, &p, len);
+    if (ret)
+        *pp = p;
+    return ret;
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    return (NULL);
 }
 
 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-	     long len)
-	{
-	ASN1_OBJECT *ret=NULL;
-	const unsigned char *p;
-	unsigned char *data;
-	int i, length;
+                             long len)
+{
+    ASN1_OBJECT *ret = NULL;
+    const unsigned char *p;
+    unsigned char *data;
+    int i, length;
 
-	/* Sanity check OID encoding.
-	 * Need at least one content octet.
-	 * MSB must be clear in the last octet.
-	 * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
-	 */
-	if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
-	    p[len - 1] & 0x80)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
-		return NULL;
-		}
-	/* Now 0 < len <= INT_MAX, so the cast is safe. */
-	length = (int)len;
-	for (i = 0; i < length; i++, p++)
-		{
-		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
-			return NULL;
-			}
-		}
+    /*
+     * Sanity check OID encoding. Need at least one content octet. MSB must
+     * be clear in the last octet. can't have leading 0x80 in subidentifiers,
+     * see: X.690 8.19.2
+     */
+    if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+        p[len - 1] & 0x80) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
+        return NULL;
+    }
+    /* Now 0 < len <= INT_MAX, so the cast is safe. */
+    length = (int)len;
+    for (i = 0; i < length; i++, p++) {
+        if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
+            return NULL;
+        }
+    }
 
-	/* only the ASN1_OBJECTs from the 'table' will have values
-	 * for ->sn or ->ln */
-	if ((a == NULL) || ((*a) == NULL) ||
-		!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
-		{
-		if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
-		}
-	else	ret=(*a);
+    /*
+     * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
+     * ->ln
+     */
+    if ((a == NULL) || ((*a) == NULL) ||
+        !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+        if ((ret = ASN1_OBJECT_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
 
-	p= *pp;
-	/* detach data from object */
-	data = (unsigned char *)ret->data;
-	ret->data = NULL;
-	/* once detached we can change it */
-	if ((data == NULL) || (ret->length < length))
-		{
-		ret->length=0;
-		if (data != NULL) OPENSSL_free(data);
-		data=(unsigned char *)OPENSSL_malloc(length);
-		if (data == NULL)
-			{ i=ERR_R_MALLOC_FAILURE; goto err; }
-		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-		}
-	memcpy(data,p,length);
-	/* reattach data to object, after which it remains const */
-	ret->data  =data;
-	ret->length=length;
-	ret->sn=NULL;
-	ret->ln=NULL;
-	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
-	p+=length;
+    p = *pp;
+    /* detach data from object */
+    data = (unsigned char *)ret->data;
+    ret->data = NULL;
+    /* once detached we can change it */
+    if ((data == NULL) || (ret->length < length)) {
+        ret->length = 0;
+        if (data != NULL)
+            OPENSSL_free(data);
+        data = (unsigned char *)OPENSSL_malloc(length);
+        if (data == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    }
+    memcpy(data, p, length);
+    /* reattach data to object, after which it remains const */
+    ret->data = data;
+    ret->length = length;
+    ret->sn = NULL;
+    ret->ln = NULL;
+    /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+    p += length;
 
-	if (a != NULL) (*a)=ret;
-	*pp=p;
-	return(ret);
-err:
-	OPENSSL_PUT_ERROR(ASN1, i);
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		ASN1_OBJECT_free(ret);
-	return(NULL);
-	}
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, i);
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        ASN1_OBJECT_free(ret);
+    return (NULL);
+}
 
 ASN1_OBJECT *ASN1_OBJECT_new(void)
-	{
-	ASN1_OBJECT *ret;
+{
+    ASN1_OBJECT *ret;
 
-	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(NULL);
-		}
-	ret->length=0;
-	ret->data=NULL;
-	ret->nid=0;
-	ret->sn=NULL;
-	ret->ln=NULL;
-	ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
-	return(ret);
-	}
+    ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->length = 0;
+    ret->data = NULL;
+    ret->nid = 0;
+    ret->sn = NULL;
+    ret->ln = NULL;
+    ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+    return (ret);
+}
 
 void ASN1_OBJECT_free(ASN1_OBJECT *a)
-	{
-	if (a == NULL) return;
-	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
-		{
-#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
-		if (a->sn != NULL) OPENSSL_free((void *)a->sn);
-		if (a->ln != NULL) OPENSSL_free((void *)a->ln);
+{
+    if (a == NULL)
+        return;
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+#ifndef CONST_STRICT            /* disable purely for compile-time strict
+                                 * const checking. Doing this on a "real"
+                                 * compile will cause memory leaks */
+        if (a->sn != NULL)
+            OPENSSL_free((void *)a->sn);
+        if (a->ln != NULL)
+            OPENSSL_free((void *)a->ln);
 #endif
-		a->sn=a->ln=NULL;
-		}
-	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
-		{
-		if (a->data != NULL) OPENSSL_free((void *)a->data);
-		a->data=NULL;
-		a->length=0;
-		}
-	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
-		OPENSSL_free(a);
-	}
+        a->sn = a->ln = NULL;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+        if (a->data != NULL)
+            OPENSSL_free((void *)a->data);
+        a->data = NULL;
+        a->length = 0;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+        OPENSSL_free(a);
+}
 
 ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
-	     const char *sn, const char *ln)
-	{
-	ASN1_OBJECT o;
+                                const char *sn, const char *ln)
+{
+    ASN1_OBJECT o;
 
-	o.sn=sn;
-	o.ln=ln;
-	o.data=data;
-	o.nid=nid;
-	o.length=len;
-	o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
-		ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-	return(OBJ_dup(&o));
-	}
+    o.sn = sn;
+    o.ln = ln;
+    o.data = data;
+    o.nid = nid;
+    o.length = len;
+    o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+        ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    return (OBJ_dup(&o));
+}
diff --git a/src/crypto/asn1/a_octet.c b/src/crypto/asn1/a_octet.c
index 583c9e9..2e74d6b 100644
--- a/src/crypto/asn1/a_octet.c
+++ b/src/crypto/asn1/a_octet.c
@@ -59,12 +59,19 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
-{ return M_ASN1_OCTET_STRING_dup(x); }
+{
+    return M_ASN1_OCTET_STRING_dup(x);
+}
 
-int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
-{ return M_ASN1_OCTET_STRING_cmp(a, b); }
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b)
+{
+    return M_ASN1_OCTET_STRING_cmp(a, b);
+}
 
-int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
-{ return M_ASN1_OCTET_STRING_set(x, d, len); }
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
+                          int len)
+{
+    return M_ASN1_OCTET_STRING_set(x, d, len);
+}
diff --git a/src/crypto/asn1/a_print.c b/src/crypto/asn1/a_print.c
index 3b6be10..aee54fa 100644
--- a/src/crypto/asn1/a_print.c
+++ b/src/crypto/asn1/a_print.c
@@ -59,61 +59,63 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int ASN1_PRINTABLE_type(const unsigned char *s, int len)
-	{
-	int c;
-	int ia5=0;
-	int t61=0;
+{
+    int c;
+    int ia5 = 0;
+    int t61 = 0;
 
-	if (len <= 0) len= -1;
-	if (s == NULL) return(V_ASN1_PRINTABLESTRING);
+    if (len <= 0)
+        len = -1;
+    if (s == NULL)
+        return (V_ASN1_PRINTABLESTRING);
 
-	while ((*s) && (len-- != 0))
-		{
-		c= *(s++);
-		if (!(	((c >= 'a') && (c <= 'z')) ||
-			((c >= 'A') && (c <= 'Z')) ||
-			(c == ' ') ||
-			((c >= '0') && (c <= '9')) ||
-			(c == ' ') || (c == '\'') ||
-			(c == '(') || (c == ')') ||
-			(c == '+') || (c == ',') ||
-			(c == '-') || (c == '.') ||
-			(c == '/') || (c == ':') ||
-			(c == '=') || (c == '?')))
-			ia5=1;
-		if (c&0x80)
-			t61=1;
-		}
-	if (t61) return(V_ASN1_T61STRING);
-	if (ia5) return(V_ASN1_IA5STRING);
-	return(V_ASN1_PRINTABLESTRING);
-	}
+    while ((*s) && (len-- != 0)) {
+        c = *(s++);
+        if (!(((c >= 'a') && (c <= 'z')) ||
+              ((c >= 'A') && (c <= 'Z')) ||
+              (c == ' ') ||
+              ((c >= '0') && (c <= '9')) ||
+              (c == ' ') || (c == '\'') ||
+              (c == '(') || (c == ')') ||
+              (c == '+') || (c == ',') ||
+              (c == '-') || (c == '.') ||
+              (c == '/') || (c == ':') || (c == '=') || (c == '?')))
+            ia5 = 1;
+        if (c & 0x80)
+            t61 = 1;
+    }
+    if (t61)
+        return (V_ASN1_T61STRING);
+    if (ia5)
+        return (V_ASN1_IA5STRING);
+    return (V_ASN1_PRINTABLESTRING);
+}
 
 int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
-	{
-	int i;
-	unsigned char *p;
+{
+    int i;
+    unsigned char *p;
 
-	if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
-	if ((s->length%4) != 0) return(0);
-	p=s->data;
-	for (i=0; i<s->length; i+=4)
-		{
-		if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
-			break;
-		else
-			p+=4;
-		}
-	if (i < s->length) return(0);
-	p=s->data;
-	for (i=3; i<s->length; i+=4)
-		{
-		*(p++)=s->data[i];
-		}
-	*(p)='\0';
-	s->length/=4;
-	s->type=ASN1_PRINTABLE_type(s->data,s->length);
-	return(1);
-	}
+    if (s->type != V_ASN1_UNIVERSALSTRING)
+        return (0);
+    if ((s->length % 4) != 0)
+        return (0);
+    p = s->data;
+    for (i = 0; i < s->length; i += 4) {
+        if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+            break;
+        else
+            p += 4;
+    }
+    if (i < s->length)
+        return (0);
+    p = s->data;
+    for (i = 3; i < s->length; i += 4) {
+        *(p++) = s->data[i];
+    }
+    *(p) = '\0';
+    s->length /= 4;
+    s->type = ASN1_PRINTABLE_type(s->data, s->length);
+    return (1);
+}
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index d4316f7..ba1224e 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -56,231 +56,253 @@
 
 #include <openssl/asn1.h>
 
-#include <stdlib.h>  /* For bsearch */
+#include <stdlib.h>             /* For bsearch */
 #include <string.h>
 
 #include <openssl/err.h>
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
-
 static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
 static void st_free(ASN1_STRING_TABLE *tbl);
 
-/* This is the global mask for the mbstring functions: this is use to
- * mask out certain types (such as BMPString and UTF8String) because
- * certain software (e.g. Netscape) has problems with them.
+/*
+ * This is the global mask for the mbstring functions: this is use to mask
+ * out certain types (such as BMPString and UTF8String) because certain
+ * software (e.g. Netscape) has problems with them.
  */
 
 static unsigned long global_mask = B_ASN1_UTF8STRING;
 
 void ASN1_STRING_set_default_mask(unsigned long mask)
 {
-	global_mask = mask;
+    global_mask = mask;
 }
 
 unsigned long ASN1_STRING_get_default_mask(void)
 {
-	return global_mask;
+    return global_mask;
 }
 
-/* This function sets the default to various "flavours" of configuration.
- * based on an ASCII string. Currently this is:
- * MASK:XXXX : a numerical mask value.
- * nobmp : Don't use BMPStrings (just Printable, T61).
- * pkix : PKIX recommendation in RFC2459.
- * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
- * default:   the default value, Printable, T61, BMP.
+/*
+ * This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is: MASK:XXXX : a numerical mask
+ * value. nobmp : Don't use BMPStrings (just Printable, T61). pkix : PKIX
+ * recommendation in RFC2459. utf8only : only use UTF8Strings (RFC2459
+ * recommendation for 2004). default: the default value, Printable, T61, BMP.
  */
 
 int ASN1_STRING_set_default_mask_asc(const char *p)
 {
-	unsigned long mask;
-	char *end;
-	if(!strncmp(p, "MASK:", 5)) {
-		if(!p[5]) return 0;
-		mask = strtoul(p + 5, &end, 0);
-		if(*end) return 0;
-	} else if(!strcmp(p, "nombstr"))
-			 mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
-	else if(!strcmp(p, "pkix"))
-			mask = ~((unsigned long)B_ASN1_T61STRING);
-	else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
-	else if(!strcmp(p, "default"))
-	    mask = 0xFFFFFFFFL;
-	else return 0;
-	ASN1_STRING_set_default_mask(mask);
-	return 1;
+    unsigned long mask;
+    char *end;
+    if (!strncmp(p, "MASK:", 5)) {
+        if (!p[5])
+            return 0;
+        mask = strtoul(p + 5, &end, 0);
+        if (*end)
+            return 0;
+    } else if (!strcmp(p, "nombstr"))
+        mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
+    else if (!strcmp(p, "pkix"))
+        mask = ~((unsigned long)B_ASN1_T61STRING);
+    else if (!strcmp(p, "utf8only"))
+        mask = B_ASN1_UTF8STRING;
+    else if (!strcmp(p, "default"))
+        mask = 0xFFFFFFFFL;
+    else
+        return 0;
+    ASN1_STRING_set_default_mask(mask);
+    return 1;
 }
 
-/* The following function generates an ASN1_STRING based on limits in a table.
- * Frequently the types and length of an ASN1_STRING are restricted by a 
- * corresponding OID. For example certificates and certificate requests.
+/*
+ * The following function generates an ASN1_STRING based on limits in a
+ * table. Frequently the types and length of an ASN1_STRING are restricted by
+ * a corresponding OID. For example certificates and certificate requests.
  */
 
-ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
-					int inlen, int inform, int nid)
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid)
 {
-	ASN1_STRING_TABLE *tbl;
-	ASN1_STRING *str = NULL;
-	unsigned long mask;
-	int ret;
-	if(!out) out = &str;
-	tbl = ASN1_STRING_TABLE_get(nid);
-	if(tbl) {
-		mask = tbl->mask;
-		if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
-		ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
-					tbl->minsize, tbl->maxsize);
-	} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
-	if(ret <= 0) return NULL;
-	return *out;
+    ASN1_STRING_TABLE *tbl;
+    ASN1_STRING *str = NULL;
+    unsigned long mask;
+    int ret;
+    if (!out)
+        out = &str;
+    tbl = ASN1_STRING_TABLE_get(nid);
+    if (tbl) {
+        mask = tbl->mask;
+        if (!(tbl->flags & STABLE_NO_MASK))
+            mask &= global_mask;
+        ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+                                  tbl->minsize, tbl->maxsize);
+    } else
+        ret =
+            ASN1_mbstring_copy(out, in, inlen, inform,
+                               DIRSTRING_TYPE & global_mask);
+    if (ret <= 0)
+        return NULL;
+    return *out;
 }
 
-/* Now the tables and helper functions for the string table:
+/*
+ * Now the tables and helper functions for the string table:
  */
 
 /* size limits: this stuff is taken straight from RFC3280 */
 
-#define ub_name				32768
-#define ub_common_name			64
-#define ub_locality_name		128
-#define ub_state_name			128
-#define ub_organization_name		64
-#define ub_organization_unit_name	64
-#define ub_title			64
-#define ub_email_address		128
-#define ub_serial_number		64
-
+#define ub_name                         32768
+#define ub_common_name                  64
+#define ub_locality_name                128
+#define ub_state_name                   128
+#define ub_organization_name            64
+#define ub_organization_unit_name       64
+#define ub_title                        64
+#define ub_email_address                128
+#define ub_serial_number                64
 
 /* This table must be kept in NID order */
 
 static const ASN1_STRING_TABLE tbl_standard[] = {
-{NID_commonName,		1, ub_common_name, DIRSTRING_TYPE, 0},
-{NID_countryName,		2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_localityName,		1, ub_locality_name, DIRSTRING_TYPE, 0},
-{NID_stateOrProvinceName,	1, ub_state_name, DIRSTRING_TYPE, 0},
-{NID_organizationName,		1, ub_organization_name, DIRSTRING_TYPE, 0},
-{NID_organizationalUnitName,	1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
-{NID_pkcs9_emailAddress,	1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_pkcs9_unstructuredName,	1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_challengePassword,	1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_unstructuredAddress,	1, -1, DIRSTRING_TYPE, 0},
-{NID_givenName,			1, ub_name, DIRSTRING_TYPE, 0},
-{NID_surname,			1, ub_name, DIRSTRING_TYPE, 0},
-{NID_initials,			1, ub_name, DIRSTRING_TYPE, 0},
-{NID_serialNumber,		1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_friendlyName,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
-{NID_name,			1, ub_name, DIRSTRING_TYPE, 0},
-{NID_dnQualifier,		-1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_domainComponent,		1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_ms_csp_name,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+    {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
+    {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
+    {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+    {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+    {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
+     0},
+    {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
+     STABLE_NO_MASK},
+    {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+    {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
+     STABLE_NO_MASK},
+    {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+    {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+    {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
 };
 
 static int sk_table_cmp(const ASN1_STRING_TABLE **a,
-			const ASN1_STRING_TABLE **b)
+                        const ASN1_STRING_TABLE **b)
 {
-	return (*a)->nid - (*b)->nid;
+    return (*a)->nid - (*b)->nid;
 }
 
 static int table_cmp(const void *in_a, const void *in_b)
 {
-	const ASN1_STRING_TABLE *a = in_a;
-	const ASN1_STRING_TABLE *b = in_b;
-	return a->nid - b->nid;
+    const ASN1_STRING_TABLE *a = in_a;
+    const ASN1_STRING_TABLE *b = in_b;
+    return a->nid - b->nid;
 }
 
 ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
 {
-	int found;
-	size_t idx;
-	ASN1_STRING_TABLE *ttmp;
-	ASN1_STRING_TABLE fnd;
-	fnd.nid = nid;
+    int found;
+    size_t idx;
+    ASN1_STRING_TABLE *ttmp;
+    ASN1_STRING_TABLE fnd;
+    fnd.nid = nid;
 
-	ttmp = bsearch(&fnd, tbl_standard, sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE), sizeof(ASN1_STRING_TABLE), table_cmp);
-	if(ttmp) return ttmp;
-	if(!stable) return NULL;
-	found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
-	if (!found) return NULL;
-	return sk_ASN1_STRING_TABLE_value(stable, idx);
+    ttmp =
+        bsearch(&fnd, tbl_standard,
+                sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE),
+                sizeof(ASN1_STRING_TABLE), table_cmp);
+    if (ttmp)
+        return ttmp;
+    if (!stable)
+        return NULL;
+    found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
+    if (!found)
+        return NULL;
+    return sk_ASN1_STRING_TABLE_value(stable, idx);
 }
-	
+
 int ASN1_STRING_TABLE_add(int nid,
-		 long minsize, long maxsize, unsigned long mask,
-				unsigned long flags)
+                          long minsize, long maxsize, unsigned long mask,
+                          unsigned long flags)
 {
-	ASN1_STRING_TABLE *tmp;
-	char new_nid = 0;
-	flags &= ~STABLE_FLAGS_MALLOC;
-	if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
-	if(!stable) {
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
-		tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
-		if(!tmp) {
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return 0;
-		}
-		tmp->flags = flags | STABLE_FLAGS_MALLOC;
-		tmp->nid = nid;
-		new_nid = 1;
-	} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
-	if(minsize != -1) tmp->minsize = minsize;
-	if(maxsize != -1) tmp->maxsize = maxsize;
-	tmp->mask = mask;
-	if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
-	return 1;
+    ASN1_STRING_TABLE *tmp;
+    char new_nid = 0;
+    flags &= ~STABLE_FLAGS_MALLOC;
+    if (!stable)
+        stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+    if (!stable) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
+        tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
+        if (!tmp) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        tmp->flags = flags | STABLE_FLAGS_MALLOC;
+        tmp->nid = nid;
+        new_nid = 1;
+    } else
+        tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+    if (minsize != -1)
+        tmp->minsize = minsize;
+    if (maxsize != -1)
+        tmp->maxsize = maxsize;
+    tmp->mask = mask;
+    if (new_nid)
+        sk_ASN1_STRING_TABLE_push(stable, tmp);
+    return 1;
 }
 
 void ASN1_STRING_TABLE_cleanup(void)
 {
-	STACK_OF(ASN1_STRING_TABLE) *tmp;
-	tmp = stable;
-	if(!tmp) return;
-	stable = NULL;
-	sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+    STACK_OF(ASN1_STRING_TABLE) *tmp;
+    tmp = stable;
+    if (!tmp)
+        return;
+    stable = NULL;
+    sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
 }
 
 static void st_free(ASN1_STRING_TABLE *tbl)
 {
-	if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
+    if (tbl->flags & STABLE_FLAGS_MALLOC)
+        OPENSSL_free(tbl);
 }
 
-
 #ifdef STRING_TABLE_TEST
 
-int
-main(void)
+int main(void)
 {
-	ASN1_STRING_TABLE *tmp;
-	int i, last_nid = -1;
+    ASN1_STRING_TABLE *tmp;
+    int i, last_nid = -1;
 
-	for (tmp = tbl_standard, i = 0;
-		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
-		{
-			if (tmp->nid < last_nid)
-				{
-				last_nid = 0;
-				break;
-				}
-			last_nid = tmp->nid;
-		}
+    for (tmp = tbl_standard, i = 0;
+         i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
+        if (tmp->nid < last_nid) {
+            last_nid = 0;
+            break;
+        }
+        last_nid = tmp->nid;
+    }
 
-	if (last_nid != 0)
-		{
-		printf("Table order OK\n");
-		exit(0);
-		}
+    if (last_nid != 0) {
+        printf("Table order OK\n");
+        exit(0);
+    }
 
-	for (tmp = tbl_standard, i = 0;
-		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
-			printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
-							OBJ_nid2ln(tmp->nid));
+    for (tmp = tbl_standard, i = 0;
+         i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
+        printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+               OBJ_nid2ln(tmp->nid));
 
-	return 0;
+    return 0;
 }
 
 #endif
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index ac2cb48..4391092 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -67,12 +67,10 @@
 
 #include "asn1_locl.h"
 
-
-/* This is an implementation of the ASN1 Time structure which is:
- *    Time ::= CHOICE {
- *      utcTime        UTCTime,
- *      generalTime    GeneralizedTime }
- * written by Steve Henson.
+/*
+ * This is an implementation of the ASN1 Time structure which is: Time ::=
+ * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve
+ * Henson.
  */
 
 IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
@@ -81,141 +79,139 @@
 
 #if 0
 int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
-	{
-	if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
-				return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
-				     a->type ,V_ASN1_UNIVERSAL));
-	OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
-	return -1;
-	}
+{
+    if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
+        return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+                               a->type, V_ASN1_UNIVERSAL));
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
+    return -1;
+}
 #endif
 
-
 ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
-	{
-	return ASN1_TIME_adj(s, t, 0, 0);
-	}
+{
+    return ASN1_TIME_adj(s, t, 0, 0);
+}
 
 ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
-				int offset_day, long offset_sec)
-	{
-	struct tm *ts;
-	struct tm data;
+                         int offset_day, long offset_sec)
+{
+    struct tm *ts;
+    struct tm data;
 
-	ts=OPENSSL_gmtime(&t,&data);
-	if (ts == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
-		return NULL;
-		}
-	if (offset_day || offset_sec)
-		{ 
-		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-			return NULL;
-		}
-	if((ts->tm_year >= 50) && (ts->tm_year < 150))
-			return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
-	return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
-	}
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
+        return NULL;
+    }
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
+    if ((ts->tm_year >= 50) && (ts->tm_year < 150))
+        return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+    return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+}
 
 int ASN1_TIME_check(ASN1_TIME *t)
-	{
-	if (t->type == V_ASN1_GENERALIZEDTIME)
-		return ASN1_GENERALIZEDTIME_check(t);
-	else if (t->type == V_ASN1_UTCTIME)
-		return ASN1_UTCTIME_check(t);
-	return 0;
-	}
+{
+    if (t->type == V_ASN1_GENERALIZEDTIME)
+        return ASN1_GENERALIZEDTIME_check(t);
+    else if (t->type == V_ASN1_UTCTIME)
+        return ASN1_UTCTIME_check(t);
+    return 0;
+}
 
 /* Convert an ASN1_TIME structure to GeneralizedTime */
-ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
-	{
-	ASN1_GENERALIZEDTIME *ret;
-	char *str;
-	int newlen;
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
+                                                   ASN1_GENERALIZEDTIME **out)
+{
+    ASN1_GENERALIZEDTIME *ret;
+    char *str;
+    int newlen;
 
-	if (!ASN1_TIME_check(t)) return NULL;
+    if (!ASN1_TIME_check(t))
+        return NULL;
 
-	if (!out || !*out)
-		{
-		if (!(ret = ASN1_GENERALIZEDTIME_new ()))
-			return NULL;
-		if (out) *out = ret;
-		}
-	else ret = *out;
+    if (!out || !*out) {
+        if (!(ret = ASN1_GENERALIZEDTIME_new()))
+            return NULL;
+        if (out)
+            *out = ret;
+    } else
+        ret = *out;
 
-	/* If already GeneralizedTime just copy across */
-	if (t->type == V_ASN1_GENERALIZEDTIME)
-		{
-		if(!ASN1_STRING_set(ret, t->data, t->length))
-			return NULL;
-		return ret;
-		}
+    /* If already GeneralizedTime just copy across */
+    if (t->type == V_ASN1_GENERALIZEDTIME) {
+        if (!ASN1_STRING_set(ret, t->data, t->length))
+            return NULL;
+        return ret;
+    }
 
-	/* grow the string */
-	if (!ASN1_STRING_set(ret, NULL, t->length + 2))
-		return NULL;
-	/* ASN1_STRING_set() allocated 'len + 1' bytes. */
-	newlen = t->length + 2 + 1;
-	str = (char *)ret->data;
-	/* Work out the century and prepend */
-	if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
-	else BUF_strlcpy(str, "20", newlen);
+    /* grow the string */
+    if (!ASN1_STRING_set(ret, NULL, t->length + 2))
+        return NULL;
+    /* ASN1_STRING_set() allocated 'len + 1' bytes. */
+    newlen = t->length + 2 + 1;
+    str = (char *)ret->data;
+    /* Work out the century and prepend */
+    if (t->data[0] >= '5')
+        BUF_strlcpy(str, "19", newlen);
+    else
+        BUF_strlcpy(str, "20", newlen);
 
-	BUF_strlcat(str, (char *)t->data, newlen);
+    BUF_strlcat(str, (char *)t->data, newlen);
 
-	return ret;
-	}
+    return ret;
+}
 
 int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
-	{
-	ASN1_TIME t;
+{
+    ASN1_TIME t;
 
-	t.length = strlen(str);
-	t.data = (unsigned char *)str;
-	t.flags = 0;
-	
-	t.type = V_ASN1_UTCTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    t.flags = 0;
 
-	if (!ASN1_TIME_check(&t))
-		{
-		t.type = V_ASN1_GENERALIZEDTIME;
-		if (!ASN1_TIME_check(&t))
-			return 0;
-		}
-	
-	if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
-			return 0;
+    t.type = V_ASN1_UTCTIME;
 
-	return 1;
-	}
+    if (!ASN1_TIME_check(&t)) {
+        t.type = V_ASN1_GENERALIZEDTIME;
+        if (!ASN1_TIME_check(&t))
+            return 0;
+    }
+
+    if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+        return 0;
+
+    return 1;
+}
 
 static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
-	{
-	if (t == NULL)
-		{
-		time_t now_t;
-		time(&now_t);
-		if (OPENSSL_gmtime(&now_t, tm))
-			return 1;
-		return 0;
-		}
-		
-	if (t->type == V_ASN1_UTCTIME)
-		return asn1_utctime_to_tm(tm, t);
-	else if (t->type == V_ASN1_GENERALIZEDTIME)
-		return asn1_generalizedtime_to_tm(tm, t);
+{
+    if (t == NULL) {
+        time_t now_t;
+        time(&now_t);
+        if (OPENSSL_gmtime(&now_t, tm))
+            return 1;
+        return 0;
+    }
 
-	return 0;
-	}
+    if (t->type == V_ASN1_UTCTIME)
+        return asn1_utctime_to_tm(tm, t);
+    else if (t->type == V_ASN1_GENERALIZEDTIME)
+        return asn1_generalizedtime_to_tm(tm, t);
+
+    return 0;
+}
 
 int ASN1_TIME_diff(int *pday, int *psec,
-			const ASN1_TIME *from, const ASN1_TIME *to)
-	{
-	struct tm tm_from, tm_to;
-	if (!asn1_time_to_tm(&tm_from, from))
-		return 0;
-	if (!asn1_time_to_tm(&tm_to, to))
-		return 0;
-	return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
-	}	
+                   const ASN1_TIME *from, const ASN1_TIME *to)
+{
+    struct tm tm_from, tm_to;
+    if (!asn1_time_to_tm(&tm_from, from))
+        return 0;
+    if (!asn1_time_to_tm(&tm_to, to))
+        return 0;
+    return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
diff --git a/src/crypto/asn1/a_type.c b/src/crypto/asn1/a_type.c
index fd3d5b1..ecd4734 100644
--- a/src/crypto/asn1/a_type.c
+++ b/src/crypto/asn1/a_type.c
@@ -61,100 +61,93 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
-
 int ASN1_TYPE_get(ASN1_TYPE *a)
-	{
-	if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
-		return(a->type);
-	else
-		return(0);
-	}
+{
+    if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+        return (a->type);
+    else
+        return (0);
+}
 
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
-	{
-	if (a->value.ptr != NULL)
-		{
-		ASN1_TYPE **tmp_a = &a;
-		ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
-		}
-	a->type=type;
-	if (type == V_ASN1_BOOLEAN)
-		a->value.boolean = value ? 0xff : 0;
-	else
-		a->value.ptr=value;
-	}
+{
+    if (a->value.ptr != NULL) {
+        ASN1_TYPE **tmp_a = &a;
+        ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
+    }
+    a->type = type;
+    if (type == V_ASN1_BOOLEAN)
+        a->value.boolean = value ? 0xff : 0;
+    else
+        a->value.ptr = value;
+}
 
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
-	{
-	if (!value || (type == V_ASN1_BOOLEAN))
-		{
-		void *p = (void *)value;
-		ASN1_TYPE_set(a, type, p);
-		}
-	else if (type == V_ASN1_OBJECT)
-		{
-		ASN1_OBJECT *odup;
-		odup = OBJ_dup(value);
-		if (!odup)
-			return 0;
-		ASN1_TYPE_set(a, type, odup);
-		}
-	else
-		{
-		ASN1_STRING *sdup;
-		sdup = ASN1_STRING_dup(value);
-		if (!sdup)
-			return 0;
-		ASN1_TYPE_set(a, type, sdup);
-		}
-	return 1;
-	}
+{
+    if (!value || (type == V_ASN1_BOOLEAN)) {
+        void *p = (void *)value;
+        ASN1_TYPE_set(a, type, p);
+    } else if (type == V_ASN1_OBJECT) {
+        ASN1_OBJECT *odup;
+        odup = OBJ_dup(value);
+        if (!odup)
+            return 0;
+        ASN1_TYPE_set(a, type, odup);
+    } else {
+        ASN1_STRING *sdup;
+        sdup = ASN1_STRING_dup(value);
+        if (!sdup)
+            return 0;
+        ASN1_TYPE_set(a, type, sdup);
+    }
+    return 1;
+}
 
 /* Returns 0 if they are equal, != 0 otherwise. */
 int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
-	{
-	int result = -1;
+{
+    int result = -1;
 
-	if (!a || !b || a->type != b->type) return -1;
+    if (!a || !b || a->type != b->type)
+        return -1;
 
-	switch (a->type)
-		{
-	case V_ASN1_OBJECT:
-		result = OBJ_cmp(a->value.object, b->value.object);
-		break;
-	case V_ASN1_NULL:
-		result = 0;	/* They do not have content. */
-		break;
-	case V_ASN1_BOOLEAN:
-		result = a->value.boolean - b->value.boolean;
-		break;
-	case V_ASN1_INTEGER:
-	case V_ASN1_NEG_INTEGER:
-	case V_ASN1_ENUMERATED:
-	case V_ASN1_NEG_ENUMERATED:
-	case V_ASN1_BIT_STRING:
-	case V_ASN1_OCTET_STRING:
-	case V_ASN1_SEQUENCE:
-	case V_ASN1_SET:
-	case V_ASN1_NUMERICSTRING:
-	case V_ASN1_PRINTABLESTRING:
-	case V_ASN1_T61STRING:
-	case V_ASN1_VIDEOTEXSTRING:
-	case V_ASN1_IA5STRING:
-	case V_ASN1_UTCTIME:
-	case V_ASN1_GENERALIZEDTIME:
-	case V_ASN1_GRAPHICSTRING:
-	case V_ASN1_VISIBLESTRING:
-	case V_ASN1_GENERALSTRING:
-	case V_ASN1_UNIVERSALSTRING:
-	case V_ASN1_BMPSTRING:
-	case V_ASN1_UTF8STRING:
-	case V_ASN1_OTHER:
-	default:
-		result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
-					 (ASN1_STRING *) b->value.ptr);
-		break;
-		}
+    switch (a->type) {
+    case V_ASN1_OBJECT:
+        result = OBJ_cmp(a->value.object, b->value.object);
+        break;
+    case V_ASN1_NULL:
+        result = 0;             /* They do not have content. */
+        break;
+    case V_ASN1_BOOLEAN:
+        result = a->value.boolean - b->value.boolean;
+        break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_NEG_INTEGER:
+    case V_ASN1_ENUMERATED:
+    case V_ASN1_NEG_ENUMERATED:
+    case V_ASN1_BIT_STRING:
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    default:
+        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
+                                 (ASN1_STRING *)b->value.ptr);
+        break;
+    }
 
-	return result;
-	}
+    return result;
+}
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index dbbbecb..5a55bd2 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -63,280 +63,273 @@
 #include <openssl/mem.h>
 #include <openssl/time_support.h>
 
+#include "asn1_locl.h"
 
 #if 0
 int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
-	{
-	return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
-		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
-	}
-
+{
+    return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+                           V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
+}
 
 ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
-	     long length)
-	{
-	ASN1_UTCTIME *ret=NULL;
+                               long length)
+{
+    ASN1_UTCTIME *ret = NULL;
 
-	ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
-		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
-		return(NULL);
-		}
-	if (!ASN1_UTCTIME_check(ret))
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
-		goto err;
-		}
+    ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
+                                         V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
+        return (NULL);
+    }
+    if (!ASN1_UTCTIME_check(ret)) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
+        goto err;
+    }
 
-	return(ret);
-err:
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		M_ASN1_UTCTIME_free(ret);
-	return(NULL);
-	}
+    return (ret);
+ err:
+    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+        M_ASN1_UTCTIME_free(ret);
+    return (NULL);
+}
 
 #endif
 
 int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
-	{
-	static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
-	static const int max[8]={99,12,31,23,59,59,12,59};
-	char *a;
-	int n,i,l,o;
+{
+    static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
+    char *a;
+    int n, i, l, o;
 
-	if (d->type != V_ASN1_UTCTIME) return(0);
-	l=d->length;
-	a=(char *)d->data;
-	o=0;
+    if (d->type != V_ASN1_UTCTIME)
+        return (0);
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
 
-	if (l < 11) goto err;
-	for (i=0; i<6; i++)
-		{
-		if ((i == 5) && ((a[o] == 'Z') ||
-			(a[o] == '+') || (a[o] == '-')))
-			{
-			i++;
-			if (tm)
-				tm->tm_sec = 0;
-			break;
-			}
-		if ((a[o] < '0') || (a[o] > '9')) goto err;
-		n= a[o]-'0';
-		if (++o > l) goto err;
+    if (l < 11)
+        goto err;
+    for (i = 0; i < 6; i++) {
+        if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+            i++;
+            if (tm)
+                tm->tm_sec = 0;
+            break;
+        }
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = a[o] - '0';
+        if (++o > l)
+            goto err;
 
-		if ((a[o] < '0') || (a[o] > '9')) goto err;
-		n=(n*10)+ a[o]-'0';
-		if (++o > l) goto err;
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = (n * 10) + a[o] - '0';
+        if (++o > l)
+            goto err;
 
-		if ((n < min[i]) || (n > max[i])) goto err;
-		if (tm)
-			{
-			switch(i)
-				{
-			case 0:
-				tm->tm_year = n < 50 ? n + 100 : n;
-				break;
-			case 1:
-				tm->tm_mon = n - 1;
-				break;
-			case 2:
-				tm->tm_mday = n;
-				break;
-			case 3:
-				tm->tm_hour = n;
-				break;
-			case 4:
-				tm->tm_min = n;
-				break;
-			case 5:
-				tm->tm_sec = n;
-				break;
-				}
-			}
-		}
-	if (a[o] == 'Z')
-		o++;
-	else if ((a[o] == '+') || (a[o] == '-'))
-		{
-		int offsign = a[o] == '-' ? -1 : 1, offset = 0;
-		o++;
-		if (o+4 > l) goto err;
-		for (i=6; i<8; i++)
-			{
-			if ((a[o] < '0') || (a[o] > '9')) goto err;
-			n= a[o]-'0';
-			o++;
-			if ((a[o] < '0') || (a[o] > '9')) goto err;
-			n=(n*10)+ a[o]-'0';
-			if ((n < min[i]) || (n > max[i])) goto err;
-			if (tm)
-				{
-				if (i == 6)
-					offset = n * 3600;
-				else if (i == 7)
-					offset += n * 60;
-				}
-			o++;
-			}
-		if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
-			return 0;
-		}
-	return o == l;
-err:
-	return 0;
-	}
+        if ((n < min[i]) || (n > max[i]))
+            goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n < 50 ? n + 100 : n;
+                break;
+            case 1:
+                tm->tm_mon = n - 1;
+                break;
+            case 2:
+                tm->tm_mday = n;
+                break;
+            case 3:
+                tm->tm_hour = n;
+                break;
+            case 4:
+                tm->tm_min = n;
+                break;
+            case 5:
+                tm->tm_sec = n;
+                break;
+            }
+        }
+    }
+    if (a[o] == 'Z')
+        o++;
+    else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+        o++;
+        if (o + 4 > l)
+            goto err;
+        for (i = 6; i < 8; i++) {
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = a[o] - '0';
+            o++;
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = (n * 10) + a[o] - '0';
+            if ((n < min[i]) || (n > max[i]))
+                goto err;
+            if (tm) {
+                if (i == 6)
+                    offset = n * 3600;
+                else if (i == 7)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
+    }
+    return o == l;
+ err:
+    return 0;
+}
 
 int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
-	{
-	return asn1_utctime_to_tm(NULL, d);
-	}
+{
+    return asn1_utctime_to_tm(NULL, d);
+}
 
 int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
-	{
-	ASN1_UTCTIME t;
+{
+    ASN1_UTCTIME t;
 
-	t.type=V_ASN1_UTCTIME;
-	t.length=strlen(str);
-	t.data=(unsigned char *)str;
-	if (ASN1_UTCTIME_check(&t))
-		{
-		if (s != NULL)
-			{
-			if (!ASN1_STRING_set((ASN1_STRING *)s,
-				(unsigned char *)str,t.length))
-				return 0;
-			s->type = V_ASN1_UTCTIME;
-			}
-		return(1);
-		}
-	else
-		return(0);
-	}
+    t.type = V_ASN1_UTCTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    if (ASN1_UTCTIME_check(&t)) {
+        if (s != NULL) {
+            if (!ASN1_STRING_set((ASN1_STRING *)s,
+                                 (unsigned char *)str, t.length))
+                return 0;
+            s->type = V_ASN1_UTCTIME;
+        }
+        return (1);
+    } else
+        return (0);
+}
 
 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
-	{
-	return ASN1_UTCTIME_adj(s, t, 0, 0);
-	}
+{
+    return ASN1_UTCTIME_adj(s, t, 0, 0);
+}
 
 ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
-				int offset_day, long offset_sec)
-	{
-	char *p;
-	struct tm *ts;
-	struct tm data;
-	size_t len = 20;
-	int free_s = 0;
+                               int offset_day, long offset_sec)
+{
+    char *p;
+    struct tm *ts;
+    struct tm data;
+    size_t len = 20;
+    int free_s = 0;
 
-	if (s == NULL)
-		{
-		free_s = 1;
-		s=M_ASN1_UTCTIME_new();
-		}
-	if (s == NULL)
-		goto err;
+    if (s == NULL) {
+        free_s = 1;
+        s = M_ASN1_UTCTIME_new();
+    }
+    if (s == NULL)
+        goto err;
 
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        goto err;
 
-	ts=OPENSSL_gmtime(&t, &data);
-	if (ts == NULL)
-		goto err;
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            goto err;
+    }
 
-	if (offset_day || offset_sec)
-		{ 
-		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-			goto err;
-		}
+    if ((ts->tm_year < 50) || (ts->tm_year >= 150))
+        goto err;
 
-	if((ts->tm_year < 50) || (ts->tm_year >= 150))
-		goto err;
+    p = (char *)s->data;
+    if ((p == NULL) || ((size_t)s->length < len)) {
+        p = OPENSSL_malloc(len);
+        if (p == NULL) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (s->data != NULL)
+            OPENSSL_free(s->data);
+        s->data = (unsigned char *)p;
+    }
 
-	p=(char *)s->data;
-	if ((p == NULL) || ((size_t)s->length < len))
-		{
-		p=OPENSSL_malloc(len);
-		if (p == NULL)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		if (s->data != NULL)
-			OPENSSL_free(s->data);
-		s->data=(unsigned char *)p;
-		}
-
-	BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
-		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
-	s->length=strlen(p);
-	s->type=V_ASN1_UTCTIME;
-	return(s);
-	err:
-	if (free_s && s)
-		M_ASN1_UTCTIME_free(s);
-	return NULL;
-	}
-
+    BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+                 ts->tm_sec);
+    s->length = strlen(p);
+    s->type = V_ASN1_UTCTIME;
+    return (s);
+ err:
+    if (free_s && s)
+        M_ASN1_UTCTIME_free(s);
+    return NULL;
+}
 
 int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
-	{
-	struct tm stm, ttm;
-	int day, sec;
+{
+    struct tm stm, ttm;
+    int day, sec;
 
-	if (!asn1_utctime_to_tm(&stm, s))
-		return -2;
+    if (!asn1_utctime_to_tm(&stm, s))
+        return -2;
 
-	if (!OPENSSL_gmtime(&t, &ttm))
-		return -2;
+    if (!OPENSSL_gmtime(&t, &ttm))
+        return -2;
 
-	if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
-		return -2;
+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+        return -2;
 
-	if (day > 0)
-		return 1;
-	if (day < 0)
-		return -1;
-	if (sec > 0)
-		return 1;
-	if (sec < 0)
-		return -1;
-	return 0;
-	}
-
+    if (day > 0)
+        return 1;
+    if (day < 0)
+        return -1;
+    if (sec > 0)
+        return 1;
+    if (sec < 0)
+        return -1;
+    return 0;
+}
 
 #if 0
 time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
-	{
-	struct tm tm;
-	int offset;
+{
+    struct tm tm;
+    int offset;
 
-	memset(&tm,'\0',sizeof tm);
+    memset(&tm, '\0', sizeof tm);
 
-#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
-	tm.tm_year=g2(s->data);
-	if(tm.tm_year < 50)
-		tm.tm_year+=100;
-	tm.tm_mon=g2(s->data+2)-1;
-	tm.tm_mday=g2(s->data+4);
-	tm.tm_hour=g2(s->data+6);
-	tm.tm_min=g2(s->data+8);
-	tm.tm_sec=g2(s->data+10);
-	if(s->data[12] == 'Z')
-		offset=0;
-	else
-		{
-		offset=g2(s->data+13)*60+g2(s->data+15);
-		if(s->data[12] == '-')
-			offset= -offset;
-		}
-#undef g2
+# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
+    tm.tm_year = g2(s->data);
+    if (tm.tm_year < 50)
+        tm.tm_year += 100;
+    tm.tm_mon = g2(s->data + 2) - 1;
+    tm.tm_mday = g2(s->data + 4);
+    tm.tm_hour = g2(s->data + 6);
+    tm.tm_min = g2(s->data + 8);
+    tm.tm_sec = g2(s->data + 10);
+    if (s->data[12] == 'Z')
+        offset = 0;
+    else {
+        offset = g2(s->data + 13) * 60 + g2(s->data + 15);
+        if (s->data[12] == '-')
+            offset = -offset;
+    }
+# undef g2
 
-	return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
-	                               * instead of UTC, and unless we rewrite OpenSSL
-				       * in Lisp we cannot locally change the timezone
-				       * without possibly interfering with other parts
-	                               * of the program. timegm, which uses UTC, is
-				       * non-standard.
-	                               * Also time_t is inappropriate for general
-	                               * UTC times because it may a 32 bit type. */
-	}
+    return mktime(&tm) - offset * 60; /* FIXME: mktime assumes the current
+                                       * timezone instead of UTC, and unless
+                                       * we rewrite OpenSSL in Lisp we cannot
+                                       * locally change the timezone without
+                                       * possibly interfering with other
+                                       * parts of the program. timegm, which
+                                       * uses UTC, is non-standard. Also
+                                       * time_t is inappropriate for general
+                                       * UTC times because it may a 32 bit
+                                       * type. */
+}
 #endif
diff --git a/src/crypto/asn1/a_utf8.c b/src/crypto/asn1/a_utf8.c
index ed6e98d..1702768 100644
--- a/src/crypto/asn1/a_utf8.c
+++ b/src/crypto/asn1/a_utf8.c
@@ -59,152 +59,176 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 /* UTF8 utilities */
 
-/* This parses a UTF8 string one character at a time. It is passed a pointer
- * to the string and the length of the string. It sets 'value' to the value of
- * the current character. It returns the number of characters read or a
- * negative error code:
- * -1 = string too short
- * -2 = illegal character
- * -3 = subsequent characters not of the form 10xxxxxx
- * -4 = character encoded incorrectly (not minimal length).
+/*
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value
+ * of the current character. It returns the number of characters read or a
+ * negative error code: -1 = string too short -2 = illegal character -3 =
+ * subsequent characters not of the form 10xxxxxx -4 = character encoded
+ * incorrectly (not minimal length).
  */
 
 int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
 {
-	const unsigned char *p;
-	unsigned long value;
-	int ret;
-	if(len <= 0) return 0;
-	p = str;
+    const unsigned char *p;
+    unsigned long value;
+    int ret;
+    if (len <= 0)
+        return 0;
+    p = str;
 
-	/* Check syntax and work out the encoded value (if correct) */
-	if((*p & 0x80) == 0) {
-		value = *p++ & 0x7f;
-		ret = 1;
-	} else if((*p & 0xe0) == 0xc0) {
-		if(len < 2) return -1;
-		if((p[1] & 0xc0) != 0x80) return -3;
-		value = (*p++ & 0x1f) << 6;
-		value |= *p++ & 0x3f;
-		if(value < 0x80) return -4;
-		ret = 2;
-	} else if((*p & 0xf0) == 0xe0) {
-		if(len < 3) return -1;
-		if( ((p[1] & 0xc0) != 0x80)
-		   || ((p[2] & 0xc0) != 0x80) ) return -3;
-		value = (*p++ & 0xf) << 12;
-		value |= (*p++ & 0x3f) << 6;
-		value |= *p++ & 0x3f;
-		if(value < 0x800) return -4;
-		ret = 3;
-	} else if((*p & 0xf8) == 0xf0) {
-		if(len < 4) return -1;
-		if( ((p[1] & 0xc0) != 0x80)
-		   || ((p[2] & 0xc0) != 0x80) 
-		   || ((p[3] & 0xc0) != 0x80) ) return -3;
-		value = ((unsigned long)(*p++ & 0x7)) << 18;
-		value |= (*p++ & 0x3f) << 12;
-		value |= (*p++ & 0x3f) << 6;
-		value |= *p++ & 0x3f;
-		if(value < 0x10000) return -4;
-		ret = 4;
-	} else if((*p & 0xfc) == 0xf8) {
-		if(len < 5) return -1;
-		if( ((p[1] & 0xc0) != 0x80)
-		   || ((p[2] & 0xc0) != 0x80) 
-		   || ((p[3] & 0xc0) != 0x80) 
-		   || ((p[4] & 0xc0) != 0x80) ) return -3;
-		value = ((unsigned long)(*p++ & 0x3)) << 24;
-		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
-		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
-		value |= (*p++ & 0x3f) << 6;
-		value |= *p++ & 0x3f;
-		if(value < 0x200000) return -4;
-		ret = 5;
-	} else if((*p & 0xfe) == 0xfc) {
-		if(len < 6) return -1;
-		if( ((p[1] & 0xc0) != 0x80)
-		   || ((p[2] & 0xc0) != 0x80) 
-		   || ((p[3] & 0xc0) != 0x80) 
-		   || ((p[4] & 0xc0) != 0x80) 
-		   || ((p[5] & 0xc0) != 0x80) ) return -3;
-		value = ((unsigned long)(*p++ & 0x1)) << 30;
-		value |= ((unsigned long)(*p++ & 0x3f)) << 24;
-		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
-		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
-		value |= (*p++ & 0x3f) << 6;
-		value |= *p++ & 0x3f;
-		if(value < 0x4000000) return -4;
-		ret = 6;
-	} else return -2;
-	*val = value;
-	return ret;
+    /* Check syntax and work out the encoded value (if correct) */
+    if ((*p & 0x80) == 0) {
+        value = *p++ & 0x7f;
+        ret = 1;
+    } else if ((*p & 0xe0) == 0xc0) {
+        if (len < 2)
+            return -1;
+        if ((p[1] & 0xc0) != 0x80)
+            return -3;
+        value = (*p++ & 0x1f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x80)
+            return -4;
+        ret = 2;
+    } else if ((*p & 0xf0) == 0xe0) {
+        if (len < 3)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80))
+            return -3;
+        value = (*p++ & 0xf) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x800)
+            return -4;
+        ret = 3;
+    } else if ((*p & 0xf8) == 0xf0) {
+        if (len < 4)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x7)) << 18;
+        value |= (*p++ & 0x3f) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x10000)
+            return -4;
+        ret = 4;
+    } else if ((*p & 0xfc) == 0xf8) {
+        if (len < 5)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x3)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x200000)
+            return -4;
+        ret = 5;
+    } else if ((*p & 0xfe) == 0xfc) {
+        if (len < 6)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80)
+            || ((p[5] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x1)) << 30;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x4000000)
+            return -4;
+        ret = 6;
+    } else
+        return -2;
+    *val = value;
+    return ret;
 }
 
-/* This takes a character 'value' and writes the UTF8 encoded value in
- * 'str' where 'str' is a buffer containing 'len' characters. Returns
- * the number of characters written or -1 if 'len' is too small. 'str' can
- * be set to NULL in which case it just returns the number of characters.
- * It will need at most 6 characters.
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
  */
 
 int UTF8_putc(unsigned char *str, int len, unsigned long value)
 {
-	if(!str) len = 6;	/* Maximum we will need */
-	else if(len <= 0) return -1;
-	if(value < 0x80) {
-		if(str) *str = (unsigned char)value;
-		return 1;
-	}
-	if(value < 0x800) {
-		if(len < 2) return -1;
-		if(str) {
-			*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
-			*str = (unsigned char)((value & 0x3f) | 0x80);
-		}
-		return 2;
-	}
-	if(value < 0x10000) {
-		if(len < 3) return -1;
-		if(str) {
-			*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
-			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-			*str = (unsigned char)((value & 0x3f) | 0x80);
-		}
-		return 3;
-	}
-	if(value < 0x200000) {
-		if(len < 4) return -1;
-		if(str) {
-			*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
-			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-			*str = (unsigned char)((value & 0x3f) | 0x80);
-		}
-		return 4;
-	}
-	if(value < 0x4000000) {
-		if(len < 5) return -1;
-		if(str) {
-			*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
-			*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
-			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-			*str = (unsigned char)((value & 0x3f) | 0x80);
-		}
-		return 5;
-	}
-	if(len < 6) return -1;
-	if(str) {
-		*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
-		*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
-		*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
-		*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-		*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-		*str = (unsigned char)((value & 0x3f) | 0x80);
-	}
-	return 6;
+    if (!str)
+        len = 6;                /* Maximum we will need */
+    else if (len <= 0)
+        return -1;
+    if (value < 0x80) {
+        if (str)
+            *str = (unsigned char)value;
+        return 1;
+    }
+    if (value < 0x800) {
+        if (len < 2)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 2;
+    }
+    if (value < 0x10000) {
+        if (len < 3)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 3;
+    }
+    if (value < 0x200000) {
+        if (len < 4)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 4;
+    }
+    if (value < 0x4000000) {
+        if (len < 5)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+            *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 5;
+    }
+    if (len < 6)
+        return -1;
+    if (str) {
+        *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+        *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+        *str = (unsigned char)((value & 0x3f) | 0x80);
+    }
+    return 6;
 }
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 0f2ce50..b637e79 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -63,12 +63,19 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
-/* Cross-module errors from crypto/x509/i2d_pr.c */
+/* Cross-module errors from crypto/x509/i2d_pr.c. */
 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
 
-/* Cross-module errors from crypto/x509/asn1_gen.c.
- * TODO(davidben): Remove these once asn1_gen.c is gone. */
+/* Cross-module errors from crypto/x509/algorithm.c. */
+OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE);
+/*
+ * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove
+ * these once asn1_gen.c is gone.
+ */
 OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -93,414 +100,406 @@
 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
 
-static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max);
 static void asn1_put_length(unsigned char **pp, int length);
 
 static int _asn1_check_infinite_end(const unsigned char **p, long len)
-	{
-	/* If there is 0 or 1 byte left, the length check should pick
-	 * things up */
-	if (len <= 0)
-		return(1);
-	else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
-		{
-		(*p)+=2;
-		return(1);
-		}
-	return(0);
-	}
+{
+    /*
+     * If there is 0 or 1 byte left, the length check should pick things up
+     */
+    if (len <= 0)
+        return (1);
+    else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+        (*p) += 2;
+        return (1);
+    }
+    return (0);
+}
 
 int ASN1_check_infinite_end(unsigned char **p, long len)
-	{
-	return _asn1_check_infinite_end((const unsigned char **)p, len);
-	}
+{
+    return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
 
 int ASN1_const_check_infinite_end(const unsigned char **p, long len)
-	{
-	return _asn1_check_infinite_end(p, len);
-	}
-
+{
+    return _asn1_check_infinite_end(p, len);
+}
 
 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
-	int *pclass, long omax)
-	{
-	int i,ret;
-	long l;
-	const unsigned char *p= *pp;
-	int tag,xclass,inf;
-	long max=omax;
+                    int *pclass, long omax)
+{
+    int i, ret;
+    long l;
+    const unsigned char *p = *pp;
+    int tag, xclass, inf;
+    long max = omax;
 
-	if (!max) goto err;
-	ret=(*p&V_ASN1_CONSTRUCTED);
-	xclass=(*p&V_ASN1_PRIVATE);
-	i= *p&V_ASN1_PRIMITIVE_TAG;
-	if (i == V_ASN1_PRIMITIVE_TAG)
-		{		/* high-tag */
-		p++;
-		if (--max == 0) goto err;
-		l=0;
-		while (*p&0x80)
-			{
-			l<<=7L;
-			l|= *(p++)&0x7f;
-			if (--max == 0) goto err;
-			if (l > (INT_MAX >> 7L)) goto err;
-			}
-		l<<=7L;
-		l|= *(p++)&0x7f;
-		tag=(int)l;
-		if (--max == 0) goto err;
-		}
-	else
-		{ 
-		tag=i;
-		p++;
-		if (--max == 0) goto err;
-		}
-	*ptag=tag;
-	*pclass=xclass;
-	if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
+    if (!max)
+        goto err;
+    ret = (*p & V_ASN1_CONSTRUCTED);
+    xclass = (*p & V_ASN1_PRIVATE);
+    i = *p & V_ASN1_PRIMITIVE_TAG;
+    if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
+        p++;
+        if (--max == 0)
+            goto err;
+        l = 0;
+        while (*p & 0x80) {
+            l <<= 7L;
+            l |= *(p++) & 0x7f;
+            if (--max == 0)
+                goto err;
+            if (l > (INT_MAX >> 7L))
+                goto err;
+        }
+        l <<= 7L;
+        l |= *(p++) & 0x7f;
+        tag = (int)l;
+        if (--max == 0)
+            goto err;
+    } else {
+        tag = i;
+        p++;
+        if (--max == 0)
+            goto err;
+    }
 
-	if (inf && !(ret & V_ASN1_CONSTRUCTED))
-		goto err;
+    /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
+    if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
+        goto err;
+
+    *ptag = tag;
+    *pclass = xclass;
+    if (!asn1_get_length(&p, &inf, plength, max))
+        goto err;
+
+    if (inf && !(ret & V_ASN1_CONSTRUCTED))
+        goto err;
 
 #if 0
-	fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n", 
-		(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
-		(int)(omax+ *pp));
+    fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n",
+            (int)p, *plength, omax, (int)*pp, (int)(p + *plength),
+            (int)(omax + *pp));
 
 #endif
-	if (*plength > (omax - (p - *pp)))
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-		/* Set this so that even if things are not long enough
-		 * the values are set correctly */
-		ret|=0x80;
-		}
-	*pp=p;
-	return(ret|inf);
-err:
-	OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
-	return(0x80);
-	}
+    if (*plength > (omax - (p - *pp))) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+        /*
+         * Set this so that even if things are not long enough the values are
+         * set correctly
+         */
+        ret |= 0x80;
+    }
+    *pp = p;
+    return (ret | inf);
+ err:
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
+    return (0x80);
+}
 
-static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
-	{
-	const unsigned char *p= *pp;
-	unsigned long ret=0;
-	unsigned int i;
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max)
+{
+    const unsigned char *p = *pp;
+    unsigned long ret = 0;
+    unsigned long i;
 
-	if (max-- < 1) return(0);
-	if (*p == 0x80)
-		{
-		*inf=1;
-		ret=0;
-		p++;
-		}
-	else
-		{
-		*inf=0;
-		i= *p&0x7f;
-		if (*(p++) & 0x80)
-			{
-			if (i > sizeof(long))
-				return 0;
-			if (max-- == 0) return(0);
-			while (i-- > 0)
-				{
-				ret<<=8L;
-				ret|= *(p++);
-				if (max-- == 0) return(0);
-				}
-			}
-		else
-			ret=i;
-		}
-	if (ret > LONG_MAX)
-		return 0;
-	*pp=p;
-	*rl=(long)ret;
-	return(1);
-	}
+    if (max-- < 1)
+        return 0;
+    if (*p == 0x80) {
+        *inf = 1;
+        ret = 0;
+        p++;
+    } else {
+        *inf = 0;
+        i = *p & 0x7f;
+        if (*(p++) & 0x80) {
+            if (i > sizeof(ret) || max < (long)i)
+                return 0;
+            while (i-- > 0) {
+                ret <<= 8L;
+                ret |= *(p++);
+            }
+        } else
+            ret = i;
+    }
+    if (ret > LONG_MAX)
+        return 0;
+    *pp = p;
+    *rl = (long)ret;
+    return 1;
+}
 
-/* class 0 is constructed
- * constructed == 2 for indefinite length constructed */
+/*
+ * class 0 is constructed constructed == 2 for indefinite length constructed
+ */
 void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
-	     int xclass)
-	{
-	unsigned char *p= *pp;
-	int i, ttag;
+                     int xclass)
+{
+    unsigned char *p = *pp;
+    int i, ttag;
 
-	i=(constructed)?V_ASN1_CONSTRUCTED:0;
-	i|=(xclass&V_ASN1_PRIVATE);
-	if (tag < 31)
-		*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
-	else
-		{
-		*(p++)=i|V_ASN1_PRIMITIVE_TAG;
-		for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
-		ttag = i;
-		while(i-- > 0)
-			{
-			p[i] = tag & 0x7f;
-			if(i != (ttag - 1)) p[i] |= 0x80;
-			tag >>= 7;
-			}
-		p += ttag;
-		}
-	if (constructed == 2)
-		*(p++)=0x80;
-	else
-		asn1_put_length(&p,length);
-	*pp=p;
-	}
+    i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+    i |= (xclass & V_ASN1_PRIVATE);
+    if (tag < 31)
+        *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+    else {
+        *(p++) = i | V_ASN1_PRIMITIVE_TAG;
+        for (i = 0, ttag = tag; ttag > 0; i++)
+            ttag >>= 7;
+        ttag = i;
+        while (i-- > 0) {
+            p[i] = tag & 0x7f;
+            if (i != (ttag - 1))
+                p[i] |= 0x80;
+            tag >>= 7;
+        }
+        p += ttag;
+    }
+    if (constructed == 2)
+        *(p++) = 0x80;
+    else
+        asn1_put_length(&p, length);
+    *pp = p;
+}
 
 int ASN1_put_eoc(unsigned char **pp)
-	{
-	unsigned char *p = *pp;
-	*p++ = 0;
-	*p++ = 0;
-	*pp = p;
-	return 2;
-	}
+{
+    unsigned char *p = *pp;
+    *p++ = 0;
+    *p++ = 0;
+    *pp = p;
+    return 2;
+}
 
 static void asn1_put_length(unsigned char **pp, int length)
-	{
-	unsigned char *p= *pp;
-	int i,l;
-	if (length <= 127)
-		*(p++)=(unsigned char)length;
-	else
-		{
-		l=length;
-		for (i=0; l > 0; i++)
-			l>>=8;
-		*(p++)=i|0x80;
-		l=i;
-		while (i-- > 0)
-			{
-			p[i]=length&0xff;
-			length>>=8;
-			}
-		p+=l;
-		}
-	*pp=p;
-	}
+{
+    unsigned char *p = *pp;
+    int i, l;
+    if (length <= 127)
+        *(p++) = (unsigned char)length;
+    else {
+        l = length;
+        for (i = 0; l > 0; i++)
+            l >>= 8;
+        *(p++) = i | 0x80;
+        l = i;
+        while (i-- > 0) {
+            p[i] = length & 0xff;
+            length >>= 8;
+        }
+        p += l;
+    }
+    *pp = p;
+}
 
 int ASN1_object_size(int constructed, int length, int tag)
-	{
-	int ret;
+{
+    int ret;
 
-	ret=length;
-	ret++;
-	if (tag >= 31)
-		{
-		while (tag > 0)
-			{
-			tag>>=7;
-			ret++;
-			}
-		}
-	if (constructed == 2)
-		return ret + 3;
-	ret++;
-	if (length > 127)
-		{
-		while (length > 0)
-			{
-			length>>=8;
-			ret++;
-			}
-		}
-	return(ret);
-	}
+    ret = length;
+    ret++;
+    if (tag >= 31) {
+        while (tag > 0) {
+            tag >>= 7;
+            ret++;
+        }
+    }
+    if (constructed == 2)
+        return ret + 3;
+    ret++;
+    if (length > 127) {
+        while (length > 0) {
+            length >>= 8;
+            ret++;
+        }
+    }
+    return (ret);
+}
 
 static int _asn1_Finish(ASN1_const_CTX *c)
-	{
-	if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
-		{
-		if (!ASN1_const_check_infinite_end(&c->p,c->slen))
-			{
-			c->error=ASN1_R_MISSING_ASN1_EOS;
-			return(0);
-			}
-		}
-	if (	((c->slen != 0) && !(c->inf & 1)) ||
-		((c->slen < 0) && (c->inf & 1)))
-		{
-		c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
-		return(0);
-		}
-	return(1);
-	}
+{
+    if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
+        if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
+            c->error = ASN1_R_MISSING_ASN1_EOS;
+            return (0);
+        }
+    }
+    if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
+        c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
+        return (0);
+    }
+    return (1);
+}
 
 int asn1_Finish(ASN1_CTX *c)
-	{
-	return _asn1_Finish((ASN1_const_CTX *)c);
-	}
+{
+    return _asn1_Finish((ASN1_const_CTX *)c);
+}
 
 int asn1_const_Finish(ASN1_const_CTX *c)
-	{
-	return _asn1_Finish(c);
-	}
+{
+    return _asn1_Finish(c);
+}
 
 int asn1_GetSequence(ASN1_const_CTX *c, long *length)
-	{
-	const unsigned char *q;
+{
+    const unsigned char *q;
 
-	q=c->p;
-	c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
-		*length);
-	if (c->inf & 0x80)
-		{
-		c->error=ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
-		return(0);
-		}
-	if (c->tag != V_ASN1_SEQUENCE)
-		{
-		c->error=ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
-		return(0);
-		}
-	(*length)-=(c->p-q);
-	if (c->max && (*length < 0))
-		{
-		c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
-		return(0);
-		}
-	if (c->inf == (1|V_ASN1_CONSTRUCTED))
-		c->slen= *length+ *(c->pp)-c->p;
-	c->eos=0;
-	return(1);
-	}
+    q = c->p;
+    c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
+                             *length);
+    if (c->inf & 0x80) {
+        c->error = ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
+        return (0);
+    }
+    if (c->tag != V_ASN1_SEQUENCE) {
+        c->error = ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
+        return (0);
+    }
+    (*length) -= (c->p - q);
+    if (c->max && (*length < 0)) {
+        c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
+        return (0);
+    }
+    if (c->inf == (1 | V_ASN1_CONSTRUCTED))
+        c->slen = *length + *(c->pp) - c->p;
+    c->eos = 0;
+    return (1);
+}
 
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
-	{
-	if (str == NULL)
-		return 0;
-	dst->type = str->type;
-	if (!ASN1_STRING_set(dst,str->data,str->length))
-		return 0;
-	dst->flags = str->flags;
-	return 1;
-	}
+{
+    if (str == NULL)
+        return 0;
+    dst->type = str->type;
+    if (!ASN1_STRING_set(dst, str->data, str->length))
+        return 0;
+    dst->flags = str->flags;
+    return 1;
+}
 
 ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
-	{
-	ASN1_STRING *ret;
-	if (!str)
-		 return NULL;
-	ret=ASN1_STRING_new();
-	if (!ret)
-		return NULL;
-	if (!ASN1_STRING_copy(ret,str))
-		{
-		ASN1_STRING_free(ret);
-		return NULL;
-		}
-	return ret;
-	}
+{
+    ASN1_STRING *ret;
+    if (!str)
+        return NULL;
+    ret = ASN1_STRING_new();
+    if (!ret)
+        return NULL;
+    if (!ASN1_STRING_copy(ret, str)) {
+        ASN1_STRING_free(ret);
+        return NULL;
+    }
+    return ret;
+}
 
 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
-	{
-	unsigned char *c;
-	const char *data=_data;
+{
+    unsigned char *c;
+    const char *data = _data;
 
-	if (len < 0)
-		{
-		if (data == NULL)
-			return(0);
-		else
-			len=strlen(data);
-		}
-	if ((str->length < len) || (str->data == NULL))
-		{
-		c=str->data;
-		if (c == NULL)
-			str->data=OPENSSL_malloc(len+1);
-		else
-			str->data=OPENSSL_realloc(c,len+1);
+    if (len < 0) {
+        if (data == NULL)
+            return (0);
+        else
+            len = strlen(data);
+    }
+    if ((str->length < len) || (str->data == NULL)) {
+        c = str->data;
+        if (c == NULL)
+            str->data = OPENSSL_malloc(len + 1);
+        else
+            str->data = OPENSSL_realloc(c, len + 1);
 
-		if (str->data == NULL)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			str->data=c;
-			return(0);
-			}
-		}
-	str->length=len;
-	if (data != NULL)
-		{
-		memcpy(str->data,data,len);
-		/* an allowance for strings :-) */
-		str->data[len]='\0';
-		}
-	return(1);
-	}
+        if (str->data == NULL) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            str->data = c;
+            return (0);
+        }
+    }
+    str->length = len;
+    if (data != NULL) {
+        memcpy(str->data, data, len);
+        /* an allowance for strings :-) */
+        str->data[len] = '\0';
+    }
+    return (1);
+}
 
 void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
-	{
-	if (str->data)
-		OPENSSL_free(str->data);
-	str->data = data;
-	str->length = len;
-	}
+{
+    if (str->data)
+        OPENSSL_free(str->data);
+    str->data = data;
+    str->length = len;
+}
 
 ASN1_STRING *ASN1_STRING_new(void)
-	{
-	return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
-	}
-
+{
+    return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+}
 
 ASN1_STRING *ASN1_STRING_type_new(int type)
-	{
-	ASN1_STRING *ret;
+{
+    ASN1_STRING *ret;
 
-	ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return(NULL);
-		}
-	ret->length=0;
-	ret->type=type;
-	ret->data=NULL;
-	ret->flags=0;
-	return(ret);
-	}
+    ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->length = 0;
+    ret->type = type;
+    ret->data = NULL;
+    ret->flags = 0;
+    return (ret);
+}
 
 void ASN1_STRING_free(ASN1_STRING *a)
-	{
-	if (a == NULL) return;
-	if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
-		OPENSSL_free(a->data);
-	OPENSSL_free(a);
-	}
+{
+    if (a == NULL)
+        return;
+    if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+        OPENSSL_free(a->data);
+    OPENSSL_free(a);
+}
 
 int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
-	{
-	int i;
+{
+    int i;
 
-	i=(a->length-b->length);
-	if (i == 0)
-		{
-		i=memcmp(a->data,b->data,a->length);
-		if (i == 0)
-			return(a->type-b->type);
-		else
-			return(i);
-		}
-	else
-		return(i);
-	}
+    i = (a->length - b->length);
+    if (i == 0) {
+        i = memcmp(a->data, b->data, a->length);
+        if (i == 0)
+            return (a->type - b->type);
+        else
+            return (i);
+    } else
+        return (i);
+}
 
 int ASN1_STRING_length(const ASN1_STRING *x)
-{ return M_ASN1_STRING_length(x); }
+{
+    return M_ASN1_STRING_length(x);
+}
 
 void ASN1_STRING_length_set(ASN1_STRING *x, int len)
-{ M_ASN1_STRING_length_set(x, len); return; }
+{
+    M_ASN1_STRING_length_set(x, len);
+    return;
+}
 
 int ASN1_STRING_type(ASN1_STRING *x)
-{ return M_ASN1_STRING_type(x); }
+{
+    return M_ASN1_STRING_type(x);
+}
 
-unsigned char * ASN1_STRING_data(ASN1_STRING *x)
-{ return M_ASN1_STRING_data(x); }
+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
+{
+    return M_ASN1_STRING_data(x);
+}
diff --git a/src/crypto/asn1/asn1_locl.h b/src/crypto/asn1/asn1_locl.h
index ca5f612..49eceb6 100644
--- a/src/crypto/asn1/asn1_locl.h
+++ b/src/crypto/asn1/asn1_locl.h
@@ -1,6 +1,7 @@
 /* asn1t.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
  */
 /* ====================================================================
  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -63,11 +64,10 @@
 
 /* ASN1 print context structure */
 
-struct asn1_pctx_st
-	{
-	unsigned long flags;
-	unsigned long nm_flags;
-	unsigned long cert_flags;
-	unsigned long oid_flags;
-	unsigned long str_flags;
-	} /* ASN1_PCTX */;
+struct asn1_pctx_st {
+    unsigned long flags;
+    unsigned long nm_flags;
+    unsigned long cert_flags;
+    unsigned long oid_flags;
+    unsigned long str_flags;
+} /* ASN1_PCTX */ ;
diff --git a/src/crypto/asn1/asn1_par.c b/src/crypto/asn1/asn1_par.c
index e04aa1e..d1f6640 100644
--- a/src/crypto/asn1/asn1_par.c
+++ b/src/crypto/asn1/asn1_par.c
@@ -60,385 +60,352 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 #define ASN1_PARSE_MAXDEPTH 128
 
-static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
-	int indent);
-static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
-	int offset, int depth, int indent, int dump);
 static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
-	     int indent)
-	{
-	static const char fmt[]="%-18s";
-	char str[128];
-	const char *p;
+                           int indent);
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+                       int offset, int depth, int indent, int dump);
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+                           int indent)
+{
+    static const char fmt[] = "%-18s";
+    char str[128];
+    const char *p;
 
-	if (constructed & V_ASN1_CONSTRUCTED)
-		p="cons: ";
-	else
-		p="prim: ";
-	if (BIO_write(bp,p,6) < 6) goto err;
-	BIO_indent(bp,indent,128);
+    if (constructed & V_ASN1_CONSTRUCTED)
+        p = "cons: ";
+    else
+        p = "prim: ";
+    if (BIO_write(bp, p, 6) < 6)
+        goto err;
+    BIO_indent(bp, indent, 128);
 
-	p=str;
-	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
-		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
-	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
-		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
-	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
-		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
-	else if (tag > 30)
-		BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
-	else
-		p = ASN1_tag2str(tag);
+    p = str;
+    if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+        BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
+    else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+        BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
+    else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+        BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
+    else if (tag > 30)
+        BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
+    else
+        p = ASN1_tag2str(tag);
 
-	if (BIO_printf(bp,fmt,p) <= 0)
-		goto err;
-	return(1);
-err:
-	return(0);
-	}
+    if (BIO_printf(bp, fmt, p) <= 0)
+        goto err;
+    return (1);
+ err:
+    return (0);
+}
 
 int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
-	{
-	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
-	}
+{
+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
+}
 
-int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
-	{
-	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
-	}
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump)
+{
+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
+}
 
-static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
-	     int depth, int indent, int dump)
-	{
-	const unsigned char *p,*ep,*tot,*op,*opp;
-	long len;
-	int tag,xclass,ret=0;
-	int nl,hl,j,r;
-	ASN1_OBJECT *o=NULL;
-	ASN1_OCTET_STRING *os=NULL;
-	/* ASN1_BMPSTRING *bmp=NULL;*/
-	int dump_indent;
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+                       int offset, int depth, int indent, int dump)
+{
+    const unsigned char *p, *ep, *tot, *op, *opp;
+    long len;
+    int tag, xclass, ret = 0;
+    int nl, hl, j, r;
+    ASN1_OBJECT *o = NULL;
+    ASN1_OCTET_STRING *os = NULL;
+    /* ASN1_BMPSTRING *bmp=NULL; */
+    int dump_indent;
 
 #if 0
-	dump_indent = indent;
+    dump_indent = indent;
 #else
-	dump_indent = 6;	/* Because we know BIO_dump_indent() */
+    dump_indent = 6;            /* Because we know BIO_dump_indent() */
 #endif
 
-	if (depth > ASN1_PARSE_MAXDEPTH)
-		{
-		BIO_puts(bp, "BAD RECURSION DEPTH\n");
-		return 0;
-		}
+    if (depth > ASN1_PARSE_MAXDEPTH) {
+        BIO_puts(bp, "BAD RECURSION DEPTH\n");
+        return 0;
+    }
 
-	p= *pp;
-	tot=p+length;
-	op=p-1;
-	while ((p < tot) && (op < p))
-		{
-		op=p;
-		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
+    p = *pp;
+    tot = p + length;
+    op = p - 1;
+    while ((p < tot) && (op < p)) {
+        op = p;
+        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
 #ifdef LINT
-		j=j;
+        j = j;
 #endif
-		if (j & 0x80)
-			{
-			if (BIO_puts(bp, "Error in encoding\n") <= 0)
-				goto end;
-			ret=0;
-			goto end;
-			}
-		hl=(p-op);
-		length-=hl;
-		/* if j == 0x21 it is a constructed indefinite length object */
-		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
-			<= 0) goto end;
+        if (j & 0x80) {
+            if (BIO_puts(bp, "Error in encoding\n") <= 0)
+                goto end;
+            ret = 0;
+            goto end;
+        }
+        hl = (p - op);
+        length -= hl;
+        /*
+         * if j == 0x21 it is a constructed indefinite length object
+         */
+        if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
+            <= 0)
+            goto end;
 
-		if (j != (V_ASN1_CONSTRUCTED | 1))
-			{
-			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
-				depth,(long)hl,len) <= 0)
-				goto end;
-			}
-		else
-			{
-			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
-				depth,(long)hl) <= 0)
-				goto end;
-			}
-		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
-			goto end;
-		if (j & V_ASN1_CONSTRUCTED)
-			{
-			ep=p+len;
-			if (BIO_puts(bp, "\n") <= 0) goto end;
-			if (len > length)
-				{
-				BIO_printf(bp,
-					"length is greater than %ld\n",length);
-				ret=0;
-				goto end;
-				}
-			if ((j == 0x21) && (len == 0))
-				{
-				for (;;)
-					{
-					r=asn1_parse2(bp,&p,(long)(tot-p),
-						offset+(p - *pp),depth+1,
-						indent,dump);
-					if (r == 0) { ret=0; goto end; }
-					if ((r == 2) || (p >= tot)) break;
-					}
-				}
-			else
-				while (p < ep)
-					{
-					r=asn1_parse2(bp,&p,(long)len,
-						offset+(p - *pp),depth+1,
-						indent,dump);
-					if (r == 0) { ret=0; goto end; }
-					}
-			}
-		else if (xclass != 0)
-			{
-			p+=len;
-			if (BIO_puts(bp, "\n") <= 0) goto end;
-			}
-		else
-			{
-			nl=0;
-			if (	(tag == V_ASN1_PRINTABLESTRING) ||
-				(tag == V_ASN1_T61STRING) ||
-				(tag == V_ASN1_IA5STRING) ||
-				(tag == V_ASN1_VISIBLESTRING) ||
-				(tag == V_ASN1_NUMERICSTRING) ||
-				(tag == V_ASN1_UTF8STRING) ||
-				(tag == V_ASN1_UTCTIME) ||
-				(tag == V_ASN1_GENERALIZEDTIME))
-				{
-				if (BIO_puts(bp, ":") <= 0) goto end;
-				if ((len > 0) &&
-					BIO_write(bp,(const char *)p,(int)len)
-					!= (int)len)
-					goto end;
-				}
-			else if (tag == V_ASN1_OBJECT)
-				{
-				opp=op;
-				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
-					{
-					if (BIO_puts(bp, ":") <= 0) goto end;
-					i2a_ASN1_OBJECT(bp,o);
-					}
-				else
-					{
-					if (BIO_puts(bp, ":BAD OBJECT") <= 0)
-						goto end;
-					}
-				}
-			else if (tag == V_ASN1_BOOLEAN)
-				{
-				int ii;
+        if (j != (V_ASN1_CONSTRUCTED | 1)) {
+            if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
+                           depth, (long)hl, len) <= 0)
+                goto end;
+        } else {
+            if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ", depth, (long)hl) <= 0)
+                goto end;
+        }
+        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+            goto end;
+        if (j & V_ASN1_CONSTRUCTED) {
+            const unsigned char *sp;
 
-				opp=op;
-				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
-				if (ii < 0)
-					{
-					if (BIO_puts(bp, "Bad boolean\n") <= 0)
-						goto end;
-					}
-				BIO_printf(bp,":%d",ii);
-				}
-			else if (tag == V_ASN1_BMPSTRING)
-				{
-				/* do the BMP thang */
-				}
-			else if (tag == V_ASN1_OCTET_STRING)
-				{
-				int i,printable=1;
+            ep = p + len;
+            if (BIO_puts(bp, "\n") <= 0)
+                goto end;
+            if (len > length) {
+                BIO_printf(bp, "length is greater than %ld\n", length);
+                ret = 0;
+                goto end;
+            }
+            if ((j == 0x21) && (len == 0)) {
+                sp = p;
+                for (;;) {
+                    r = asn1_parse2(bp, &p, (long)(tot - p),
+                                    offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    if ((r == 2) || (p >= tot)) {
+                        len = p - sp;
+                        break;
+                    }
+                }
+            } else {
+                long tmp = len;
 
-				opp=op;
-				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
-				if (os != NULL && os->length > 0)
-					{
-					opp = os->data;
-					/* testing whether the octet string is
-					 * printable */
-					for (i=0; i<os->length; i++)
-						{
-						if ((	(opp[i] < ' ') &&
-							(opp[i] != '\n') &&
-							(opp[i] != '\r') &&
-							(opp[i] != '\t')) ||
-							(opp[i] > '~'))
-							{
-							printable=0;
-							break;
-							}
-						}
-					if (printable)
-					/* printable string */
-						{
-						if (BIO_puts(bp, ":") <= 0)
-							goto end;
-						if (BIO_write(bp,(const char *)opp,
-							os->length) <= 0)
-							goto end;
-						}
-					else if (!dump)
-					/* not printable => print octet string
-					 * as hex dump */
-						{
-						if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
-							goto end;
-						for (i=0; i<os->length; i++)
-							{
-							if (BIO_printf(bp,"%02X"
-								, opp[i]) <= 0)
-								goto end;
-							}
-						}
-					else
-					/* print the normal dump */
-						{
-						if (!nl) 
-							{
-							if (BIO_puts(bp, "\n") <= 0)
-								goto end;
-							}
-						if (!BIO_hexdump(bp, opp,
-							((dump == -1 || dump > 
-							os->length)?os->length:dump),
-							dump_indent))
-							goto end;
-						nl=1;
-						}
-					}
-				if (os != NULL)
-					{
-					M_ASN1_OCTET_STRING_free(os);
-					os=NULL;
-					}
-				}
-			else if (tag == V_ASN1_INTEGER)
-				{
-				ASN1_INTEGER *bs;
-				int i;
+                while (p < ep) {
+                    sp = p;
+                    r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    tmp -= p - sp;
+                }
+            }
+        } else if (xclass != 0) {
+            p += len;
+            if (BIO_puts(bp, "\n") <= 0)
+                goto end;
+        } else {
+            nl = 0;
+            if ((tag == V_ASN1_PRINTABLESTRING) ||
+                (tag == V_ASN1_T61STRING) ||
+                (tag == V_ASN1_IA5STRING) ||
+                (tag == V_ASN1_VISIBLESTRING) ||
+                (tag == V_ASN1_NUMERICSTRING) ||
+                (tag == V_ASN1_UTF8STRING) ||
+                (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
+                if (BIO_puts(bp, ":") <= 0)
+                    goto end;
+                if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
+                    != (int)len)
+                    goto end;
+            } else if (tag == V_ASN1_OBJECT) {
+                opp = op;
+                if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
+                    if (BIO_puts(bp, ":") <= 0)
+                        goto end;
+                    i2a_ASN1_OBJECT(bp, o);
+                } else {
+                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
+                        goto end;
+                }
+            } else if (tag == V_ASN1_BOOLEAN) {
+                int ii;
 
-				opp=op;
-				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
-				if (bs != NULL)
-					{
-					if (BIO_puts(bp, ":") <= 0) goto end;
-					if (bs->type == V_ASN1_NEG_INTEGER)
-						if (BIO_puts(bp, "-") <= 0)
-							goto end;
-					for (i=0; i<bs->length; i++)
-						{
-						if (BIO_printf(bp,"%02X",
-							bs->data[i]) <= 0)
-							goto end;
-						}
-					if (bs->length == 0)
-						{
-						if (BIO_puts(bp, "00") <= 0)
-							goto end;
-						}
-					}
-				else
-					{
-					if (BIO_puts(bp, "BAD INTEGER") <= 0)
-						goto end;
-					}
-				M_ASN1_INTEGER_free(bs);
-				}
-			else if (tag == V_ASN1_ENUMERATED)
-				{
-				ASN1_ENUMERATED *bs;
-				int i;
+                opp = op;
+                ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
+                if (ii < 0) {
+                    if (BIO_puts(bp, "Bad boolean\n") <= 0)
+                        goto end;
+                }
+                BIO_printf(bp, ":%d", ii);
+            } else if (tag == V_ASN1_BMPSTRING) {
+                /* do the BMP thang */
+            } else if (tag == V_ASN1_OCTET_STRING) {
+                int i, printable = 1;
 
-				opp=op;
-				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
-				if (bs != NULL)
-					{
-					if (BIO_puts(bp, ":") <= 0) goto end;
-					if (bs->type == V_ASN1_NEG_ENUMERATED)
-						if (BIO_puts(bp, "-") <= 0)
-							goto end;
-					for (i=0; i<bs->length; i++)
-						{
-						if (BIO_printf(bp,"%02X",
-							bs->data[i]) <= 0)
-							goto end;
-						}
-					if (bs->length == 0)
-						{
-						if (BIO_puts(bp, "00") <= 0)
-							goto end;
-						}
-					}
-				else
-					{
-					if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
-						goto end;
-					}
-				M_ASN1_ENUMERATED_free(bs);
-				}
-			else if (len > 0 && dump)
-				{
-				if (!nl) 
-					{
-					if (BIO_puts(bp, "\n") <= 0)
-						goto end;
-					}
-				if (!BIO_hexdump(bp,p,
-					((dump == -1 || dump > len)?len:dump),
-					dump_indent))
-					goto end;
-				nl=1;
-				}
+                opp = op;
+                os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+                if (os != NULL && os->length > 0) {
+                    opp = os->data;
+                    /*
+                     * testing whether the octet string is printable
+                     */
+                    for (i = 0; i < os->length; i++) {
+                        if (((opp[i] < ' ') &&
+                             (opp[i] != '\n') &&
+                             (opp[i] != '\r') &&
+                             (opp[i] != '\t')) || (opp[i] > '~')) {
+                            printable = 0;
+                            break;
+                        }
+                    }
+                    if (printable)
+                        /* printable string */
+                    {
+                        if (BIO_puts(bp, ":") <= 0)
+                            goto end;
+                        if (BIO_write(bp, (const char *)opp, os->length) <= 0)
+                            goto end;
+                    } else if (!dump)
+                        /*
+                         * not printable => print octet string as hex dump
+                         */
+                    {
+                        if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
+                            goto end;
+                        for (i = 0; i < os->length; i++) {
+                            if (BIO_printf(bp, "%02X", opp[i]) <= 0)
+                                goto end;
+                        }
+                    } else
+                        /* print the normal dump */
+                    {
+                        if (!nl) {
+                            if (BIO_puts(bp, "\n") <= 0)
+                                goto end;
+                        }
+                        if (!BIO_hexdump(bp, opp,
+                                         ((dump == -1 || dump >
+                                           os->length) ? os->length : dump),
+                                         dump_indent))
+                            goto end;
+                        nl = 1;
+                    }
+                }
+                if (os != NULL) {
+                    M_ASN1_OCTET_STRING_free(os);
+                    os = NULL;
+                }
+            } else if (tag == V_ASN1_INTEGER) {
+                ASN1_INTEGER *bs;
+                int i;
 
-			if (!nl) 
-				{
-				if (BIO_puts(bp, "\n") <= 0) goto end;
-				}
-			p+=len;
-			if ((tag == V_ASN1_EOC) && (xclass == 0))
-				{
-				ret=2; /* End of sequence */
-				goto end;
-				}
-			}
-		length-=len;
-		}
-	ret=1;
-end:
-	if (o != NULL) ASN1_OBJECT_free(o);
-	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
-	*pp=p;
-	return(ret);
-	}
+                opp = op;
+                bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+                if (bs != NULL) {
+                    if (BIO_puts(bp, ":") <= 0)
+                        goto end;
+                    if (bs->type == V_ASN1_NEG_INTEGER)
+                        if (BIO_puts(bp, "-") <= 0)
+                            goto end;
+                    for (i = 0; i < bs->length; i++) {
+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (bs->length == 0) {
+                        if (BIO_puts(bp, "00") <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, "BAD INTEGER") <= 0)
+                        goto end;
+                }
+                M_ASN1_INTEGER_free(bs);
+            } else if (tag == V_ASN1_ENUMERATED) {
+                ASN1_ENUMERATED *bs;
+                int i;
+
+                opp = op;
+                bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+                if (bs != NULL) {
+                    if (BIO_puts(bp, ":") <= 0)
+                        goto end;
+                    if (bs->type == V_ASN1_NEG_ENUMERATED)
+                        if (BIO_puts(bp, "-") <= 0)
+                            goto end;
+                    for (i = 0; i < bs->length; i++) {
+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (bs->length == 0) {
+                        if (BIO_puts(bp, "00") <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
+                        goto end;
+                }
+                M_ASN1_ENUMERATED_free(bs);
+            } else if (len > 0 && dump) {
+                if (!nl) {
+                    if (BIO_puts(bp, "\n") <= 0)
+                        goto end;
+                }
+                if (!BIO_hexdump(bp, p,
+                                 ((dump == -1 || dump > len) ? len : dump),
+                                 dump_indent))
+                    goto end;
+                nl = 1;
+            }
+
+            if (!nl) {
+                if (BIO_puts(bp, "\n") <= 0)
+                    goto end;
+            }
+            p += len;
+            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+                ret = 2;        /* End of sequence */
+                goto end;
+            }
+        }
+        length -= len;
+    }
+    ret = 1;
+ end:
+    if (o != NULL)
+        ASN1_OBJECT_free(o);
+    if (os != NULL)
+        M_ASN1_OCTET_STRING_free(os);
+    *pp = p;
+    return (ret);
+}
 
 const char *ASN1_tag2str(int tag)
 {
-	static const char * const tag2str[] = {
-	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
-	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
-	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
-	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
-	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
-	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
-	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
-	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
-	};
+    static const char *const tag2str[] = {
+        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
+        "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
+        "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
+        "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
+        "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
+        "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24
+                                                                      */
+        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
+        "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
+    };
 
-	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
-							tag &= ~0x100;
+    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+        tag &= ~0x100;
 
-	if(tag < 0 || tag > 30) return "(unknown)";
-	return tag2str[tag];
+    if (tag < 0 || tag > 30)
+        return "(unknown)";
+    return tag2str[tag];
 }
-
diff --git a/src/crypto/asn1/asn1_test.cc b/src/crypto/asn1/asn1_test.cc
new file mode 100644
index 0000000..8b02442
--- /dev/null
+++ b/src/crypto/asn1/asn1_test.cc
@@ -0,0 +1,81 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+
+#include <openssl/asn1.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include "../test/scoped_types.h"
+
+
+// kTag128 is an ASN.1 structure with a universal tag with number 128.
+static const uint8_t kTag128[] = {
+    0x1f, 0x81, 0x00, 0x01, 0x00,
+};
+
+// kTag258 is an ASN.1 structure with a universal tag with number 258.
+static const uint8_t kTag258[] = {
+    0x1f, 0x82, 0x02, 0x01, 0x00,
+};
+
+static_assert(V_ASN1_NEG_INTEGER == 258,
+              "V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it.");
+
+// kTagOverflow is an ASN.1 structure with a universal tag with number 2^35-1,
+// which will not fit in an int.
+static const uint8_t kTagOverflow[] = {
+    0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01, 0x00,
+};
+
+static bool TestLargeTags() {
+  const uint8_t *p = kTag258;
+  ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
+  if (obj) {
+    fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
+    return false;
+  }
+  ERR_clear_error();
+
+  p = kTagOverflow;
+  obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow)));
+  if (obj) {
+    fprintf(stderr, "Parsed value with tag overflow (type = %d).\n", obj->type);
+    return false;
+  }
+  ERR_clear_error();
+
+  p = kTag128;
+  obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128)));
+  if (!obj || obj->type != 128 || obj->value.asn1_string->length != 1 ||
+      obj->value.asn1_string->data[0] != 0) {
+    fprintf(stderr, "Failed to parse value with tag 128.\n");
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  return true;
+}
+
+int main() {
+  CRYPTO_library_init();
+
+  if (!TestLargeTags()) {
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/asn1/asn_pack.c b/src/crypto/asn1/asn_pack.c
index e842a10..eff54e5 100644
--- a/src/crypto/asn1/asn_pack.c
+++ b/src/crypto/asn1/asn_pack.c
@@ -59,46 +59,47 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 /* ASN1_ITEM versions of the above */
 
 ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
 {
-	ASN1_STRING *octmp;
+    ASN1_STRING *octmp;
 
-	if (!oct || !*oct) {
-		if (!(octmp = ASN1_STRING_new ())) {
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return NULL;
-		}
-		if (oct) *oct = octmp;
-	} else octmp = *oct;
+    if (!oct || !*oct) {
+        if (!(octmp = ASN1_STRING_new())) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        if (oct)
+            *oct = octmp;
+    } else
+        octmp = *oct;
 
-	if(octmp->data) {
-		OPENSSL_free(octmp->data);
-		octmp->data = NULL;
-	}
-		
-	if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
-		return NULL;
-	}
-	if (!octmp->data) {
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	return octmp;
+    if (octmp->data) {
+        OPENSSL_free(octmp->data);
+        octmp->data = NULL;
+    }
+
+    if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
+        return NULL;
+    }
+    if (!octmp->data) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    return octmp;
 }
 
 /* Extract an ASN1 object from an ASN1_STRING */
 
 void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
 {
-	const unsigned char *p;
-	void *ret;
+    const unsigned char *p;
+    void *ret;
 
-	p = oct->data;
-	if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
-	return ret;
+    p = oct->data;
+    if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
+    return ret;
 }
diff --git a/src/crypto/asn1/bio_asn1.c b/src/crypto/asn1/bio_asn1.c
index 15f233b..03cc9a6 100644
--- a/src/crypto/asn1/bio_asn1.c
+++ b/src/crypto/asn1/bio_asn1.c
@@ -62,53 +62,48 @@
 #include <openssl/bio.h>
 #include <openssl/mem.h>
 
-
 /* Must be large enough for biggest tag+length */
 #define DEFAULT_ASN1_BUF_SIZE 20
 
-typedef enum 
-	{
-	ASN1_STATE_START,
-	ASN1_STATE_PRE_COPY,
-	ASN1_STATE_HEADER,
-	ASN1_STATE_HEADER_COPY,
-	ASN1_STATE_DATA_COPY,
-	ASN1_STATE_POST_COPY,
-	ASN1_STATE_DONE
-	} asn1_bio_state_t;
+typedef enum {
+    ASN1_STATE_START,
+    ASN1_STATE_PRE_COPY,
+    ASN1_STATE_HEADER,
+    ASN1_STATE_HEADER_COPY,
+    ASN1_STATE_DATA_COPY,
+    ASN1_STATE_POST_COPY,
+    ASN1_STATE_DONE
+} asn1_bio_state_t;
 
-typedef struct BIO_ASN1_EX_FUNCS_st
-	{
-	asn1_ps_func	*ex_func;
-	asn1_ps_func	*ex_free_func;
-	} BIO_ASN1_EX_FUNCS;
+typedef struct BIO_ASN1_EX_FUNCS_st {
+    asn1_ps_func *ex_func;
+    asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
 
-typedef struct BIO_ASN1_BUF_CTX_t
-	{
-	/* Internal state */
-	asn1_bio_state_t state;
-	/* Internal buffer */
-	unsigned char *buf;
-	/* Size of buffer */
-	int bufsize;
-	/* Current position in buffer */
-	int bufpos;
-	/* Current buffer length */
-	int buflen;
-	/* Amount of data to copy */
-	int copylen;
-	/* Class and tag to use */
-	int asn1_class, asn1_tag;
-	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
-	/* Extra buffer for prefix and suffix data */
-	unsigned char *ex_buf;
-	int ex_len;
-	int ex_pos;
-	void *ex_arg;
-	} BIO_ASN1_BUF_CTX;
+typedef struct BIO_ASN1_BUF_CTX_t {
+    /* Internal state */
+    asn1_bio_state_t state;
+    /* Internal buffer */
+    unsigned char *buf;
+    /* Size of buffer */
+    int bufsize;
+    /* Current position in buffer */
+    int bufpos;
+    /* Current buffer length */
+    int buflen;
+    /* Amount of data to copy */
+    int copylen;
+    /* Class and tag to use */
+    int asn1_class, asn1_tag;
+    asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+    /* Extra buffer for prefix and suffix data */
+    unsigned char *ex_buf;
+    int ex_len;
+    int ex_pos;
+    void *ex_arg;
+} BIO_ASN1_BUF_CTX;
 
-
-static int asn1_bio_write(BIO *h, const char *buf,int num);
+static int asn1_bio_write(BIO *h, const char *buf, int num);
 static int asn1_bio_read(BIO *h, char *buf, int size);
 static int asn1_bio_puts(BIO *h, const char *str);
 static int asn1_bio_gets(BIO *h, char *str, int size);
@@ -119,378 +114,364 @@
 
 static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
 static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-				asn1_ps_func *cleanup, asn1_bio_state_t next);
+                             asn1_ps_func *cleanup, asn1_bio_state_t next);
 static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-				asn1_ps_func *setup, 
-				asn1_bio_state_t ex_state,
-				asn1_bio_state_t other_state);
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state);
 
-static const BIO_METHOD methods_asn1=
-	{
-	BIO_TYPE_ASN1,
-	"asn1",
-	asn1_bio_write,
-	asn1_bio_read,
-	asn1_bio_puts,
-	asn1_bio_gets,
-	asn1_bio_ctrl,
-	asn1_bio_new,
-	asn1_bio_free,
-	asn1_bio_callback_ctrl,
-	};
+static const BIO_METHOD methods_asn1 = {
+    BIO_TYPE_ASN1,
+    "asn1",
+    asn1_bio_write,
+    asn1_bio_read,
+    asn1_bio_puts,
+    asn1_bio_gets,
+    asn1_bio_ctrl,
+    asn1_bio_new,
+    asn1_bio_free,
+    asn1_bio_callback_ctrl,
+};
 
 const BIO_METHOD *BIO_f_asn1(void)
-	{
-	return(&methods_asn1);
-	}
-
+{
+    return (&methods_asn1);
+}
 
 static int asn1_bio_new(BIO *b)
-	{
-	BIO_ASN1_BUF_CTX *ctx;
-	ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
-	if (!ctx)
-		return 0;
-	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
-		{
-		OPENSSL_free(ctx);
-		return 0;
-		}
-	b->init = 1;
-	b->ptr = (char *)ctx;
-	b->flags = 0;
-	return 1;
-	}
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+    if (!ctx)
+        return 0;
+    if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    b->init = 1;
+    b->ptr = (char *)ctx;
+    b->flags = 0;
+    return 1;
+}
 
 static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
-	{
-	ctx->buf = OPENSSL_malloc(size);
-	if (!ctx->buf)
-		return 0;
-	ctx->bufsize = size;
-	ctx->bufpos = 0;
-	ctx->buflen = 0;
-	ctx->copylen = 0;
-	ctx->asn1_class = V_ASN1_UNIVERSAL;
-	ctx->asn1_tag = V_ASN1_OCTET_STRING;
-	ctx->ex_buf = 0;
-	ctx->ex_pos = 0;
-	ctx->ex_len = 0;
-	ctx->state = ASN1_STATE_START;
-	return 1;
-	}
+{
+    ctx->buf = OPENSSL_malloc(size);
+    if (!ctx->buf)
+        return 0;
+    ctx->bufsize = size;
+    ctx->bufpos = 0;
+    ctx->buflen = 0;
+    ctx->copylen = 0;
+    ctx->asn1_class = V_ASN1_UNIVERSAL;
+    ctx->asn1_tag = V_ASN1_OCTET_STRING;
+    ctx->ex_buf = 0;
+    ctx->ex_pos = 0;
+    ctx->ex_len = 0;
+    ctx->state = ASN1_STATE_START;
+    return 1;
+}
 
 static int asn1_bio_free(BIO *b)
-	{
-	BIO_ASN1_BUF_CTX *ctx;
-	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
-	if (ctx == NULL)
-		return 0;
-	if (ctx->buf)
-		OPENSSL_free(ctx->buf);
-	OPENSSL_free(ctx);
-	b->init = 0;
-	b->ptr = NULL;
-	b->flags = 0;
-	return 1;
-	}
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
+    if (ctx->buf)
+        OPENSSL_free(ctx->buf);
+    OPENSSL_free(ctx);
+    b->init = 0;
+    b->ptr = NULL;
+    b->flags = 0;
+    return 1;
+}
 
-static int asn1_bio_write(BIO *b, const char *in , int inl)
-	{
-	BIO_ASN1_BUF_CTX *ctx;
-	int wrmax, wrlen, ret;
-	unsigned char *p;
-	if (!in || (inl < 0) || (b->next_bio == NULL))
-		return 0;
-	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
-	if (ctx == NULL)
-		return 0;
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    int wrmax, wrlen, ret;
+    unsigned char *p;
+    if (!in || (inl < 0) || (b->next_bio == NULL))
+        return 0;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
 
-	wrlen = 0;
-	ret = -1;
+    wrlen = 0;
+    ret = -1;
 
-	for(;;)
-		{
-		switch (ctx->state)
-			{
+    for (;;) {
+        switch (ctx->state) {
 
-			/* Setup prefix data, call it */
-			case ASN1_STATE_START:
-			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
-				ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
-				return 0;
-			break;
+            /* Setup prefix data, call it */
+        case ASN1_STATE_START:
+            if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+                                   ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+                return 0;
+            break;
 
-			/* Copy any pre data first */
-			case ASN1_STATE_PRE_COPY:
+            /* Copy any pre data first */
+        case ASN1_STATE_PRE_COPY:
 
-			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
-							ASN1_STATE_HEADER);
+            ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+                                    ASN1_STATE_HEADER);
 
-			if (ret <= 0)
-				goto done;
+            if (ret <= 0)
+                goto done;
 
-			break;
+            break;
 
-			case ASN1_STATE_HEADER:
-			ctx->buflen =
-				ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
-			assert(ctx->buflen <= ctx->bufsize);
-			p = ctx->buf;
-			ASN1_put_object(&p, 0, inl,
-					ctx->asn1_tag, ctx->asn1_class);
-			ctx->copylen = inl;
-			ctx->state = ASN1_STATE_HEADER_COPY;
+        case ASN1_STATE_HEADER:
+            ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+            assert(ctx->buflen <= ctx->bufsize);
+            p = ctx->buf;
+            ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+            ctx->copylen = inl;
+            ctx->state = ASN1_STATE_HEADER_COPY;
 
-			break;
+            break;
 
-			case ASN1_STATE_HEADER_COPY:	
-			ret = BIO_write(b->next_bio,
-					ctx->buf + ctx->bufpos, ctx->buflen);
-			if (ret <= 0)
-				goto done;
+        case ASN1_STATE_HEADER_COPY:
+            ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
+            if (ret <= 0)
+                goto done;
 
-			ctx->buflen -= ret;
-			if (ctx->buflen)
-				ctx->bufpos += ret;
-			else
-				{
-				ctx->bufpos = 0;
-				ctx->state = ASN1_STATE_DATA_COPY;
-				}
+            ctx->buflen -= ret;
+            if (ctx->buflen)
+                ctx->bufpos += ret;
+            else {
+                ctx->bufpos = 0;
+                ctx->state = ASN1_STATE_DATA_COPY;
+            }
 
-			break;
+            break;
 
-			case ASN1_STATE_DATA_COPY:
+        case ASN1_STATE_DATA_COPY:
 
-			if (inl > ctx->copylen)
-				wrmax = ctx->copylen;
-			else
-				wrmax = inl;
-			ret = BIO_write(b->next_bio, in, wrmax);
-			if (ret <= 0)
-				break;
-			wrlen += ret;
-			ctx->copylen -= ret;
-			in += ret;
-			inl -= ret;
+            if (inl > ctx->copylen)
+                wrmax = ctx->copylen;
+            else
+                wrmax = inl;
+            ret = BIO_write(b->next_bio, in, wrmax);
+            if (ret <= 0)
+                break;
+            wrlen += ret;
+            ctx->copylen -= ret;
+            in += ret;
+            inl -= ret;
 
-			if (ctx->copylen == 0)
-				ctx->state = ASN1_STATE_HEADER;
+            if (ctx->copylen == 0)
+                ctx->state = ASN1_STATE_HEADER;
 
-			if (inl == 0)
-				goto done;
+            if (inl == 0)
+                goto done;
 
-			break;
+            break;
 
-			default:
-			BIO_clear_retry_flags(b);
-			return 0;
+        default:
+            BIO_clear_retry_flags(b);
+            return 0;
 
-			}
+        }
 
-		}
+    }
 
-	done:
-	BIO_clear_retry_flags(b);
-	BIO_copy_next_retry(b);
+ done:
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
 
-	return (wrlen > 0) ? wrlen : ret;
+    return (wrlen > 0) ? wrlen : ret;
 
-	}
+}
 
 static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-				asn1_ps_func *cleanup, asn1_bio_state_t next)
-	{
-	int ret;
-	if (ctx->ex_len <= 0)
-		return 1;
-	for(;;)
-		{
-		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
-								ctx->ex_len);
-		if (ret <= 0)
-			break;
-		ctx->ex_len -= ret;
-		if (ctx->ex_len > 0)
-			ctx->ex_pos += ret;
-		else
-			{
-			if(cleanup)
-				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
-								&ctx->ex_arg);
-			ctx->state = next;
-			ctx->ex_pos = 0;
-			break;
-			}
-		}
-	return ret;
-	}
+                             asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+    int ret;
+    if (ctx->ex_len <= 0)
+        return 1;
+    for (;;) {
+        ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+        if (ret <= 0)
+            break;
+        ctx->ex_len -= ret;
+        if (ctx->ex_len > 0)
+            ctx->ex_pos += ret;
+        else {
+            if (cleanup)
+                cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+            ctx->state = next;
+            ctx->ex_pos = 0;
+            break;
+        }
+    }
+    return ret;
+}
 
 static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-				asn1_ps_func *setup, 
-				asn1_bio_state_t ex_state,
-				asn1_bio_state_t other_state)
-	{
-	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
-		{
-		BIO_clear_retry_flags(b);
-		return 0;
-		}
-	if (ctx->ex_len > 0)
-		ctx->state = ex_state;
-	else
-		ctx->state = other_state;
-	return 1;
-	}
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state)
+{
+    if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+        BIO_clear_retry_flags(b);
+        return 0;
+    }
+    if (ctx->ex_len > 0)
+        ctx->state = ex_state;
+    else
+        ctx->state = other_state;
+    return 1;
+}
 
-static int asn1_bio_read(BIO *b, char *in , int inl)
-	{
-	if (!b->next_bio)
-		return 0;
-	return BIO_read(b->next_bio, in , inl);
-	}
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+    if (!b->next_bio)
+        return 0;
+    return BIO_read(b->next_bio, in, inl);
+}
 
 static int asn1_bio_puts(BIO *b, const char *str)
-	{
-	return asn1_bio_write(b, str, strlen(str));
-	}
+{
+    return asn1_bio_write(b, str, strlen(str));
+}
 
 static int asn1_bio_gets(BIO *b, char *str, int size)
-	{
-	if (!b->next_bio)
-		return 0;
-	return BIO_gets(b->next_bio, str , size);
-	}
+{
+    if (!b->next_bio)
+        return 0;
+    return BIO_gets(b->next_bio, str, size);
+}
 
 static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb fp)
-	{
-	if (b->next_bio == NULL) return(0);
-	return BIO_callback_ctrl(b->next_bio,cmd,fp);
-	}
+{
+    if (b->next_bio == NULL)
+        return (0);
+    return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
 
 static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
-	{
-	BIO_ASN1_BUF_CTX *ctx;
-	BIO_ASN1_EX_FUNCS *ex_func;
-	long ret = 1;
-	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
-	if (ctx == NULL)
-		return 0;
-	switch(cmd)
-		{
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    BIO_ASN1_EX_FUNCS *ex_func;
+    long ret = 1;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
+    switch (cmd) {
 
-		case BIO_C_SET_PREFIX:
-		ex_func = arg2;
-		ctx->prefix  = ex_func->ex_func;
-		ctx->prefix_free  = ex_func->ex_free_func;
-		break;
+    case BIO_C_SET_PREFIX:
+        ex_func = arg2;
+        ctx->prefix = ex_func->ex_func;
+        ctx->prefix_free = ex_func->ex_free_func;
+        break;
 
-		case BIO_C_GET_PREFIX:
-		ex_func = arg2;
-		ex_func->ex_func = ctx->prefix;
-		ex_func->ex_free_func = ctx->prefix_free;
-		break;
+    case BIO_C_GET_PREFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->prefix;
+        ex_func->ex_free_func = ctx->prefix_free;
+        break;
 
-		case BIO_C_SET_SUFFIX:
-		ex_func = arg2;
-		ctx->suffix  = ex_func->ex_func;
-		ctx->suffix_free  = ex_func->ex_free_func;
-		break;
+    case BIO_C_SET_SUFFIX:
+        ex_func = arg2;
+        ctx->suffix = ex_func->ex_func;
+        ctx->suffix_free = ex_func->ex_free_func;
+        break;
 
-		case BIO_C_GET_SUFFIX:
-		ex_func = arg2;
-		ex_func->ex_func = ctx->suffix;
-		ex_func->ex_free_func = ctx->suffix_free;
-		break;
+    case BIO_C_GET_SUFFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->suffix;
+        ex_func->ex_free_func = ctx->suffix_free;
+        break;
 
-		case BIO_C_SET_EX_ARG:
-		ctx->ex_arg = arg2;
-		break;
+    case BIO_C_SET_EX_ARG:
+        ctx->ex_arg = arg2;
+        break;
 
-		case BIO_C_GET_EX_ARG:
-		*(void **)arg2 = ctx->ex_arg;
-		break;
+    case BIO_C_GET_EX_ARG:
+        *(void **)arg2 = ctx->ex_arg;
+        break;
 
-		case BIO_CTRL_FLUSH:
-		if (!b->next_bio)
-			return 0;
+    case BIO_CTRL_FLUSH:
+        if (!b->next_bio)
+            return 0;
 
-		/* Call post function if possible */
-		if (ctx->state == ASN1_STATE_HEADER)
-			{
-			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
-				ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
-				return 0;
-			}
+        /* Call post function if possible */
+        if (ctx->state == ASN1_STATE_HEADER) {
+            if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+                                   ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+                return 0;
+        }
 
-		if (ctx->state == ASN1_STATE_POST_COPY)
-			{
-			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
-							ASN1_STATE_DONE);
-			if (ret <= 0)
-				return ret;
-			}
+        if (ctx->state == ASN1_STATE_POST_COPY) {
+            ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+                                    ASN1_STATE_DONE);
+            if (ret <= 0)
+                return ret;
+        }
 
-		if (ctx->state == ASN1_STATE_DONE)
-			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
-		else
-			{
-			BIO_clear_retry_flags(b);
-			return 0;
-			}
-		break;
+        if (ctx->state == ASN1_STATE_DONE)
+            return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+        else {
+            BIO_clear_retry_flags(b);
+            return 0;
+        }
+        break;
 
+    default:
+        if (!b->next_bio)
+            return 0;
+        return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
 
-		default:
-		if (!b->next_bio)
-			return 0;
-		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+    }
 
-		}
-
-	return ret;
-	}
+    return ret;
+}
 
 static int asn1_bio_set_ex(BIO *b, int cmd,
-		asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
-	{
-	BIO_ASN1_EX_FUNCS extmp;
-	extmp.ex_func = ex_func;
-	extmp.ex_free_func = ex_free_func;
-	return BIO_ctrl(b, cmd, 0, &extmp);
-	}
+                           asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    extmp.ex_func = ex_func;
+    extmp.ex_free_func = ex_free_func;
+    return BIO_ctrl(b, cmd, 0, &extmp);
+}
 
 static int asn1_bio_get_ex(BIO *b, int cmd,
-		asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
-	{
-	BIO_ASN1_EX_FUNCS extmp;
-	int ret;
-	ret = BIO_ctrl(b, cmd, 0, &extmp);
-	if (ret > 0)
-		{
-		*ex_func = extmp.ex_func;
-		*ex_free_func = extmp.ex_free_func;
-		}
-	return ret;
-	}
+                           asn1_ps_func **ex_func,
+                           asn1_ps_func **ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    int ret;
+    ret = BIO_ctrl(b, cmd, 0, &extmp);
+    if (ret > 0) {
+        *ex_func = extmp.ex_func;
+        *ex_free_func = extmp.ex_free_func;
+    }
+    return ret;
+}
 
-int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
-	{
-	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
-	}
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
 
-int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
-	{
-	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
-	}
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
 
-int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
-	{
-	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
-	}
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
 
-int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
-	{
-	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
-	}
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
diff --git a/src/crypto/asn1/bio_ndef.c b/src/crypto/asn1/bio_ndef.c
index f07d3de..81a8aa7 100644
--- a/src/crypto/asn1/bio_ndef.c
+++ b/src/crypto/asn1/bio_ndef.c
@@ -63,192 +63,189 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 /* Experimental NDEF ASN1 BIO support routines */
 
-/* The usage is quite simple, initialize an ASN1 structure,
- * get a BIO from it then any data written through the BIO
- * will end up translated to approptiate format on the fly.
- * The data is streamed out and does *not* need to be
- * all held in memory at once.
- *
- * When the BIO is flushed the output is finalized and any
- * signatures etc written out.
- *
- * The BIO is a 'proper' BIO and can handle non blocking I/O
- * correctly.
- *
- * The usage is simple. The implementation is *not*...
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * approptiate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
  */
 
 /* BIO support data stored in the ASN1 BIO ex_arg */
 
-typedef struct ndef_aux_st
-	{
-	/* ASN1 structure this BIO refers to */
-	ASN1_VALUE *val;
-	const ASN1_ITEM *it;
-	/* Top of the BIO chain */
-	BIO *ndef_bio;
-	/* Output BIO */
-	BIO *out;
-	/* Boundary where content is inserted */
-	unsigned char **boundary;
-	/* DER buffer start */
-	unsigned char *derbuf;
-	} NDEF_SUPPORT;
+typedef struct ndef_aux_st {
+    /* ASN1 structure this BIO refers to */
+    ASN1_VALUE *val;
+    const ASN1_ITEM *it;
+    /* Top of the BIO chain */
+    BIO *ndef_bio;
+    /* Output BIO */
+    BIO *out;
+    /* Boundary where content is inserted */
+    unsigned char **boundary;
+    /* DER buffer start */
+    unsigned char *derbuf;
+} NDEF_SUPPORT;
 
 static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
 static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
 
 BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
-	{
-	NDEF_SUPPORT *ndef_aux = NULL;
-	BIO *asn_bio = NULL;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_STREAM_ARG sarg;
+{
+    NDEF_SUPPORT *ndef_aux = NULL;
+    BIO *asn_bio = NULL;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
 
-	if (!aux || !aux->asn1_cb)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
-		return NULL;
-		}
-	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
-	asn_bio = BIO_new(BIO_f_asn1());
+    if (!aux || !aux->asn1_cb) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return NULL;
+    }
+    ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+    asn_bio = BIO_new(BIO_f_asn1());
 
-	/* ASN1 bio needs to be next to output BIO */
+    /* ASN1 bio needs to be next to output BIO */
 
-	out = BIO_push(asn_bio, out);
+    out = BIO_push(asn_bio, out);
 
-	if (!ndef_aux || !asn_bio || !out)
-		goto err;
+    if (!ndef_aux || !asn_bio || !out)
+        goto err;
 
-	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
-	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+    BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+    BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
 
-	/* Now let callback prepend any digest, cipher etc BIOs
-	 * ASN1 structure needs.
-	 */
+    /*
+     * Now let callback prepend any digest, cipher etc BIOs ASN1 structure
+     * needs.
+     */
 
-	sarg.out = out;
-	sarg.ndef_bio = NULL;
-	sarg.boundary = NULL;
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
 
-	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
-		goto err;
+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+        goto err;
 
-	ndef_aux->val = val;
-	ndef_aux->it = it;
-	ndef_aux->ndef_bio = sarg.ndef_bio;
-	ndef_aux->boundary = sarg.boundary;
-	ndef_aux->out = out;
+    ndef_aux->val = val;
+    ndef_aux->it = it;
+    ndef_aux->ndef_bio = sarg.ndef_bio;
+    ndef_aux->boundary = sarg.boundary;
+    ndef_aux->out = out;
 
-	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+    BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
 
-	return sarg.ndef_bio;
+    return sarg.ndef_bio;
 
-	err:
-	if (asn_bio)
-		BIO_free(asn_bio);
-	if (ndef_aux)
-		OPENSSL_free(ndef_aux);
-	return NULL;
-	}
+ err:
+    if (asn_bio)
+        BIO_free(asn_bio);
+    if (ndef_aux)
+        OPENSSL_free(ndef_aux);
+    return NULL;
+}
 
 static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-	{
-	NDEF_SUPPORT *ndef_aux;
-	unsigned char *p;
-	int derlen;
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
 
-	if (!parg)
-		return 0;
+    if (!parg)
+        return 0;
 
-	ndef_aux = *(NDEF_SUPPORT **)parg;
+    ndef_aux = *(NDEF_SUPPORT **)parg;
 
-	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
-	p = OPENSSL_malloc(derlen);
-	if (p == NULL)
-		return 0;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (p == NULL)
+        return 0;
 
-	ndef_aux->derbuf = p;
-	*pbuf = p;
-	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
 
-	if (!*ndef_aux->boundary)
-		return 0;
+    if (!*ndef_aux->boundary)
+        return 0;
 
-	*plen = *ndef_aux->boundary - *pbuf;
+    *plen = *ndef_aux->boundary - *pbuf;
 
-	return 1;
-	}
+    return 1;
+}
 
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-	{
-	NDEF_SUPPORT *ndef_aux;
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
 
-	if (!parg)
-		return 0;
+    if (!parg)
+        return 0;
 
-	ndef_aux = *(NDEF_SUPPORT **)parg;
+    ndef_aux = *(NDEF_SUPPORT **)parg;
 
-	if (ndef_aux->derbuf)
-		OPENSSL_free(ndef_aux->derbuf);
+    if (ndef_aux->derbuf)
+        OPENSSL_free(ndef_aux->derbuf);
 
-	ndef_aux->derbuf = NULL;
-	*pbuf = NULL;
-	*plen = 0;
-	return 1;
-	}
+    ndef_aux->derbuf = NULL;
+    *pbuf = NULL;
+    *plen = 0;
+    return 1;
+}
 
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-	{
-	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
-	if (!ndef_prefix_free(b, pbuf, plen, parg))
-		return 0;
-	OPENSSL_free(*pndef_aux);
-	*pndef_aux = NULL;
-	return 1;
-	}
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+    if (!ndef_prefix_free(b, pbuf, plen, parg))
+        return 0;
+    OPENSSL_free(*pndef_aux);
+    *pndef_aux = NULL;
+    return 1;
+}
 
 static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-	{
-	NDEF_SUPPORT *ndef_aux;
-	unsigned char *p;
-	int derlen;
-	const ASN1_AUX *aux;
-	ASN1_STREAM_ARG sarg;
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+    const ASN1_AUX *aux;
+    ASN1_STREAM_ARG sarg;
 
-	if (!parg)
-		return 0;
+    if (!parg)
+        return 0;
 
-	ndef_aux = *(NDEF_SUPPORT **)parg;
+    ndef_aux = *(NDEF_SUPPORT **)parg;
 
-	aux = ndef_aux->it->funcs;
+    aux = ndef_aux->it->funcs;
 
-	/* Finalize structures */
-	sarg.ndef_bio = ndef_aux->ndef_bio;
-	sarg.out = ndef_aux->out;
-	sarg.boundary = ndef_aux->boundary;
-	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
-				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
-		return 0;
+    /* Finalize structures */
+    sarg.ndef_bio = ndef_aux->ndef_bio;
+    sarg.out = ndef_aux->out;
+    sarg.boundary = ndef_aux->boundary;
+    if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+                     &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+        return 0;
 
-	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
-	p = OPENSSL_malloc(derlen);
-	if (p == NULL)
-		return 0;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (p == NULL)
+        return 0;
 
-	ndef_aux->derbuf = p;
-	*pbuf = p;
-	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
 
-	if (!*ndef_aux->boundary)
-		return 0;
-	*pbuf = *ndef_aux->boundary;
-	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+    if (!*ndef_aux->boundary)
+        return 0;
+    *pbuf = *ndef_aux->boundary;
+    *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
 
-	return 1;
-	}
+    return 1;
+}
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index bcdb773..3af16f8 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -62,145 +62,139 @@
 /* Based on a_int.c: equivalent ENUMERATED functions */
 
 int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
-	{
-	int i,n=0;
-	static const char *h="0123456789ABCDEF";
-	char buf[2];
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
 
-	if (a == NULL) return(0);
+    if (a == NULL)
+        return (0);
 
-	if (a->length == 0)
-		{
-		if (BIO_write(bp,"00",2) != 2) goto err;
-		n=2;
-		}
-	else
-		{
-		for (i=0; i<a->length; i++)
-			{
-			if ((i != 0) && (i%35 == 0))
-				{
-				if (BIO_write(bp,"\\\n",2) != 2) goto err;
-				n+=2;
-				}
-			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
-			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
-			if (BIO_write(bp,buf,2) != 2) goto err;
-			n+=2;
-			}
-		}
-	return(n);
-err:
-	return(-1);
-	}
+    if (a->length == 0) {
+        if (BIO_write(bp, "00", 2) != 2)
+            goto err;
+        n = 2;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return (n);
+ err:
+    return (-1);
+}
 
 int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
-	{
-	int ret=0;
-	int i,j,k,m,n,again,bufsize;
-	unsigned char *s=NULL,*sp;
-	unsigned char *bufp;
-	int num=0,slen=0,first=1;
+{
+    int ret = 0;
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
 
-	bs->type=V_ASN1_ENUMERATED;
+    bs->type = V_ASN1_ENUMERATED;
 
-	bufsize=BIO_gets(bp,buf,size);
-	for (;;)
-		{
-		if (bufsize < 1) goto err_sl;
-		i=bufsize;
-		if (buf[i-1] == '\n') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		if (buf[i-1] == '\r') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		again=(buf[i-1] == '\\');
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1)
+            goto err_sl;
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        again = (buf[i - 1] == '\\');
 
-		for (j=0; j<i; j++)
-			{
-			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
-				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
-				((buf[j] >= 'A') && (buf[j] <= 'F'))))
-				{
-				i=j;
-				break;
-				}
-			}
-		buf[i]='\0';
-		/* We have now cleared all the crap off the end of the
-		 * line */
-		if (i < 2) goto err_sl;
+        for (j = 0; j < i; j++) {
+            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                  ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err_sl;
 
-		bufp=(unsigned char *)buf;
-		if (first)
-			{
-			first=0;
-			if ((bufp[0] == '0') && (buf[1] == '0'))
-				{
-				bufp+=2;
-				i-=2;
-				}
-			}
-		k=0;
-		i-=again;
-		if (i%2 != 0)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
-			goto err;
-			}
-		i/=2;
-		if (num+i > slen)
-			{
-			if (s == NULL)
-				sp=(unsigned char *)OPENSSL_malloc(
-					(unsigned int)num+i*2);
-			else
-				sp=(unsigned char *)OPENSSL_realloc(s,
-					(unsigned int)num+i*2);
-			if (sp == NULL)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			s=sp;
-			slen=num+i*2;
-			}
-		for (j=0; j<i; j++,k+=2)
-			{
-			for (n=0; n<2; n++)
-				{
-				m=bufp[k+n];
-				if ((m >= '0') && (m <= '9'))
-					m-='0';
-				else if ((m >= 'a') && (m <= 'f'))
-					m=m-'a'+10;
-				else if ((m >= 'A') && (m <= 'F'))
-					m=m-'A'+10;
-				else
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
-					goto err;
-					}
-				s[num+j]<<=4;
-				s[num+j]|=m;
-				}
-			}
-		num+=i;
-		if (again)
-			bufsize=BIO_gets(bp,buf,size);
-		else
-			break;
-		}
-	bs->length=num;
-	bs->data=s;
-	ret=1;
-err:
-	if (0)
-		{
-err_sl:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
-		}
-	if (s != NULL)
-		OPENSSL_free(s);
-	return(ret);
-	}
-
+        bufp = (unsigned char *)buf;
+        if (first) {
+            first = 0;
+            if ((bufp[0] == '0') && (buf[1] == '0')) {
+                bufp += 2;
+                i -= 2;
+            }
+        }
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+            goto err;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            if (s == NULL)
+                sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+                                                     i * 2);
+            else
+                sp = (unsigned char *)OPENSSL_realloc(s,
+                                                      (unsigned int)num +
+                                                      i * 2);
+            if (sp == NULL) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = bufp[k + n];
+                if ((m >= '0') && (m <= '9'))
+                    m -= '0';
+                else if ((m >= 'a') && (m <= 'f'))
+                    m = m - 'a' + 10;
+                else if ((m >= 'A') && (m <= 'F'))
+                    m = m - 'A' + 10;
+                else {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+                    goto err;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    ret = 1;
+ err:
+    if (0) {
+ err_sl:
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+    }
+    if (s != NULL)
+        OPENSSL_free(s);
+    return (ret);
+}
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 5186304..60c0f2f 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -59,152 +59,144 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
-	{
-	int i,n=0;
-	static const char *h="0123456789ABCDEF";
-	char buf[2];
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
 
-	if (a == NULL) return(0);
+    if (a == NULL)
+        return (0);
 
-	if (a->type & V_ASN1_NEG)
-		{
-		if (BIO_write(bp, "-", 1) != 1) goto err;
-		n = 1;
-		}
+    if (a->type & V_ASN1_NEG) {
+        if (BIO_write(bp, "-", 1) != 1)
+            goto err;
+        n = 1;
+    }
 
-	if (a->length == 0)
-		{
-		if (BIO_write(bp,"00",2) != 2) goto err;
-		n += 2;
-		}
-	else
-		{
-		for (i=0; i<a->length; i++)
-			{
-			if ((i != 0) && (i%35 == 0))
-				{
-				if (BIO_write(bp,"\\\n",2) != 2) goto err;
-				n+=2;
-				}
-			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
-			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
-			if (BIO_write(bp,buf,2) != 2) goto err;
-			n+=2;
-			}
-		}
-	return(n);
-err:
-	return(-1);
-	}
+    if (a->length == 0) {
+        if (BIO_write(bp, "00", 2) != 2)
+            goto err;
+        n += 2;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return (n);
+ err:
+    return (-1);
+}
 
 int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
-	{
-	int ret=0;
-	int i,j,k,m,n,again,bufsize;
-	unsigned char *s=NULL,*sp;
-	unsigned char *bufp;
-	int num=0,slen=0,first=1;
+{
+    int ret = 0;
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
 
-	bs->type=V_ASN1_INTEGER;
+    bs->type = V_ASN1_INTEGER;
 
-	bufsize=BIO_gets(bp,buf,size);
-	for (;;)
-		{
-		if (bufsize < 1) goto err_sl;
-		i=bufsize;
-		if (buf[i-1] == '\n') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		if (buf[i-1] == '\r') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		again=(buf[i-1] == '\\');
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1)
+            goto err_sl;
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        again = (buf[i - 1] == '\\');
 
-		for (j=0; j<i; j++)
-			{
-			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
-				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
-				((buf[j] >= 'A') && (buf[j] <= 'F'))))
-				{
-				i=j;
-				break;
-				}
-			}
-		buf[i]='\0';
-		/* We have now cleared all the crap off the end of the
-		 * line */
-		if (i < 2) goto err_sl;
+        for (j = 0; j < i; j++) {
+            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                  ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err_sl;
 
-		bufp=(unsigned char *)buf;
-		if (first)
-			{
-			first=0;
-			if ((bufp[0] == '0') && (buf[1] == '0'))
-				{
-				bufp+=2;
-				i-=2;
-				}
-			}
-		k=0;
-		i-=again;
-		if (i%2 != 0)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
-			goto err;
-			}
-		i/=2;
-		if (num+i > slen)
-			{
-			if (s == NULL)
-				sp=(unsigned char *)OPENSSL_malloc(
-					(unsigned int)num+i*2);
-			else
-				sp=OPENSSL_realloc_clean(s,slen,num+i*2);
-			if (sp == NULL)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			s=sp;
-			slen=num+i*2;
-			}
-		for (j=0; j<i; j++,k+=2)
-			{
-			for (n=0; n<2; n++)
-				{
-				m=bufp[k+n];
-				if ((m >= '0') && (m <= '9'))
-					m-='0';
-				else if ((m >= 'a') && (m <= 'f'))
-					m=m-'a'+10;
-				else if ((m >= 'A') && (m <= 'F'))
-					m=m-'A'+10;
-				else
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
-					goto err;
-					}
-				s[num+j]<<=4;
-				s[num+j]|=m;
-				}
-			}
-		num+=i;
-		if (again)
-			bufsize=BIO_gets(bp,buf,size);
-		else
-			break;
-		}
-	bs->length=num;
-	bs->data=s;
-	ret=1;
-err:
-	if (0)
-		{
-err_sl:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
-		}
-	if (s != NULL)
-		OPENSSL_free(s);
-	return(ret);
-	}
-
+        bufp = (unsigned char *)buf;
+        if (first) {
+            first = 0;
+            if ((bufp[0] == '0') && (buf[1] == '0')) {
+                bufp += 2;
+                i -= 2;
+            }
+        }
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+            goto err;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            if (s == NULL)
+                sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+                                                     i * 2);
+            else
+                sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
+            if (sp == NULL) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = bufp[k + n];
+                if ((m >= '0') && (m <= '9'))
+                    m -= '0';
+                else if ((m >= 'a') && (m <= 'f'))
+                    m = m - 'a' + 10;
+                else if ((m >= 'A') && (m <= 'F'))
+                    m = m - 'A' + 10;
+                else {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+                    goto err;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    ret = 1;
+ err:
+    if (0) {
+ err_sl:
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+    }
+    if (s != NULL)
+        OPENSSL_free(s);
+    return (ret);
+}
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index 5a7fe36..ec9cb83 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -59,146 +59,138 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
-
 int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
-	{
-	int i,n=0;
-	static const char *h="0123456789ABCDEF";
-	char buf[2];
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
 
-	if (a == NULL) return(0);
+    if (a == NULL)
+        return (0);
 
-	if (a->length == 0)
-		{
-		if (BIO_write(bp,"0",1) != 1) goto err;
-		n=1;
-		}
-	else
-		{
-		for (i=0; i<a->length; i++)
-			{
-			if ((i != 0) && (i%35 == 0))
-				{
-				if (BIO_write(bp,"\\\n",2) != 2) goto err;
-				n+=2;
-				}
-			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
-			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
-			if (BIO_write(bp,buf,2) != 2) goto err;
-			n+=2;
-			}
-		}
-	return(n);
-err:
-	return(-1);
-	}
+    if (a->length == 0) {
+        if (BIO_write(bp, "0", 1) != 1)
+            goto err;
+        n = 1;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return (n);
+ err:
+    return (-1);
+}
 
 int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
-	{
-	int ret=0;
-	int i,j,k,m,n,again,bufsize;
-	unsigned char *s=NULL,*sp;
-	unsigned char *bufp;
-	int num=0,slen=0,first=1;
+{
+    int ret = 0;
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
 
-	bufsize=BIO_gets(bp,buf,size);
-	for (;;)
-		{
-		if (bufsize < 1)
-			{
-			if (first)
-				break;
-			else
-				goto err_sl;
-			}
-		first=0;
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1) {
+            if (first)
+                break;
+            else
+                goto err_sl;
+        }
+        first = 0;
 
-		i=bufsize;
-		if (buf[i-1] == '\n') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		if (buf[i-1] == '\r') buf[--i]='\0';
-		if (i == 0) goto err_sl;
-		again=(buf[i-1] == '\\');
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err_sl;
+        again = (buf[i - 1] == '\\');
 
-		for (j=i-1; j>0; j--)
-			{
-			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
-				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
-				((buf[j] >= 'A') && (buf[j] <= 'F'))))
-				{
-				i=j;
-				break;
-				}
-			}
-		buf[i]='\0';
-		/* We have now cleared all the crap off the end of the
-		 * line */
-		if (i < 2) goto err_sl;
+        for (j = i - 1; j > 0; j--) {
+            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                  ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err_sl;
 
-		bufp=(unsigned char *)buf;
+        bufp = (unsigned char *)buf;
 
-		k=0;
-		i-=again;
-		if (i%2 != 0)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
-			goto err;
-			}
-		i/=2;
-		if (num+i > slen)
-			{
-			if (s == NULL)
-				sp=(unsigned char *)OPENSSL_malloc(
-					(unsigned int)num+i*2);
-			else
-				sp=(unsigned char *)OPENSSL_realloc(s,
-					(unsigned int)num+i*2);
-			if (sp == NULL)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			s=sp;
-			slen=num+i*2;
-			}
-		for (j=0; j<i; j++,k+=2)
-			{
-			for (n=0; n<2; n++)
-				{
-				m=bufp[k+n];
-				if ((m >= '0') && (m <= '9'))
-					m-='0';
-				else if ((m >= 'a') && (m <= 'f'))
-					m=m-'a'+10;
-				else if ((m >= 'A') && (m <= 'F'))
-					m=m-'A'+10;
-				else
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
-					goto err;
-					}
-				s[num+j]<<=4;
-				s[num+j]|=m;
-				}
-			}
-		num+=i;
-		if (again)
-			bufsize=BIO_gets(bp,buf,size);
-		else
-			break;
-		}
-	bs->length=num;
-	bs->data=s;
-	ret=1;
-err:
-	if (0)
-		{
-err_sl:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
-		}
-	if (s != NULL)
-		OPENSSL_free(s);
-	return(ret);
-	}
-
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+            goto err;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            if (s == NULL)
+                sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+                                                     i * 2);
+            else
+                sp = (unsigned char *)OPENSSL_realloc(s,
+                                                      (unsigned int)num +
+                                                      i * 2);
+            if (sp == NULL) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = bufp[k + n];
+                if ((m >= '0') && (m <= '9'))
+                    m -= '0';
+                else if ((m >= 'a') && (m <= 'f'))
+                    m = m - 'a' + 10;
+                else if ((m >= 'A') && (m <= 'F'))
+                    m = m - 'A' + 10;
+                else {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+                    goto err;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    ret = 1;
+ err:
+    if (0) {
+ err_sl:
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+    }
+    if (s != NULL)
+        OPENSSL_free(s);
+    return (ret);
+}
diff --git a/src/crypto/asn1/t_bitst.c b/src/crypto/asn1/t_bitst.c
index 1ca6e08..e754ca7 100644
--- a/src/crypto/asn1/t_bitst.c
+++ b/src/crypto/asn1/t_bitst.c
@@ -60,43 +60,44 @@
 
 #include <openssl/mem.h>
 
-
 int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
-				BIT_STRING_BITNAME *tbl, int indent)
+                               BIT_STRING_BITNAME *tbl, int indent)
 {
-	BIT_STRING_BITNAME *bnam;
-	char first = 1;
-	BIO_printf(out, "%*s", indent, "");
-	for(bnam = tbl; bnam->lname; bnam++) {
-		if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
-			if(!first) BIO_puts(out, ", ");
-			BIO_puts(out, bnam->lname);
-			first = 0;
-		}
-	}
-	BIO_puts(out, "\n");
-	return 1;
+    BIT_STRING_BITNAME *bnam;
+    char first = 1;
+    BIO_printf(out, "%*s", indent, "");
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+            if (!first)
+                BIO_puts(out, ", ");
+            BIO_puts(out, bnam->lname);
+            first = 0;
+        }
+    }
+    BIO_puts(out, "\n");
+    return 1;
 }
 
 int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
-				BIT_STRING_BITNAME *tbl)
+                            BIT_STRING_BITNAME *tbl)
 {
-	int bitnum;
-	bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
-	if(bitnum < 0) return 0;
-	if(bs) {
-		if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
-			return 0;
-	}
-	return 1;
+    int bitnum;
+    bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+    if (bitnum < 0)
+        return 0;
+    if (bs) {
+        if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+            return 0;
+    }
+    return 1;
 }
 
 int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
 {
-	BIT_STRING_BITNAME *bnam;
-	for(bnam = tbl; bnam->lname; bnam++) {
-		if(!strcmp(bnam->sname, name) ||
-			!strcmp(bnam->lname, name) ) return bnam->bitnum;
-	}
-	return -1;
+    BIT_STRING_BITNAME *bnam;
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name))
+            return bnam->bitnum;
+    }
+    return -1;
 }
diff --git a/src/crypto/asn1/t_pkey.c b/src/crypto/asn1/t_pkey.c
deleted file mode 100644
index 6ac9b3d..0000000
--- a/src/crypto/asn1/t_pkey.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <openssl/asn1.h>
-
-#include <openssl/bio.h>
-#include <openssl/mem.h>
-
-
-int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
-			unsigned char *buf, int off)
-	{
-	int n,i;
-	const char *neg;
-
-	if (num == NULL) return(1);
-	neg = (BN_is_negative(num))?"-":"";
-	if(!BIO_indent(bp,off,128))
-		return 0;
-	if (BN_is_zero(num))
-		{
-		if (BIO_printf(bp, "%s 0\n", number) <= 0)
-			return 0;
-		return 1;
-		}
-
-	if (BN_num_bytes(num) <= sizeof(long))
-		{
-		if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
-			(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
-			<= 0) return(0);
-		}
-	else
-		{
-		buf[0]=0;
-		if (BIO_printf(bp,"%s%s",number,
-			(neg[0] == '-')?" (Negative)":"") <= 0)
-			return(0);
-		n=BN_bn2bin(num,&buf[1]);
-	
-		if (buf[1] & 0x80)
-			n++;
-		else	buf++;
-
-		for (i=0; i<n; i++)
-			{
-			if ((i%15) == 0)
-				{
-				if(BIO_puts(bp,"\n") <= 0
-				   || !BIO_indent(bp,off+4,128))
-				    return 0;
-				}
-			if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
-				<= 0) return(0);
-			}
-		if (BIO_write(bp,"\n",1) <= 0) return(0);
-		}
-	return(1);
-	}
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 7c81753..40d575d 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -65,1278 +65,1157 @@
 
 #include "../internal.h"
 
-
 static int asn1_check_eoc(const unsigned char **in, long len);
 static int asn1_find_end(const unsigned char **in, long len, char inf);
 
 static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-			char inf, int tag, int aclass, int depth);
+                        char inf, int tag, int aclass, int depth);
 
 static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
 
 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
-				char *inf, char *cst,
-				const unsigned char **in, long len,
-				int exptag, int expclass, char opt,
-				ASN1_TLC *ctx);
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx);
 
 static int asn1_template_ex_d2i(ASN1_VALUE **pval,
-				const unsigned char **in, long len,
-				const ASN1_TEMPLATE *tt, char opt,
-				ASN1_TLC *ctx);
+                                const unsigned char **in, long len,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx);
 static int asn1_template_noexp_d2i(ASN1_VALUE **val,
-				const unsigned char **in, long len,
-				const ASN1_TEMPLATE *tt, char opt,
-				ASN1_TLC *ctx);
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx);
 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
-				const unsigned char **in, long len,
-				const ASN1_ITEM *it,
-				int tag, int aclass, char opt, ASN1_TLC *ctx);
+                                 const unsigned char **in, long len,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt,
+                                 ASN1_TLC *ctx);
 
 /* Table to convert tags to bit values, used for MSTRING type */
 static const unsigned long tag2bit[32] = {
-0,	0,	0,	B_ASN1_BIT_STRING,	/* tags  0 -  3 */
-B_ASN1_OCTET_STRING,	0,	0,		B_ASN1_UNKNOWN,/* tags  4- 7 */
-B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,/* tags  8-11 */
-B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
-B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
-B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
-B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,			       /* tags 23-24 */	
-B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
-B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
-	};
+    0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */
+    B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */
+    B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags
+                                                                     * 8-11 */
+    B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags
+                                                                        * 12-15
+                                                                        */
+    B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags
+                                                                       * 16-19
+                                                                       */
+    B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */
+    B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */
+    B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags
+                                                                     * 25-27 */
+    B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags
+                                                                               * 28-31
+                                                                               */
+};
 
 unsigned long ASN1_tag2bit(int tag)
-	{
-	if ((tag < 0) || (tag > 30)) return 0;
-	return tag2bit[tag];
-	}
+{
+    if ((tag < 0) || (tag > 30))
+        return 0;
+    return tag2bit[tag];
+}
 
 /* Macro to initialize and invalidate the cache */
 
-#define asn1_tlc_clear(c)	if (c) (c)->valid = 0
+#define asn1_tlc_clear(c)       if (c) (c)->valid = 0
 /* Version to avoid compiler warning about 'c' always non-NULL */
-#define asn1_tlc_clear_nc(c)	(c)->valid = 0
+#define asn1_tlc_clear_nc(c)    (c)->valid = 0
 
-/* Decode an ASN1 item, this currently behaves just 
- * like a standard 'd2i' function. 'in' points to 
- * a buffer to read the data from, in future we will
- * have more advanced versions that can input data
- * a piece at a time and this will simply be a special
- * case.
+/*
+ * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
+ * function. 'in' points to a buffer to read the data from, in future we
+ * will have more advanced versions that can input data a piece at a time and
+ * this will simply be a special case.
  */
 
 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
-		const unsigned char **in, long len, const ASN1_ITEM *it)
-	{
-	ASN1_TLC c;
-	ASN1_VALUE *ptmpval = NULL;
-	if (!pval)
-		pval = &ptmpval;
-	asn1_tlc_clear_nc(&c);
-	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
-		return *pval;
-	return NULL;
-	}
+                          const unsigned char **in, long len,
+                          const ASN1_ITEM *it)
+{
+    ASN1_TLC c;
+    ASN1_VALUE *ptmpval = NULL;
+    if (!pval)
+        pval = &ptmpval;
+    asn1_tlc_clear_nc(&c);
+    if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+        return *pval;
+    return NULL;
+}
 
 int ASN1_template_d2i(ASN1_VALUE **pval,
-		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
-	{
-	ASN1_TLC c;
-	asn1_tlc_clear_nc(&c);
-	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
-	}
+                      const unsigned char **in, long len,
+                      const ASN1_TEMPLATE *tt)
+{
+    ASN1_TLC c;
+    asn1_tlc_clear_nc(&c);
+    return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+}
 
-
-/* Decode an item, taking care of IMPLICIT tagging, if any.
- * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
+/*
+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
+ * tag mismatch return -1 to handle OPTIONAL
  */
 
 int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
-			const ASN1_ITEM *it,
-			int tag, int aclass, char opt, ASN1_TLC *ctx)
-	{
-	const ASN1_TEMPLATE *tt, *errtt = NULL;
-	const ASN1_COMPAT_FUNCS *cf;
-	const ASN1_EXTERN_FUNCS *ef;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_aux_cb *asn1_cb;
-	const unsigned char *p = NULL, *q;
-	unsigned char *wp=NULL;	/* BIG FAT WARNING!  BREAKS CONST WHERE USED */
-	unsigned char imphack = 0, oclass;
-	char seq_eoc, seq_nolen, cst, isopt;
-	long tmplen;
-	int i;
-	int otag;
-	int ret = 0;
-	ASN1_VALUE **pchptr, *ptmpval;
-	int combine = aclass & ASN1_TFLG_COMBINE;
-	if (!pval)
-		return 0;
-	if (aux && aux->asn1_cb)
-		asn1_cb = aux->asn1_cb;
-	else asn1_cb = 0;
+                     const ASN1_ITEM *it,
+                     int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    const ASN1_TEMPLATE *tt, *errtt = NULL;
+    const ASN1_COMPAT_FUNCS *cf;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    const unsigned char *p = NULL, *q;
+    unsigned char *wp = NULL;   /* BIG FAT WARNING! BREAKS CONST WHERE USED */
+    unsigned char imphack = 0, oclass;
+    char seq_eoc, seq_nolen, cst, isopt;
+    long tmplen;
+    int i;
+    int otag;
+    int ret = 0;
+    ASN1_VALUE **pchptr, *ptmpval;
+    int combine = aclass & ASN1_TFLG_COMBINE;
+    if (!pval)
+        return 0;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
 
-	switch(it->itype)
-		{
-		case ASN1_ITYPE_PRIMITIVE:
-		if (it->templates)
-			{
-			/* tagging or OPTIONAL is currently illegal on an item
-			 * template because the flags can't get passed down.
-			 * In practice this isn't a problem: we include the
-			 * relevant flags from the item template in the
-			 * template itself.
-			 */
-			if ((tag != -1) || opt)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
-				goto err;
-				}
-			return asn1_template_ex_d2i(pval, in, len,
-					it->templates, opt, ctx);
-		}
-		return asn1_d2i_ex_primitive(pval, in, len, it,
-						tag, aclass, opt, ctx);
-		break;
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            /*
+             * tagging or OPTIONAL is currently illegal on an item template
+             * because the flags can't get passed down. In practice this
+             * isn't a problem: we include the relevant flags from the item
+             * template in the template itself.
+             */
+            if ((tag != -1) || opt) {
+                OPENSSL_PUT_ERROR(ASN1,
+                                  ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+                goto err;
+            }
+            return asn1_template_ex_d2i(pval, in, len,
+                                        it->templates, opt, ctx);
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it,
+                                     tag, aclass, opt, ctx);
+        break;
 
-		case ASN1_ITYPE_MSTRING:
-		p = *in;
-		/* Just read in tag and class */
-		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
-						&p, len, -1, 0, 1, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
+    case ASN1_ITYPE_MSTRING:
+        p = *in;
+        /* Just read in tag and class */
+        ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+                              &p, len, -1, 0, 1, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
 
-		/* Must be UNIVERSAL class */
-		if (oclass != V_ASN1_UNIVERSAL)
-			{
-			/* If OPTIONAL, assume this is OK */
-			if (opt) return -1;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
-			goto err;
-			}
-		/* Check tag matches bit map */
-		if (!(ASN1_tag2bit(otag) & it->utype))
-			{
-			/* If OPTIONAL, assume this is OK */
-			if (opt)
-				return -1;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
-			goto err;
-			}
-		return asn1_d2i_ex_primitive(pval, in, len,
-						it, otag, 0, 0, ctx);
+        /* Must be UNIVERSAL class */
+        if (oclass != V_ASN1_UNIVERSAL) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
+            goto err;
+        }
+        /* Check tag matches bit map */
+        if (!(ASN1_tag2bit(otag) & it->utype)) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
+            goto err;
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
 
-		case ASN1_ITYPE_EXTERN:
-		/* Use new style d2i */
-		ef = it->funcs;
-		return ef->asn1_ex_d2i(pval, in, len,
-						it, tag, aclass, opt, ctx);
+    case ASN1_ITYPE_EXTERN:
+        /* Use new style d2i */
+        ef = it->funcs;
+        return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
 
-		case ASN1_ITYPE_COMPAT:
-		/* we must resort to old style evil hackery */
-		cf = it->funcs;
+    case ASN1_ITYPE_COMPAT:
+        /* we must resort to old style evil hackery */
+        cf = it->funcs;
 
-		/* If OPTIONAL see if it is there */
-		if (opt)
-			{
-			int exptag;
-			p = *in;
-			if (tag == -1)
-				exptag = it->utype;
-			else exptag = tag;
-			/* Don't care about anything other than presence
-			 * of expected tag */
+        /* If OPTIONAL see if it is there */
+        if (opt) {
+            int exptag;
+            p = *in;
+            if (tag == -1)
+                exptag = it->utype;
+            else
+                exptag = tag;
+            /*
+             * Don't care about anything other than presence of expected tag
+             */
 
-			ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
-					&p, len, exptag, aclass, 1, ctx);
-			if (!ret)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-				goto err;
-				}
-			if (ret == -1)
-				return -1;
-			}
+            ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
+                                  &p, len, exptag, aclass, 1, ctx);
+            if (!ret) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+                goto err;
+            }
+            if (ret == -1)
+                return -1;
+        }
 
-		/* This is the old style evil hack IMPLICIT handling:
-		 * since the underlying code is expecting a tag and
-		 * class other than the one present we change the
-		 * buffer temporarily then change it back afterwards.
-		 * This doesn't and never did work for tags > 30.
-		 *
-		 * Yes this is *horrible* but it is only needed for
-		 * old style d2i which will hopefully not be around
-		 * for much longer.
-		 * FIXME: should copy the buffer then modify it so
-		 * the input buffer can be const: we should *always*
-		 * copy because the old style d2i might modify the
-		 * buffer.
-		 */
+        /*
+         * This is the old style evil hack IMPLICIT handling: since the
+         * underlying code is expecting a tag and class other than the one
+         * present we change the buffer temporarily then change it back
+         * afterwards. This doesn't and never did work for tags > 30. Yes
+         * this is *horrible* but it is only needed for old style d2i which
+         * will hopefully not be around for much longer. FIXME: should copy
+         * the buffer then modify it so the input buffer can be const: we
+         * should *always* copy because the old style d2i might modify the
+         * buffer.
+         */
 
-		if (tag != -1)
-			{
-			wp = *(unsigned char **)in;
-			imphack = *wp;
-			if (p == NULL)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-				goto err;
-				}
-			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
-								| it->utype);
-			}
+        if (tag != -1) {
+            wp = *(unsigned char **)in;
+            imphack = *wp;
+            if (p == NULL) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+                goto err;
+            }
+            *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
+                                  | it->utype);
+        }
 
-		ptmpval = cf->asn1_d2i(pval, in, len);
+        ptmpval = cf->asn1_d2i(pval, in, len);
 
-		if (tag != -1)
-			*wp = imphack;
+        if (tag != -1)
+            *wp = imphack;
 
-		if (ptmpval)
-			return 1;
+        if (ptmpval)
+            return 1;
 
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-		goto err;
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+        goto err;
 
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
 
-		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
-				goto auxerr;
+        if (*pval) {
+            /* Free up and zero CHOICE value if initialised */
+            i = asn1_get_choice_selector(pval, it);
+            if ((i >= 0) && (i < it->tcount)) {
+                tt = it->templates + i;
+                pchptr = asn1_get_field_ptr(pval, tt);
+                ASN1_template_free(pchptr, tt);
+                asn1_set_choice_selector(pval, -1, it);
+            }
+        } else if (!ASN1_item_ex_new(pval, it)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+        /* CHOICE type, try each possibility in turn */
+        p = *in;
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            pchptr = asn1_get_field_ptr(pval, tt);
+            /*
+             * We mark field as OPTIONAL so its absence can be recognised.
+             */
+            ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+            /* If field not present, try the next one */
+            if (ret == -1)
+                continue;
+            /* If positive return, read OK, break loop */
+            if (ret > 0)
+                break;
+            /* Otherwise must be an ASN1 parsing error */
+            errtt = tt;
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
 
-		if (*pval)
-			{
-			/* Free up and zero CHOICE value if initialised */
-			i = asn1_get_choice_selector(pval, it);
-			if ((i >= 0) && (i < it->tcount))
-				{
-				tt = it->templates + i;
-				pchptr = asn1_get_field_ptr(pval, tt);
-				ASN1_template_free(pchptr, tt);
-				asn1_set_choice_selector(pval, -1, it);
-				}
-			}
-		else if (!ASN1_item_ex_new(pval, it))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
-		/* CHOICE type, try each possibility in turn */
-		p = *in;
-		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
-			{
-			pchptr = asn1_get_field_ptr(pval, tt);
-			/* We mark field as OPTIONAL so its absence
-			 * can be recognised.
-			 */
-			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
-			/* If field not present, try the next one */
-			if (ret == -1)
-				continue;
-			/* If positive return, read OK, break loop */
-			if (ret > 0)
-				break;
-			/* Otherwise must be an ASN1 parsing error */
-			errtt = tt;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
+        /* Did we fall off the end without reading anything? */
+        if (i == it->tcount) {
+            /* If OPTIONAL, this is OK */
+            if (opt) {
+                /* Free and zero it */
+                ASN1_item_ex_free(pval, it);
+                return -1;
+            }
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+            goto err;
+        }
 
-		/* Did we fall off the end without reading anything? */
-		if (i == it->tcount)
-			{
-			/* If OPTIONAL, this is OK */
-			if (opt)
-				{
-				/* Free and zero it */
-				ASN1_item_ex_free(pval, it);
-				return -1;
-				}
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
-			goto err;
-			}
+        asn1_set_choice_selector(pval, i, it);
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
 
-		asn1_set_choice_selector(pval, i, it);
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
-				goto auxerr;
-		*in = p;
-		return 1;
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        p = *in;
+        tmplen = len;
 
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		case ASN1_ITYPE_SEQUENCE:
-		p = *in;
-		tmplen = len;
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            aclass = V_ASN1_UNIVERSAL;
+        }
+        /* Get SEQUENCE length and update len, p */
+        ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+                              &p, len, tag, aclass, opt, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+        if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+            len = tmplen - (p - *in);
+            seq_nolen = 1;
+        }
+        /* If indefinite we don't do a length check */
+        else
+            seq_nolen = seq_eoc;
+        if (!cst) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+            goto err;
+        }
 
-		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
-		if (tag == -1)
-			{
-			tag = V_ASN1_SEQUENCE;
-			aclass = V_ASN1_UNIVERSAL;
-			}
-		/* Get SEQUENCE length and update len, p */
-		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
-					&p, len, tag, aclass, opt, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
-		else if (ret == -1)
-			return -1;
-		if (aux && (aux->flags & ASN1_AFLG_BROKEN))
-			{
-			len = tmplen - (p - *in);
-			seq_nolen = 1;
-			}
-		/* If indefinite we don't do a length check */
-		else seq_nolen = seq_eoc;
-		if (!cst)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
-			goto err;
-			}
+        if (!*pval && !ASN1_item_ex_new(pval, it)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
 
-		if (!*pval && !ASN1_item_ex_new(pval, it))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
 
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
-				goto auxerr;
+        /* Free up and zero any ADB found */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            if (tt->flags & ASN1_TFLG_ADB_MASK) {
+                const ASN1_TEMPLATE *seqtt;
+                ASN1_VALUE **pseqval;
+                seqtt = asn1_do_adb(pval, tt, 1);
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                ASN1_template_free(pseqval, seqtt);
+            }
+        }
 
-		/* Free up and zero any ADB found */
-		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
-			{
-			if (tt->flags & ASN1_TFLG_ADB_MASK)
-				{
-				const ASN1_TEMPLATE *seqtt;
-				ASN1_VALUE **pseqval;
-				seqtt = asn1_do_adb(pval, tt, 1);
-				pseqval = asn1_get_field_ptr(pval, seqtt);
-				ASN1_template_free(pseqval, seqtt);
-				}
-			}
+        /* Get each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                goto err;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* Have we ran out of data? */
+            if (!len)
+                break;
+            q = p;
+            if (asn1_check_eoc(&p, len)) {
+                if (!seq_eoc) {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                seq_eoc = 0;
+                q = p;
+                break;
+            }
+            /*
+             * This determines the OPTIONAL flag value. The field cannot be
+             * omitted if it is the last of a SEQUENCE and there is still
+             * data to be read. This isn't strictly necessary but it
+             * increases efficiency in some cases.
+             */
+            if (i == (it->tcount - 1))
+                isopt = 0;
+            else
+                isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+            /*
+             * attempt to read in field, allowing each to be OPTIONAL
+             */
 
-		/* Get each field entry */
-		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
-			{
-			const ASN1_TEMPLATE *seqtt;
-			ASN1_VALUE **pseqval;
-			seqtt = asn1_do_adb(pval, tt, 1);
-			if (!seqtt)
-				goto err;
-			pseqval = asn1_get_field_ptr(pval, seqtt);
-			/* Have we ran out of data? */
-			if (!len)
-				break;
-			q = p;
-			if (asn1_check_eoc(&p, len))
-				{
-				if (!seq_eoc)
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
-					goto err;
-					}
-				len -= p - q;
-				seq_eoc = 0;
-				q = p;
-				break;
-				}
-			/* This determines the OPTIONAL flag value. The field
-			 * cannot be omitted if it is the last of a SEQUENCE
-			 * and there is still data to be read. This isn't
-			 * strictly necessary but it increases efficiency in
-			 * some cases.
-			 */
-			if (i == (it->tcount - 1))
-				isopt = 0;
-			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
-			/* attempt to read in field, allowing each to be
-			 * OPTIONAL */
+            ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+            if (!ret) {
+                errtt = seqtt;
+                goto err;
+            } else if (ret == -1) {
+                /*
+                 * OPTIONAL component absent. Free and zero the field.
+                 */
+                ASN1_template_free(pseqval, seqtt);
+                continue;
+            }
+            /* Update length */
+            len -= p - q;
+        }
 
-			ret = asn1_template_ex_d2i(pseqval, &p, len,
-							seqtt, isopt, ctx);
-			if (!ret)
-				{
-				errtt = seqtt;
-				goto err;
-				}
-			else if (ret == -1)
-				{
-				/* OPTIONAL component absent.
-				 * Free and zero the field.
-				 */
-				ASN1_template_free(pseqval, seqtt);
-				continue;
-				}
-			/* Update length */
-			len -= p - q;
-			}
+        /* Check for EOC if expecting one */
+        if (seq_eoc && !asn1_check_eoc(&p, len)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+        /* Check all data read */
+        if (!seq_nolen && len) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+            goto err;
+        }
 
-		/* Check for EOC if expecting one */
-		if (seq_eoc && !asn1_check_eoc(&p, len))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
-			goto err;
-			}
-		/* Check all data read */
-		if (!seq_nolen && len)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
-			goto err;
-			}
+        /*
+         * If we get here we've got no more data in the SEQUENCE, however we
+         * may not have read all fields so check all remaining are OPTIONAL
+         * and clear any that are.
+         */
+        for (; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                goto err;
+            if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+                ASN1_VALUE **pseqval;
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                ASN1_template_free(pseqval, seqtt);
+            } else {
+                errtt = seqtt;
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
+                goto err;
+            }
+        }
+        /* Save encoding */
+        if (!asn1_enc_save(pval, *in, p - *in, it))
+            goto auxerr;
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
 
-		/* If we get here we've got no more data in the SEQUENCE,
-		 * however we may not have read all fields so check all
-		 * remaining are OPTIONAL and clear any that are.
-		 */
-		for (; i < it->tcount; tt++, i++)
-			{
-			const ASN1_TEMPLATE *seqtt;
-			seqtt = asn1_do_adb(pval, tt, 1);
-			if (!seqtt)
-				goto err;
-			if (seqtt->flags & ASN1_TFLG_OPTIONAL)
-				{
-				ASN1_VALUE **pseqval;
-				pseqval = asn1_get_field_ptr(pval, seqtt);
-				ASN1_template_free(pseqval, seqtt);
-				}
-			else
-				{
-				errtt = seqtt;
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
-				goto err;
-				}
-			}
-		/* Save encoding */
-		if (!asn1_enc_save(pval, *in, p - *in, it))
-			goto auxerr;
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
-				goto auxerr;
-		*in = p;
-		return 1;
+    default:
+        return 0;
+    }
+ auxerr:
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
+ err:
+    if (combine == 0)
+        ASN1_item_ex_free(pval, it);
+    if (errtt)
+        ERR_add_error_data(4, "Field=", errtt->field_name,
+                           ", Type=", it->sname);
+    else
+        ERR_add_error_data(2, "Type=", it->sname);
+    return 0;
+}
 
-		default:
-		return 0;
-		}
-	auxerr:
-	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
-	err:
-	if (combine == 0)
-		ASN1_item_ex_free(pval, it);
-	if (errtt)
-		ERR_add_error_data(4, "Field=", errtt->field_name,
-					", Type=", it->sname);
-	else
-		ERR_add_error_data(2, "Type=", it->sname);
-	return 0;
-	}
-
-/* Templates are handled with two separate functions.
- * One handles any EXPLICIT tag and the other handles the rest.
+/*
+ * Templates are handled with two separate functions. One handles any
+ * EXPLICIT tag and the other handles the rest.
  */
 
 static int asn1_template_ex_d2i(ASN1_VALUE **val,
-				const unsigned char **in, long inlen,
-				const ASN1_TEMPLATE *tt, char opt,
-							ASN1_TLC *ctx)
-	{
-	int flags, aclass;
-	int ret;
-	long len;
-	const unsigned char *p, *q;
-	char exp_eoc;
-	if (!val)
-		return 0;
-	flags = tt->flags;
-	aclass = flags & ASN1_TFLG_TAG_CLASS;
+                                const unsigned char **in, long inlen,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx)
+{
+    int flags, aclass;
+    int ret;
+    long len;
+    const unsigned char *p, *q;
+    char exp_eoc;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
 
-	p = *in;
+    p = *in;
 
-	/* Check if EXPLICIT tag expected */
-	if (flags & ASN1_TFLG_EXPTAG)
-		{
-		char cst;
-		/* Need to work out amount of data available to the inner
-		 * content and where it starts: so read in EXPLICIT header to
-		 * get the info.
-		 */
-		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
-					&p, inlen, tt->tag, aclass, opt, ctx);
-		q = p;
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
-		else if (ret == -1)
-			return -1;
-		if (!cst)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
-			return 0;
-			}
-		/* We've found the field so it can't be OPTIONAL now */
-		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
-		/* We read the field in OK so update length */
-		len -= p - q;
-		if (exp_eoc)
-			{
-			/* If NDEF we must have an EOC here */
-			if (!asn1_check_eoc(&p, len))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
-				goto err;
-				}
-			}
-		else
-			{
-			/* Otherwise we must hit the EXPLICIT tag end or its
-			 * an error */
-			if (len)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
-				goto err;
-				}
-			}
-		}
-		else 
-			return asn1_template_noexp_d2i(val, in, inlen,
-								tt, opt, ctx);
+    /* Check if EXPLICIT tag expected */
+    if (flags & ASN1_TFLG_EXPTAG) {
+        char cst;
+        /*
+         * Need to work out amount of data available to the inner content and
+         * where it starts: so read in EXPLICIT header to get the info.
+         */
+        ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+                              &p, inlen, tt->tag, aclass, opt, ctx);
+        q = p;
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!cst) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+            return 0;
+        }
+        /* We've found the field so it can't be OPTIONAL now */
+        ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        /* We read the field in OK so update length */
+        len -= p - q;
+        if (exp_eoc) {
+            /* If NDEF we must have an EOC here */
+            if (!asn1_check_eoc(&p, len)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+                goto err;
+            }
+        } else {
+            /*
+             * Otherwise we must hit the EXPLICIT tag end or its an error
+             */
+            if (len) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+                goto err;
+            }
+        }
+    } else
+        return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
 
-	*in = p;
-	return 1;
+    *in = p;
+    return 1;
 
-	err:
-	ASN1_template_free(val, tt);
-	return 0;
-	}
+ err:
+    ASN1_template_free(val, tt);
+    return 0;
+}
 
 static int asn1_template_noexp_d2i(ASN1_VALUE **val,
-				const unsigned char **in, long len,
-				const ASN1_TEMPLATE *tt, char opt,
-				ASN1_TLC *ctx)
-	{
-	int flags, aclass;
-	int ret;
-	const unsigned char *p;
-	if (!val)
-		return 0;
-	flags = tt->flags;
-	aclass = flags & ASN1_TFLG_TAG_CLASS;
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx)
+{
+    int flags, aclass;
+    int ret;
+    const unsigned char *p;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
 
-	p = *in;
+    p = *in;
 
-	if (flags & ASN1_TFLG_SK_MASK)
-		{
-		/* SET OF, SEQUENCE OF */
-		int sktag, skaclass;
-		char sk_eoc;
-		/* First work out expected inner tag value */
-		if (flags & ASN1_TFLG_IMPTAG)
-			{
-			sktag = tt->tag;
-			skaclass = aclass;
-			}
-		else
-			{
-			skaclass = V_ASN1_UNIVERSAL;
-			if (flags & ASN1_TFLG_SET_OF)
-				sktag = V_ASN1_SET;
-			else
-				sktag = V_ASN1_SEQUENCE;
-			}
-		/* Get the tag */
-		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
-					&p, len, sktag, skaclass, opt, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
-		else if (ret == -1)
-			return -1;
-		if (!*val)
-			*val = (ASN1_VALUE *)sk_new_null();
-		else
-			{
-			/* We've got a valid STACK: free up any items present */
-			STACK_OF(ASN1_VALUE) *sktmp
-			    = (STACK_OF(ASN1_VALUE) *)*val;
-			ASN1_VALUE *vtmp;
-			while(sk_ASN1_VALUE_num(sktmp) > 0)
-				{
-				vtmp = sk_ASN1_VALUE_pop(sktmp);
-				ASN1_item_ex_free(&vtmp,
-						ASN1_ITEM_ptr(tt->item));
-				}
-			}
-				
-		if (!*val)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        int sktag, skaclass;
+        char sk_eoc;
+        /* First work out expected inner tag value */
+        if (flags & ASN1_TFLG_IMPTAG) {
+            sktag = tt->tag;
+            skaclass = aclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (flags & ASN1_TFLG_SET_OF)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
+        /* Get the tag */
+        ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+                              &p, len, sktag, skaclass, opt, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!*val)
+            *val = (ASN1_VALUE *)sk_new_null();
+        else {
+            /*
+             * We've got a valid STACK: free up any items present
+             */
+            STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
+            ASN1_VALUE *vtmp;
+            while (sk_ASN1_VALUE_num(sktmp) > 0) {
+                vtmp = sk_ASN1_VALUE_pop(sktmp);
+                ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+            }
+        }
 
-		/* Read as many items as we can */
-		while(len > 0)
-			{
-			ASN1_VALUE *skfield;
-			const unsigned char *q = p;
-			/* See if EOC found */
-			if (asn1_check_eoc(&p, len))
-				{
-				if (!sk_eoc)
-					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
-					goto err;
-					}
-				len -= p - q;
-				sk_eoc = 0;
-				break;
-				}
-			skfield = NULL;
-			if (!ASN1_item_ex_d2i(&skfield, &p, len,
-						ASN1_ITEM_ptr(tt->item),
-						-1, 0, 0, ctx))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-				goto err;
-				}
-			len -= p - q;
-			if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
-						skfield))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			}
-		if (sk_eoc)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
-			goto err;
-			}
-		}
-	else if (flags & ASN1_TFLG_IMPTAG)
-		{
-		/* IMPLICIT tagging */
-		ret = ASN1_item_ex_d2i(val, &p, len,
-			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
-		else if (ret == -1)
-			return -1;
-		}
-	else
-		{
-		/* Nothing special */
-		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-							-1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			goto err;
-			}
-		else if (ret == -1)
-			return -1;
-		}
+        if (!*val) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
 
-	*in = p;
-	return 1;
+        /* Read as many items as we can */
+        while (len > 0) {
+            ASN1_VALUE *skfield;
+            const unsigned char *q = p;
+            /* See if EOC found */
+            if (asn1_check_eoc(&p, len)) {
+                if (!sk_eoc) {
+                    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                sk_eoc = 0;
+                break;
+            }
+            skfield = NULL;
+            if (!ASN1_item_ex_d2i(&skfield, &p, len,
+                                  ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+                goto err;
+            }
+            len -= p - q;
+            if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
+        if (sk_eoc) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+    } else if (flags & ASN1_TFLG_IMPTAG) {
+        /* IMPLICIT tagging */
+        ret = ASN1_item_ex_d2i(val, &p, len,
+                               ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
+                               ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    } else {
+        /* Nothing special */
+        ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+                               -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    }
 
-	err:
-	ASN1_template_free(val, tt);
-	return 0;
-	}
+    *in = p;
+    return 1;
+
+ err:
+    ASN1_template_free(val, tt);
+    return 0;
+}
 
 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
-				const unsigned char **in, long inlen, 
-				const ASN1_ITEM *it,
-				int tag, int aclass, char opt, ASN1_TLC *ctx)
-        OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-	{
-	int ret = 0, utype;
-	long plen;
-	char cst, inf, free_cont = 0;
-	const unsigned char *p;
-	BUF_MEM buf;
-	const unsigned char *cont = NULL;
-	long len; 
-	if (!pval)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
-		return 0; /* Should never happen */
-		}
+                                 const unsigned char **in, long inlen,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    int ret = 0, utype;
+    long plen;
+    char cst, inf, free_cont = 0;
+    const unsigned char *p;
+    BUF_MEM buf = {0, NULL, 0 };
+    const unsigned char *cont = NULL;
+    long len;
+    if (!pval) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
+        return 0;               /* Should never happen */
+    }
 
-	if (it->itype == ASN1_ITYPE_MSTRING)
-		{
-		utype = tag;
-		tag = -1;
-		}
-	else
-		utype = it->utype;
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = tag;
+        tag = -1;
+    } else
+        utype = it->utype;
 
-	if (utype == V_ASN1_ANY)
-		{
-		/* If type is ANY need to figure out type from tag */
-		unsigned char oclass;
-		if (tag >= 0)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
-			return 0;
-			}
-		if (opt)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
-			return 0;
-			}
-		p = *in;
-		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
-					&p, inlen, -1, 0, 0, ctx);
-		if (!ret)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
-		if (oclass != V_ASN1_UNIVERSAL)
-			utype = V_ASN1_OTHER;
-		}
-	if (tag == -1)
-		{
-		tag = utype;
-		aclass = V_ASN1_UNIVERSAL;
-		}
-	p = *in;
-	/* Check header */
-	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
-				&p, inlen, tag, aclass, opt, ctx);
-	if (!ret)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-		return 0;
-		}
-	else if (ret == -1)
-		return -1;
-        ret = 0;
-	/* SEQUENCE, SET and "OTHER" are left in encoded form */
-	if ((utype == V_ASN1_SEQUENCE)
-		|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
-		{
-		/* Clear context cache for type OTHER because the auto clear
-		 * when we have a exact match wont work
-		 */
-		if (utype == V_ASN1_OTHER)
-			{
-			asn1_tlc_clear(ctx);
-			}
-		/* SEQUENCE and SET must be constructed */
-		else if (!cst)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
-			return 0;
-			}
+    if (utype == V_ASN1_ANY) {
+        /* If type is ANY need to figure out type from tag */
+        unsigned char oclass;
+        if (tag >= 0) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
+            return 0;
+        }
+        if (opt) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
+            return 0;
+        }
+        p = *in;
+        ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+                              &p, inlen, -1, 0, 0, ctx);
+        if (!ret) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (oclass != V_ASN1_UNIVERSAL)
+            utype = V_ASN1_OTHER;
+    }
+    if (tag == -1) {
+        tag = utype;
+        aclass = V_ASN1_UNIVERSAL;
+    }
+    p = *in;
+    /* Check header */
+    ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+                          &p, inlen, tag, aclass, opt, ctx);
+    if (!ret) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+        return 0;
+    } else if (ret == -1)
+        return -1;
+    ret = 0;
+    /* SEQUENCE, SET and "OTHER" are left in encoded form */
+    if ((utype == V_ASN1_SEQUENCE)
+        || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
+        /*
+         * Clear context cache for type OTHER because the auto clear when we
+         * have a exact match wont work
+         */
+        if (utype == V_ASN1_OTHER) {
+            asn1_tlc_clear(ctx);
+        }
+        /* SEQUENCE and SET must be constructed */
+        else if (!cst) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
+            return 0;
+        }
 
-		cont = *in;
-		/* If indefinite length constructed find the real end */
-		if (inf)
-			{
-			if (!asn1_find_end(&p, plen, inf))
-				 goto err;
-			len = p - cont;
-			}
-		else
-			{
-			len = p - cont + plen;
-			p += plen;
-			buf.data = NULL;
-			}
-		}
-	else if (cst)
-		{
-		if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
-			|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
-			|| utype == V_ASN1_ENUMERATED)
-			{
-			/* These types only have primitive encodings. */
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
-			return 0;
-			}
+        cont = *in;
+        /* If indefinite length constructed find the real end */
+        if (inf) {
+            if (!asn1_find_end(&p, plen, inf))
+                goto err;
+            len = p - cont;
+        } else {
+            len = p - cont + plen;
+            p += plen;
+        }
+    } else if (cst) {
+        if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+            || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+            || utype == V_ASN1_ENUMERATED) {
+            /* These types only have primitive encodings. */
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
+            return 0;
+        }
 
-		buf.length = 0;
-		buf.max = 0;
-		buf.data = NULL;
-		/* Should really check the internal tags are correct but
-		 * some things may get this wrong. The relevant specs
-		 * say that constructed string types should be OCTET STRINGs
-		 * internally irrespective of the type. So instead just check
-		 * for UNIVERSAL class and ignore the tag.
-		 */
-		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
-			{
-			free_cont = 1;
-			goto err;
-			}
-		len = buf.length;
-		/* Append a final null to string */
-		if (!BUF_MEM_grow_clean(&buf, len + 1))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return 0;
-			}
-		buf.data[len] = 0;
-		cont = (const unsigned char *)buf.data;
-		free_cont = 1;
-		}
-	else
-		{
-		cont = p;
-		len = plen;
-		p += plen;
-		}
+        /* Free any returned 'buf' content */
+        free_cont = 1;
+        /*
+         * Should really check the internal tags are correct but some things
+         * may get this wrong. The relevant specs say that constructed string
+         * types should be OCTET STRINGs internally irrespective of the type.
+         * So instead just check for UNIVERSAL class and ignore the tag.
+         */
+        if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+            goto err;
+        }
+        len = buf.length;
+        /* Append a final null to string */
+        if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        buf.data[len] = 0;
+        cont = (const unsigned char *)buf.data;
+    } else {
+        cont = p;
+        len = plen;
+        p += plen;
+    }
 
-	/* We now have content length and type: translate into a structure */
-	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
-		goto err;
+    /* We now have content length and type: translate into a structure */
+    /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
+    if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+        goto err;
 
-	*in = p;
-	ret = 1;
-	err:
-	if (free_cont && buf.data) OPENSSL_free(buf.data);
-	return ret;
-	}
+    *in = p;
+    ret = 1;
+ err:
+    if (free_cont && buf.data)
+        OPENSSL_free(buf.data);
+    return ret;
+}
 
 /* Translate ASN1 content octets into a structure */
 
 int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-			int utype, char *free_cont, const ASN1_ITEM *it)
-	{
-	ASN1_VALUE **opval = NULL;
-	ASN1_STRING *stmp;
-	ASN1_TYPE *typ = NULL;
-	int ret = 0;
-	const ASN1_PRIMITIVE_FUNCS *pf;
-	ASN1_INTEGER **tint;
-	pf = it->funcs;
+                int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    ASN1_VALUE **opval = NULL;
+    ASN1_STRING *stmp;
+    ASN1_TYPE *typ = NULL;
+    int ret = 0;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    ASN1_INTEGER **tint;
+    pf = it->funcs;
 
-	if (pf && pf->prim_c2i)
-		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
-	/* If ANY type clear type and set pointer to internal value */
-	if (it->utype == V_ASN1_ANY)
-		{
-		if (!*pval)
-			{
-			typ = ASN1_TYPE_new();
-			if (typ == NULL)
-				goto err;
-			*pval = (ASN1_VALUE *)typ;
-			}
-		else
-			typ = (ASN1_TYPE *)*pval;
+    if (pf && pf->prim_c2i)
+        return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+    /* If ANY type clear type and set pointer to internal value */
+    if (it->utype == V_ASN1_ANY) {
+        if (!*pval) {
+            typ = ASN1_TYPE_new();
+            if (typ == NULL)
+                goto err;
+            *pval = (ASN1_VALUE *)typ;
+        } else
+            typ = (ASN1_TYPE *)*pval;
 
-		if (utype != typ->type)
-			ASN1_TYPE_set(typ, utype, NULL);
-		opval = pval;
-		pval = &typ->value.asn1_value;
-		}
-	switch(utype)
-		{
-		case V_ASN1_OBJECT:
-		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
-			goto err;
-		break;
+        if (utype != typ->type)
+            ASN1_TYPE_set(typ, utype, NULL);
+        opval = pval;
+        pval = &typ->value.asn1_value;
+    }
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+            goto err;
+        break;
 
-		case V_ASN1_NULL:
-		if (len)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
-			goto err;
-			}
-		*pval = (ASN1_VALUE *)1;
-		break;
+    case V_ASN1_NULL:
+        if (len) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
+            goto err;
+        }
+        *pval = (ASN1_VALUE *)1;
+        break;
 
-		case V_ASN1_BOOLEAN:
-		if (len != 1)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
-			goto err;
-			}
-		else
-			{
-			ASN1_BOOLEAN *tbool;
-			tbool = (ASN1_BOOLEAN *)pval;
-			*tbool = *cont;
-			}
-		break;
+    case V_ASN1_BOOLEAN:
+        if (len != 1) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+            goto err;
+        } else {
+            ASN1_BOOLEAN *tbool;
+            tbool = (ASN1_BOOLEAN *)pval;
+            *tbool = *cont;
+        }
+        break;
 
-		case V_ASN1_BIT_STRING:
-		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
-			goto err;
-		break;
+    case V_ASN1_BIT_STRING:
+        if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+            goto err;
+        break;
 
-		case V_ASN1_INTEGER:
-		case V_ASN1_NEG_INTEGER:
-		case V_ASN1_ENUMERATED:
-		case V_ASN1_NEG_ENUMERATED:
-		tint = (ASN1_INTEGER **)pval;
-		if (!c2i_ASN1_INTEGER(tint, &cont, len))
-			goto err;
-		/* Fixup type to match the expected form */
-		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
-		break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_NEG_INTEGER:
+    case V_ASN1_ENUMERATED:
+    case V_ASN1_NEG_ENUMERATED:
+        tint = (ASN1_INTEGER **)pval;
+        if (!c2i_ASN1_INTEGER(tint, &cont, len))
+            goto err;
+        /* Fixup type to match the expected form */
+        (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+        break;
 
-		case V_ASN1_OCTET_STRING:
-		case V_ASN1_NUMERICSTRING:
-		case V_ASN1_PRINTABLESTRING:
-		case V_ASN1_T61STRING:
-		case V_ASN1_VIDEOTEXSTRING:
-		case V_ASN1_IA5STRING:
-		case V_ASN1_UTCTIME:
-		case V_ASN1_GENERALIZEDTIME:
-		case V_ASN1_GRAPHICSTRING:
-		case V_ASN1_VISIBLESTRING:
-		case V_ASN1_GENERALSTRING:
-		case V_ASN1_UNIVERSALSTRING:
-		case V_ASN1_BMPSTRING:
-		case V_ASN1_UTF8STRING:
-		case V_ASN1_OTHER:
-		case V_ASN1_SET:
-		case V_ASN1_SEQUENCE:
-		default:
-		if (utype == V_ASN1_BMPSTRING && (len & 1))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
-			goto err;
-			}
-		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
-			goto err;
-			}
-		/* All based on ASN1_STRING and handled the same */
-		if (!*pval)
-			{
-			stmp = ASN1_STRING_type_new(utype);
-			if (!stmp)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			*pval = (ASN1_VALUE *)stmp;
-			}
-		else
-			{
-			stmp = (ASN1_STRING *)*pval;
-			stmp->type = utype;
-			}
-		/* If we've already allocated a buffer use it */
-		if (*free_cont)
-			{
-			if (stmp->data)
-				OPENSSL_free(stmp->data);
-			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
-			stmp->length = len;
-			*free_cont = 0;
-			}
-		else
-			{
-			if (!ASN1_STRING_set(stmp, cont, len))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-				ASN1_STRING_free(stmp);	
-				*pval = NULL;
-				goto err;
-				}
-			}
-		break;
-		}
-	/* If ASN1_ANY and NULL type fix up value */
-	if (typ && (utype == V_ASN1_NULL))
-		 typ->value.ptr = NULL;
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    case V_ASN1_SET:
+    case V_ASN1_SEQUENCE:
+    default:
+        if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        /* All based on ASN1_STRING and handled the same */
+        if (!*pval) {
+            stmp = ASN1_STRING_type_new(utype);
+            if (!stmp) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            *pval = (ASN1_VALUE *)stmp;
+        } else {
+            stmp = (ASN1_STRING *)*pval;
+            stmp->type = utype;
+        }
+        /* If we've already allocated a buffer use it */
+        if (*free_cont) {
+            if (stmp->data)
+                OPENSSL_free(stmp->data);
+            stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+            stmp->length = len;
+            *free_cont = 0;
+        } else {
+            if (!ASN1_STRING_set(stmp, cont, len)) {
+                OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+                ASN1_STRING_free(stmp);
+                *pval = NULL;
+                goto err;
+            }
+        }
+        break;
+    }
+    /* If ASN1_ANY and NULL type fix up value */
+    if (typ && (utype == V_ASN1_NULL))
+        typ->value.ptr = NULL;
 
-	ret = 1;
-	err:
-	if (!ret)
-		{
-		ASN1_TYPE_free(typ);
-		if (opval)
-			*opval = NULL;
-		}
-	return ret;
-	}
+    ret = 1;
+ err:
+    if (!ret) {
+        ASN1_TYPE_free(typ);
+        if (opval)
+            *opval = NULL;
+    }
+    return ret;
+}
 
-
-/* This function finds the end of an ASN1 structure when passed its maximum
- * length, whether it is indefinite length and a pointer to the content.
- * This is more efficient than calling asn1_collect because it does not
- * recurse on each indefinite length header.
+/*
+ * This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content. This
+ * is more efficient than calling asn1_collect because it does not recurse on
+ * each indefinite length header.
  */
 
 static int asn1_find_end(const unsigned char **in, long len, char inf)
-	{
-	int expected_eoc;
-	long plen;
-	const unsigned char *p = *in, *q;
-	/* If not indefinite length constructed just add length */
-	if (inf == 0)
-		{
-		*in += len;
-		return 1;
-		}
-	expected_eoc = 1;
-	/* Indefinite length constructed form. Find the end when enough EOCs
-	 * are found. If more indefinite length constructed headers
-	 * are encountered increment the expected eoc count otherwise just
-	 * skip to the end of the data.
-	 */
-	while (len > 0)
-		{
-		if(asn1_check_eoc(&p, len))
-			{
-			expected_eoc--;
-			if (expected_eoc == 0)
-				break;
-			len -= 2;
-			continue;
-			}
-		q = p;
-		/* Just read in a header: only care about the length */
-		if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-				-1, 0, 0, NULL))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
-		if (inf)
-			expected_eoc++;
-		else
-			p += plen;
-		len -= p - q;
-		}
-	if (expected_eoc)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
-		return 0;
-		}
-	*in = p;
-	return 1;
-	}
-/* This function collects the asn1 data from a constructred string
- * type into a buffer. The values of 'in' and 'len' should refer
- * to the contents of the constructed type and 'inf' should be set
- * if it is indefinite length.
+{
+    int expected_eoc;
+    long plen;
+    const unsigned char *p = *in, *q;
+    /* If not indefinite length constructed just add length */
+    if (inf == 0) {
+        *in += len;
+        return 1;
+    }
+    expected_eoc = 1;
+    /*
+     * Indefinite length constructed form. Find the end when enough EOCs are
+     * found. If more indefinite length constructed headers are encountered
+     * increment the expected eoc count otherwise just skip to the end of the
+     * data.
+     */
+    while (len > 0) {
+        if (asn1_check_eoc(&p, len)) {
+            expected_eoc--;
+            if (expected_eoc == 0)
+                break;
+            len -= 2;
+            continue;
+        }
+        q = p;
+        /* Just read in a header: only care about the length */
+        if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+                             -1, 0, 0, NULL)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (inf)
+            expected_eoc++;
+        else
+            p += plen;
+        len -= p - q;
+    }
+    if (expected_eoc) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
+
+/*
+ * This function collects the asn1 data from a constructred string type into
+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
+ * constructed type and 'inf' should be set if it is indefinite length.
  */
 
 #ifndef ASN1_MAX_STRING_NEST
-/* This determines how many levels of recursion are permitted in ASN1
- * string types. If it is not limited stack overflows can occur. If set
- * to zero no recursion is allowed at all. Although zero should be adequate
- * examples exist that require a value of 1. So 5 should be more than enough.
+/*
+ * This determines how many levels of recursion are permitted in ASN1 string
+ * types. If it is not limited stack overflows can occur. If set to zero no
+ * recursion is allowed at all. Although zero should be adequate examples
+ * exist that require a value of 1. So 5 should be more than enough.
  */
-#define ASN1_MAX_STRING_NEST 5
+# define ASN1_MAX_STRING_NEST 5
 #endif
 
-
 static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-			char inf, int tag, int aclass, int depth)
-	{
-	const unsigned char *p, *q;
-	long plen;
-	char cst, ininf;
-	p = *in;
-	inf &= 1;
-	/* If no buffer and not indefinite length constructed just pass over
-	 * the encoded data */
-	if (!buf && !inf)
-		{
-		*in += len;
-		return 1;
-		}
-	while(len > 0)
-		{
-		q = p;
-		/* Check for EOC */
-		if (asn1_check_eoc(&p, len))
-			{
-			/* EOC is illegal outside indefinite length
-			 * constructed form */
-			if (!inf)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
-				return 0;
-				}
-			inf = 0;
-			break;
-			}
+                        char inf, int tag, int aclass, int depth)
+{
+    const unsigned char *p, *q;
+    long plen;
+    char cst, ininf;
+    p = *in;
+    inf &= 1;
+    /*
+     * If no buffer and not indefinite length constructed just pass over the
+     * encoded data
+     */
+    if (!buf && !inf) {
+        *in += len;
+        return 1;
+    }
+    while (len > 0) {
+        q = p;
+        /* Check for EOC */
+        if (asn1_check_eoc(&p, len)) {
+            /*
+             * EOC is illegal outside indefinite length constructed form
+             */
+            if (!inf) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+                return 0;
+            }
+            inf = 0;
+            break;
+        }
 
-		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
-					len, tag, aclass, 0, NULL))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
-			return 0;
-			}
+        if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+                             len, tag, aclass, 0, NULL)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
 
-		/* If indefinite length constructed update max length */
-		if (cst)
-			{
-			if (depth >= ASN1_MAX_STRING_NEST)
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
-				return 0;
-				}
-			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
-						depth + 1))
-				return 0;
-			}
-		else if (plen && !collect_data(buf, &p, plen))
-			return 0;
-		len -= p - q;
-		}
-	if (inf)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
-		return 0;
-		}
-	*in = p;
-	return 1;
-	}
+        /* If indefinite length constructed update max length */
+        if (cst) {
+            if (depth >= ASN1_MAX_STRING_NEST) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
+                return 0;
+            }
+            if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
+                return 0;
+        } else if (plen && !collect_data(buf, &p, plen))
+            return 0;
+        len -= p - q;
+    }
+    if (inf) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
 
 static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
-	{
-	int len;
-	if (buf)
-		{
-		len = buf->length;
-		if (!BUF_MEM_grow_clean(buf, len + plen))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			return 0;
-			}
-		memcpy(buf->data + len, *p, plen);
-		}
-	*p += plen;
-	return 1;
-	}
+{
+    int len;
+    if (buf) {
+        len = buf->length;
+        if (!BUF_MEM_grow_clean(buf, len + plen)) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(buf->data + len, *p, plen);
+    }
+    *p += plen;
+    return 1;
+}
 
 /* Check for ASN1 EOC and swallow it if found */
 
 static int asn1_check_eoc(const unsigned char **in, long len)
-	{
-	const unsigned char *p;
-	if (len < 2) return 0;
-	p = *in;
-	if (!p[0] && !p[1])
-		{
-		*in += 2;
-		return 1;
-		}
-	return 0;
-	}
+{
+    const unsigned char *p;
+    if (len < 2)
+        return 0;
+    p = *in;
+    if (!p[0] && !p[1]) {
+        *in += 2;
+        return 1;
+    }
+    return 0;
+}
 
-/* Check an ASN1 tag and length: a bit like ASN1_get_object
- * but it sets the length for indefinite length constructed
- * form, we don't know the exact length but we can set an
- * upper bound to the amount of data available minus the
- * header length just read.
+/*
+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
+ * length for indefinite length constructed form, we don't know the exact
+ * length but we can set an upper bound to the amount of data available minus
+ * the header length just read.
  */
 
 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
-				char *inf, char *cst,
-				const unsigned char **in, long len,
-				int exptag, int expclass, char opt,
-				ASN1_TLC *ctx)
-	{
-	int i;
-	int ptag, pclass;
-	long plen;
-	const unsigned char *p, *q;
-	p = *in;
-	q = p;
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+    int i;
+    int ptag, pclass;
+    long plen;
+    const unsigned char *p, *q;
+    p = *in;
+    q = p;
 
-	if (ctx && ctx->valid)
-		{
-		i = ctx->ret;
-		plen = ctx->plen;
-		pclass = ctx->pclass;
-		ptag = ctx->ptag;
-		p += ctx->hdrlen;
-		}
-	else
-		{
-		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
-		if (ctx)
-			{
-			ctx->ret = i;
-			ctx->plen = plen;
-			ctx->pclass = pclass;
-			ctx->ptag = ptag;
-			ctx->hdrlen = p - q;
-			ctx->valid = 1;
-			/* If definite length, and no error, length +
-			 * header can't exceed total amount of data available. 
-			 */
-			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
-				asn1_tlc_clear(ctx);
-				return 0;
-				}
-			}
-		}
+    if (ctx && ctx->valid) {
+        i = ctx->ret;
+        plen = ctx->plen;
+        pclass = ctx->pclass;
+        ptag = ctx->ptag;
+        p += ctx->hdrlen;
+    } else {
+        i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+        if (ctx) {
+            ctx->ret = i;
+            ctx->plen = plen;
+            ctx->pclass = pclass;
+            ctx->ptag = ptag;
+            ctx->hdrlen = p - q;
+            ctx->valid = 1;
+            /*
+             * If definite length, and no error, length + header can't exceed
+             * total amount of data available.
+             */
+            if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+                asn1_tlc_clear(ctx);
+                return 0;
+            }
+        }
+    }
 
-	if (i & 0x80)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
-		asn1_tlc_clear(ctx);
-		return 0;
-		}
-	if (exptag >= 0)
-		{
-		if ((exptag != ptag) || (expclass != pclass))
-			{
-			/* If type is OPTIONAL, not an error:
-			 * indicate missing type.
-			 */
-			if (opt) return -1;
-			asn1_tlc_clear(ctx);
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
-			return 0;
-			}
-		/* We have a tag and class match:
-		 * assume we are going to do something with it */
-		asn1_tlc_clear(ctx);
-		}
+    if (i & 0x80) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
+        asn1_tlc_clear(ctx);
+        return 0;
+    }
+    if (exptag >= 0) {
+        if ((exptag != ptag) || (expclass != pclass)) {
+            /*
+             * If type is OPTIONAL, not an error: indicate missing type.
+             */
+            if (opt)
+                return -1;
+            asn1_tlc_clear(ctx);
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
+            return 0;
+        }
+        /*
+         * We have a tag and class match: assume we are going to do something
+         * with it
+         */
+        asn1_tlc_clear(ctx);
+    }
 
-	if (i & 1)
-		plen = len - (p - q);
+    if (i & 1)
+        plen = len - (p - q);
 
-	if (inf)
-		*inf = i & 1;
+    if (inf)
+        *inf = i & 1;
 
-	if (cst)
-		*cst = i & V_ASN1_CONSTRUCTED;
+    if (cst)
+        *cst = i & V_ASN1_CONSTRUCTED;
 
-	if (olen)
-		*olen = plen;
+    if (olen)
+        *olen = plen;
 
-	if (oclass)
-		*oclass = pclass;
+    if (oclass)
+        *oclass = pclass;
 
-	if (otag)
-		*otag = ptag;
+    if (otag)
+        *otag = ptag;
 
-	*in = p;
-	return 1;
-	}
+    *in = p;
+    return 1;
+}
diff --git a/src/crypto/asn1/tasn_enc.c b/src/crypto/asn1/tasn_enc.c
index 38e14d2..a56d08e 100644
--- a/src/crypto/asn1/tasn_enc.c
+++ b/src/crypto/asn1/tasn_enc.c
@@ -61,635 +61,599 @@
 #include <openssl/asn1t.h>
 #include <openssl/mem.h>
 
-
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
-					const ASN1_ITEM *it,
-					int tag, int aclass);
+                                 const ASN1_ITEM *it, int tag, int aclass);
 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
-					int skcontlen, const ASN1_ITEM *item,
-					int do_sort, int iclass);
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass);
 static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-					const ASN1_TEMPLATE *tt,
-					int tag, int aclass);
+                                const ASN1_TEMPLATE *tt, int tag, int aclass);
 static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
-					const ASN1_ITEM *it, int flags);
+                               const ASN1_ITEM *it, int flags);
 
-/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
- * to use indefinite length constructed encoding, where appropriate
+/*
+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
+ * indefinite length constructed encoding, where appropriate
  */
 
 int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
-						const ASN1_ITEM *it)
-	{
-	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
-	}
+                       const ASN1_ITEM *it)
+{
+    return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
 
 int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
-	{
-	return asn1_item_flags_i2d(val, out, it, 0);
-	}
+{
+    return asn1_item_flags_i2d(val, out, it, 0);
+}
 
-/* Encode an ASN1 item, this is use by the
- * standard 'i2d' function. 'out' points to 
- * a buffer to output the data to.
- *
- * The new i2d has one additional feature. If the output
- * buffer is NULL (i.e. *out == NULL) then a buffer is
+/*
+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
+ * points to a buffer to output the data to. The new i2d has one additional
+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
  * allocated and populated with the encoding.
  */
 
 static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
-					const ASN1_ITEM *it, int flags)
-	{
-	if (out && !*out)
-		{
-		unsigned char *p, *buf;
-		int len;
-		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
-		if (len <= 0)
-			return len;
-		buf = OPENSSL_malloc(len);
-		if (!buf)
-			return -1;
-		p = buf;
-		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
-		*out = buf;
-		return len;
-		}
+                               const ASN1_ITEM *it, int flags)
+{
+    if (out && !*out) {
+        unsigned char *p, *buf;
+        int len;
+        len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+        if (len <= 0)
+            return len;
+        buf = OPENSSL_malloc(len);
+        if (!buf)
+            return -1;
+        p = buf;
+        ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+        *out = buf;
+        return len;
+    }
 
-	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
-	}
+    return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
 
-/* Encode an item, taking care of IMPLICIT tagging (if any).
- * This function performs the normal item handling: it can be
- * used in external types.
+/*
+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
+ * performs the normal item handling: it can be used in external types.
  */
 
 int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-			const ASN1_ITEM *it, int tag, int aclass)
-	{
-	const ASN1_TEMPLATE *tt = NULL;
-	unsigned char *p = NULL;
-	int i, seqcontlen, seqlen, ndef = 1;
-	const ASN1_COMPAT_FUNCS *cf;
-	const ASN1_EXTERN_FUNCS *ef;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_aux_cb *asn1_cb = 0;
+                     const ASN1_ITEM *it, int tag, int aclass)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    unsigned char *p = NULL;
+    int i, seqcontlen, seqlen, ndef = 1;
+    const ASN1_COMPAT_FUNCS *cf;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb = 0;
 
-	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
-		return 0;
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return 0;
 
-	if (aux && aux->asn1_cb)
-		 asn1_cb = aux->asn1_cb;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
 
-	switch(it->itype)
-		{
+    switch (it->itype) {
 
-		case ASN1_ITYPE_PRIMITIVE:
-		if (it->templates)
-			return asn1_template_ex_i2d(pval, out, it->templates,
-								tag, aclass);
-		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
-		break;
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            return asn1_template_ex_i2d(pval, out, it->templates,
+                                        tag, aclass);
+        return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+        break;
 
-		case ASN1_ITYPE_MSTRING:
-		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+    case ASN1_ITYPE_MSTRING:
+        return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
 
-		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
-				return 0;
-		i = asn1_get_choice_selector(pval, it);
-		if ((i >= 0) && (i < it->tcount))
-			{
-			ASN1_VALUE **pchval;
-			const ASN1_TEMPLATE *chtt;
-			chtt = it->templates + i;
-			pchval = asn1_get_field_ptr(pval, chtt);
-			return asn1_template_ex_i2d(pchval, out, chtt,
-								-1, aclass);
-			}
-		/* Fixme: error condition if selector out of range */
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
-				return 0;
-		break;
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+            const ASN1_TEMPLATE *chtt;
+            chtt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, chtt);
+            return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
+        }
+        /* Fixme: error condition if selector out of range */
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        break;
 
-		case ASN1_ITYPE_EXTERN:
-		/* If new style i2d it does all the work */
-		ef = it->funcs;
-		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+    case ASN1_ITYPE_EXTERN:
+        /* If new style i2d it does all the work */
+        ef = it->funcs;
+        return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
 
-		case ASN1_ITYPE_COMPAT:
-		/* old style hackery... */
-		cf = it->funcs;
-		if (out)
-			p = *out;
-		i = cf->asn1_i2d(*pval, out);
-		/* Fixup for IMPLICIT tag: note this messes up for tags > 30,
-		 * but so did the old code. Tags > 30 are very rare anyway.
-		 */
-		if (out && (tag != -1))
-			*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
-		return i;
-		
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		/* Use indefinite length constructed if requested */
-		if (aclass & ASN1_TFLG_NDEF) ndef = 2;
-		/* fall through */
+    case ASN1_ITYPE_COMPAT:
+        /* old style hackery... */
+        cf = it->funcs;
+        if (out)
+            p = *out;
+        i = cf->asn1_i2d(*pval, out);
+        /*
+         * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so
+         * did the old code. Tags > 30 are very rare anyway.
+         */
+        if (out && (tag != -1))
+            *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
+        return i;
 
-		case ASN1_ITYPE_SEQUENCE:
-		i = asn1_enc_restore(&seqcontlen, out, pval, it);
-		/* An error occurred */
-		if (i < 0)
-			return 0;
-		/* We have a valid cached encoding... */
-		if (i > 0)
-			return seqcontlen;
-		/* Otherwise carry on */
-		seqcontlen = 0;
-		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
-		if (tag == -1)
-			{
-			tag = V_ASN1_SEQUENCE;
-			/* Retain any other flags in aclass */
-			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
-					| V_ASN1_UNIVERSAL;
-			}
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
-				return 0;
-		/* First work out sequence content length */
-		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
-			{
-			const ASN1_TEMPLATE *seqtt;
-			ASN1_VALUE **pseqval;
-			seqtt = asn1_do_adb(pval, tt, 1);
-			if (!seqtt)
-				return 0;
-			pseqval = asn1_get_field_ptr(pval, seqtt);
-			/* FIXME: check for errors in enhanced version */
-			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-								-1, aclass);
-			}
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        /* Use indefinite length constructed if requested */
+        if (aclass & ASN1_TFLG_NDEF)
+            ndef = 2;
+        /* fall through */
 
-		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
-		if (!out)
-			return seqlen;
-		/* Output SEQUENCE header */
-		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
-		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
-			{
-			const ASN1_TEMPLATE *seqtt;
-			ASN1_VALUE **pseqval;
-			seqtt = asn1_do_adb(pval, tt, 1);
-			if (!seqtt)
-				return 0;
-			pseqval = asn1_get_field_ptr(pval, seqtt);
-			/* FIXME: check for errors in enhanced version */
-			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
-			}
-		if (ndef == 2)
-			ASN1_put_eoc(out);
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
-				return 0;
-		return seqlen;
+    case ASN1_ITYPE_SEQUENCE:
+        i = asn1_enc_restore(&seqcontlen, out, pval, it);
+        /* An error occurred */
+        if (i < 0)
+            return 0;
+        /* We have a valid cached encoding... */
+        if (i > 0)
+            return seqcontlen;
+        /* Otherwise carry on */
+        seqcontlen = 0;
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            /* Retain any other flags in aclass */
+            aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+                | V_ASN1_UNIVERSAL;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        /* First work out sequence content length */
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* FIXME: check for errors in enhanced version */
+            seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
+                                               -1, aclass);
+        }
 
-		default:
-		return 0;
+        seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+        if (!out)
+            return seqlen;
+        /* Output SEQUENCE header */
+        ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* FIXME: check for errors in enhanced version */
+            asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+        }
+        if (ndef == 2)
+            ASN1_put_eoc(out);
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        return seqlen;
 
-		}
-	return 0;
-	}
+    default:
+        return 0;
+
+    }
+    return 0;
+}
 
 int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
-							const ASN1_TEMPLATE *tt)
-	{
-	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
-	}
+                      const ASN1_TEMPLATE *tt)
+{
+    return asn1_template_ex_i2d(pval, out, tt, -1, 0);
+}
 
 static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-				const ASN1_TEMPLATE *tt, int tag, int iclass)
-	{
-	int i, ret, flags, ttag, tclass, ndef;
-	size_t j;
-	flags = tt->flags;
-	/* Work out tag and class to use: tagging may come
-	 * either from the template or the arguments, not both
-	 * because this would create ambiguity. Additionally
-	 * the iclass argument may contain some additional flags
-	 * which should be noted and passed down to other levels.
-	 */
-	if (flags & ASN1_TFLG_TAG_MASK)
-		{
-		/* Error if argument and template tagging */
-		if (tag != -1)
-			/* FIXME: error code here */
-			return -1;
-		/* Get tagging from template */
-		ttag = tt->tag;
-		tclass = flags & ASN1_TFLG_TAG_CLASS;
-		}
-	else if (tag != -1)
-		{
-		/* No template tagging, get from arguments */
-		ttag = tag;
-		tclass = iclass & ASN1_TFLG_TAG_CLASS;
-		}
-	else
-		{
-		ttag = -1;
-		tclass = 0;
-		}
-	/* 
-	 * Remove any class mask from iflag.
-	 */
-	iclass &= ~ASN1_TFLG_TAG_CLASS;
+                                const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+    int i, ret, flags, ttag, tclass, ndef;
+    size_t j;
+    flags = tt->flags;
+    /*
+     * Work out tag and class to use: tagging may come either from the
+     * template or the arguments, not both because this would create
+     * ambiguity. Additionally the iclass argument may contain some
+     * additional flags which should be noted and passed down to other
+     * levels.
+     */
+    if (flags & ASN1_TFLG_TAG_MASK) {
+        /* Error if argument and template tagging */
+        if (tag != -1)
+            /* FIXME: error code here */
+            return -1;
+        /* Get tagging from template */
+        ttag = tt->tag;
+        tclass = flags & ASN1_TFLG_TAG_CLASS;
+    } else if (tag != -1) {
+        /* No template tagging, get from arguments */
+        ttag = tag;
+        tclass = iclass & ASN1_TFLG_TAG_CLASS;
+    } else {
+        ttag = -1;
+        tclass = 0;
+    }
+    /*
+     * Remove any class mask from iflag.
+     */
+    iclass &= ~ASN1_TFLG_TAG_CLASS;
 
-	/* At this point 'ttag' contains the outer tag to use,
-	 * 'tclass' is the class and iclass is any flags passed
-	 * to this function.
-	 */
+    /*
+     * At this point 'ttag' contains the outer tag to use, 'tclass' is the
+     * class and iclass is any flags passed to this function.
+     */
 
-	/* if template and arguments require ndef, use it */
-	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
-		ndef = 2;
-	else ndef = 1;
+    /* if template and arguments require ndef, use it */
+    if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+        ndef = 2;
+    else
+        ndef = 1;
 
-	if (flags & ASN1_TFLG_SK_MASK)
-		{
-		/* SET OF, SEQUENCE OF */
-		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
-		int isset, sktag, skaclass;
-		int skcontlen, sklen;
-		ASN1_VALUE *skitem;
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        int isset, sktag, skaclass;
+        int skcontlen, sklen;
+        ASN1_VALUE *skitem;
 
-		if (!*pval)
-			return 0;
+        if (!*pval)
+            return 0;
 
-		if (flags & ASN1_TFLG_SET_OF)
-			{
-			isset = 1;
-			/* 2 means we reorder */
-			if (flags & ASN1_TFLG_SEQUENCE_OF)
-				isset = 2;
-			}
-		else isset = 0;
+        if (flags & ASN1_TFLG_SET_OF) {
+            isset = 1;
+            /* 2 means we reorder */
+            if (flags & ASN1_TFLG_SEQUENCE_OF)
+                isset = 2;
+        } else
+            isset = 0;
 
-		/* Work out inner tag value: if EXPLICIT
-		 * or no tagging use underlying type.
-		 */
-		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
-			{
-			sktag = ttag;
-			skaclass = tclass;
-			}
-		else
-			{
-			skaclass = V_ASN1_UNIVERSAL;
-			if (isset)
-				sktag = V_ASN1_SET;
-			else sktag = V_ASN1_SEQUENCE;
-			}
+        /*
+         * Work out inner tag value: if EXPLICIT or no tagging use underlying
+         * type.
+         */
+        if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+            sktag = ttag;
+            skaclass = tclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (isset)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
 
-		/* Determine total length of items */
-		skcontlen = 0;
-		for (j = 0; j < sk_ASN1_VALUE_num(sk); j++)
-			{
-			skitem = sk_ASN1_VALUE_value(sk, j);
-			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
-						ASN1_ITEM_ptr(tt->item),
-							-1, iclass);
-			}
-		sklen = ASN1_object_size(ndef, skcontlen, sktag);
-		/* If EXPLICIT need length of surrounding tag */
-		if (flags & ASN1_TFLG_EXPTAG)
-			ret = ASN1_object_size(ndef, sklen, ttag);
-		else ret = sklen;
+        /* Determine total length of items */
+        skcontlen = 0;
+        for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
+            skitem = sk_ASN1_VALUE_value(sk, j);
+            skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
+                                          ASN1_ITEM_ptr(tt->item),
+                                          -1, iclass);
+        }
+        sklen = ASN1_object_size(ndef, skcontlen, sktag);
+        /* If EXPLICIT need length of surrounding tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ret = ASN1_object_size(ndef, sklen, ttag);
+        else
+            ret = sklen;
 
-		if (!out)
-			return ret;
+        if (!out)
+            return ret;
 
-		/* Now encode this lot... */
-		/* EXPLICIT tag */
-		if (flags & ASN1_TFLG_EXPTAG)
-			ASN1_put_object(out, ndef, sklen, ttag, tclass);
-		/* SET or SEQUENCE and IMPLICIT tag */
-		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
-		/* And the stuff itself */
-		asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
-								isset, iclass);
-		if (ndef == 2)
-			{
-			ASN1_put_eoc(out);
-			if (flags & ASN1_TFLG_EXPTAG)
-				ASN1_put_eoc(out);
-			}
+        /* Now encode this lot... */
+        /* EXPLICIT tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ASN1_put_object(out, ndef, sklen, ttag, tclass);
+        /* SET or SEQUENCE and IMPLICIT tag */
+        ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+        /* And the stuff itself */
+        asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+                         isset, iclass);
+        if (ndef == 2) {
+            ASN1_put_eoc(out);
+            if (flags & ASN1_TFLG_EXPTAG)
+                ASN1_put_eoc(out);
+        }
 
-		return ret;
-		}
+        return ret;
+    }
 
-	if (flags & ASN1_TFLG_EXPTAG)
-		{
-		/* EXPLICIT tagging */
-		/* Find length of tagged item */
-		i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
-								-1, iclass);
-		if (!i)
-			return 0;
-		/* Find length of EXPLICIT tag */
-		ret = ASN1_object_size(ndef, i, ttag);
-		if (out)
-			{
-			/* Output tag and item */
-			ASN1_put_object(out, ndef, i, ttag, tclass);
-			ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-								-1, iclass);
-			if (ndef == 2)
-				ASN1_put_eoc(out);
-			}
-		return ret;
-		}
+    if (flags & ASN1_TFLG_EXPTAG) {
+        /* EXPLICIT tagging */
+        /* Find length of tagged item */
+        i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
+        if (!i)
+            return 0;
+        /* Find length of EXPLICIT tag */
+        ret = ASN1_object_size(ndef, i, ttag);
+        if (out) {
+            /* Output tag and item */
+            ASN1_put_object(out, ndef, i, ttag, tclass);
+            ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
+            if (ndef == 2)
+                ASN1_put_eoc(out);
+        }
+        return ret;
+    }
 
-	/* Either normal or IMPLICIT tagging: combine class and flags */
-	return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-						ttag, tclass | iclass);
+    /* Either normal or IMPLICIT tagging: combine class and flags */
+    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+                            ttag, tclass | iclass);
 
 }
 
 /* Temporary structure used to hold DER encoding of items for SET OF */
 
-typedef	struct {
-	unsigned char *data;
-	int length;
-	ASN1_VALUE *field;
+typedef struct {
+    unsigned char *data;
+    int length;
+    ASN1_VALUE *field;
 } DER_ENC;
 
 static int der_cmp(const void *a, const void *b)
-	{
-	const DER_ENC *d1 = a, *d2 = b;
-	int cmplen, i;
-	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
-	i = memcmp(d1->data, d2->data, cmplen);
-	if (i)
-		return i;
-	return d1->length - d2->length;
-	}
+{
+    const DER_ENC *d1 = a, *d2 = b;
+    int cmplen, i;
+    cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+    i = memcmp(d1->data, d2->data, cmplen);
+    if (i)
+        return i;
+    return d1->length - d2->length;
+}
 
 /* Output the content octets of SET OF or SEQUENCE OF */
 
 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
-					int skcontlen, const ASN1_ITEM *item,
-					int do_sort, int iclass)
-	{
-	size_t i;
-	ASN1_VALUE *skitem;
-	unsigned char *tmpdat = NULL, *p = NULL;
-	DER_ENC *derlst = NULL, *tder;
-	if (do_sort)
-		 {
-		/* Don't need to sort less than 2 items */
-		if (sk_ASN1_VALUE_num(sk) < 2)
-			do_sort = 0;
-		else
-			{
-			derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
-						* sizeof(*derlst));
-			if (!derlst)
-				return 0;
-			tmpdat = OPENSSL_malloc(skcontlen);
-			if (!tmpdat)
-				{
-				OPENSSL_free(derlst);
-				return 0;
-				}
-			}
-		}
-	/* If not sorting just output each item */
-	if (!do_sort)
-		{
-		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
-			{
-			skitem = sk_ASN1_VALUE_value(sk, i);
-			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
-			}
-		return 1;
-		}
-	p = tmpdat;
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass)
+{
+    size_t i;
+    ASN1_VALUE *skitem;
+    unsigned char *tmpdat = NULL, *p = NULL;
+    DER_ENC *derlst = NULL, *tder;
+    if (do_sort) {
+        /* Don't need to sort less than 2 items */
+        if (sk_ASN1_VALUE_num(sk) < 2)
+            do_sort = 0;
+        else {
+            derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+                                    * sizeof(*derlst));
+            if (!derlst)
+                return 0;
+            tmpdat = OPENSSL_malloc(skcontlen);
+            if (!tmpdat) {
+                OPENSSL_free(derlst);
+                return 0;
+            }
+        }
+    }
+    /* If not sorting just output each item */
+    if (!do_sort) {
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            skitem = sk_ASN1_VALUE_value(sk, i);
+            ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+        }
+        return 1;
+    }
+    p = tmpdat;
 
-	/* Doing sort: build up a list of each member's DER encoding */
-	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
-		{
-		skitem = sk_ASN1_VALUE_value(sk, i);
-		tder->data = p;
-		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
-		tder->field = skitem;
-		}
+    /* Doing sort: build up a list of each member's DER encoding */
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        skitem = sk_ASN1_VALUE_value(sk, i);
+        tder->data = p;
+        tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+        tder->field = skitem;
+    }
 
-	/* Now sort them */
-	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
-	/* Output sorted DER encoding */	
-	p = *out;
-	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
-		{
-		memcpy(p, tder->data, tder->length);
-		p += tder->length;
-		}
-	*out = p;
-	/* If do_sort is 2 then reorder the STACK */
-	if (do_sort == 2)
-		{
-		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
-							i++, tder++)
-			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
-		}
-	OPENSSL_free(derlst);
-	OPENSSL_free(tmpdat);
-	return 1;
-	}
+    /* Now sort them */
+    qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+    /* Output sorted DER encoding */
+    p = *out;
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        memcpy(p, tder->data, tder->length);
+        p += tder->length;
+    }
+    *out = p;
+    /* If do_sort is 2 then reorder the STACK */
+    if (do_sort == 2) {
+        for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+            (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+    }
+    OPENSSL_free(derlst);
+    OPENSSL_free(tmpdat);
+    return 1;
+}
 
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
-				const ASN1_ITEM *it, int tag, int aclass)
-	{
-	int len;
-	int utype;
-	int usetag;
-	int ndef = 0;
+                                 const ASN1_ITEM *it, int tag, int aclass)
+{
+    int len;
+    int utype;
+    int usetag;
+    int ndef = 0;
 
-	utype = it->utype;
+    utype = it->utype;
 
-	/* Get length of content octets and maybe find
-	 * out the underlying type.
-	 */
+    /*
+     * Get length of content octets and maybe find out the underlying type.
+     */
 
-	len = asn1_ex_i2c(pval, NULL, &utype, it);
+    len = asn1_ex_i2c(pval, NULL, &utype, it);
 
-	/* If SEQUENCE, SET or OTHER then header is
-	 * included in pseudo content octets so don't
-	 * include tag+length. We need to check here
-	 * because the call to asn1_ex_i2c() could change
-	 * utype.
-	 */
-	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
-	   (utype == V_ASN1_OTHER))
-		usetag = 0;
-	else usetag = 1;
+    /*
+     * If SEQUENCE, SET or OTHER then header is included in pseudo content
+     * octets so don't include tag+length. We need to check here because the
+     * call to asn1_ex_i2c() could change utype.
+     */
+    if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+        (utype == V_ASN1_OTHER))
+        usetag = 0;
+    else
+        usetag = 1;
 
-	/* -1 means omit type */
+    /* -1 means omit type */
 
-	if (len == -1)
-		return 0;
+    if (len == -1)
+        return 0;
 
-	/* -2 return is special meaning use ndef */
-	if (len == -2)
-		{
-		ndef = 2;
-		len = 0;
-		}
+    /* -2 return is special meaning use ndef */
+    if (len == -2) {
+        ndef = 2;
+        len = 0;
+    }
 
-	/* If not implicitly tagged get tag from underlying type */
-	if (tag == -1) tag = utype;
+    /* If not implicitly tagged get tag from underlying type */
+    if (tag == -1)
+        tag = utype;
 
-	/* Output tag+length followed by content octets */
-	if (out)
-		{
-		if (usetag)
-			ASN1_put_object(out, ndef, len, tag, aclass);
-		asn1_ex_i2c(pval, *out, &utype, it);
-		if (ndef)
-			ASN1_put_eoc(out);
-		else
-			*out += len;
-		}
+    /* Output tag+length followed by content octets */
+    if (out) {
+        if (usetag)
+            ASN1_put_object(out, ndef, len, tag, aclass);
+        asn1_ex_i2c(pval, *out, &utype, it);
+        if (ndef)
+            ASN1_put_eoc(out);
+        else
+            *out += len;
+    }
 
-	if (usetag)
-		return ASN1_object_size(ndef, len, tag);
-	return len;
-	}
+    if (usetag)
+        return ASN1_object_size(ndef, len, tag);
+    return len;
+}
 
 /* Produce content octets from a structure */
 
 int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
-				const ASN1_ITEM *it)
-	{
-	ASN1_BOOLEAN *tbool = NULL;
-	ASN1_STRING *strtmp;
-	ASN1_OBJECT *otmp;
-	int utype;
-	const unsigned char *cont;
-	unsigned char c;
-	int len;
-	const ASN1_PRIMITIVE_FUNCS *pf;
-	pf = it->funcs;
-	if (pf && pf->prim_i2c)
-		return pf->prim_i2c(pval, cout, putype, it);
+                const ASN1_ITEM *it)
+{
+    ASN1_BOOLEAN *tbool = NULL;
+    ASN1_STRING *strtmp;
+    ASN1_OBJECT *otmp;
+    int utype;
+    const unsigned char *cont;
+    unsigned char c;
+    int len;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (pf && pf->prim_i2c)
+        return pf->prim_i2c(pval, cout, putype, it);
 
-	/* Should type be omitted? */
-	if ((it->itype != ASN1_ITYPE_PRIMITIVE)
-		|| (it->utype != V_ASN1_BOOLEAN))
-		{
-		if (!*pval) return -1;
-		}
+    /* Should type be omitted? */
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+        || (it->utype != V_ASN1_BOOLEAN)) {
+        if (!*pval)
+            return -1;
+    }
 
-	if (it->itype == ASN1_ITYPE_MSTRING)
-		{
-		/* If MSTRING type set the underlying type */
-		strtmp = (ASN1_STRING *)*pval;
-		utype = strtmp->type;
-		*putype = utype;
-		}
-	else if (it->utype == V_ASN1_ANY)
-		{
-		/* If ANY set type and pointer to value */
-		ASN1_TYPE *typ;
-		typ = (ASN1_TYPE *)*pval;
-		utype = typ->type;
-		*putype = utype;
-		pval = &typ->value.asn1_value;
-		}
-	else utype = *putype;
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        /* If MSTRING type set the underlying type */
+        strtmp = (ASN1_STRING *)*pval;
+        utype = strtmp->type;
+        *putype = utype;
+    } else if (it->utype == V_ASN1_ANY) {
+        /* If ANY set type and pointer to value */
+        ASN1_TYPE *typ;
+        typ = (ASN1_TYPE *)*pval;
+        utype = typ->type;
+        *putype = utype;
+        pval = &typ->value.asn1_value;
+    } else
+        utype = *putype;
 
-	switch(utype)
-		{
-		case V_ASN1_OBJECT:
-		otmp = (ASN1_OBJECT *)*pval;
-		cont = otmp->data;
-		len = otmp->length;
-		break;
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        otmp = (ASN1_OBJECT *)*pval;
+        cont = otmp->data;
+        len = otmp->length;
+        break;
 
-		case V_ASN1_NULL:
-		cont = NULL;
-		len = 0;
-		break;
+    case V_ASN1_NULL:
+        cont = NULL;
+        len = 0;
+        break;
 
-		case V_ASN1_BOOLEAN:
-		tbool = (ASN1_BOOLEAN *)pval;
-		if (*tbool == -1)
-			return -1;
-		if (it->utype != V_ASN1_ANY)
-			{
-			/* Default handling if value == size field then omit */
-			if (*tbool && (it->size > 0))
-				return -1;
-			if (!*tbool && !it->size)
-				return -1;
-			}
-		c = (unsigned char)*tbool;
-		cont = &c;
-		len = 1;
-		break;
+    case V_ASN1_BOOLEAN:
+        tbool = (ASN1_BOOLEAN *)pval;
+        if (*tbool == -1)
+            return -1;
+        if (it->utype != V_ASN1_ANY) {
+            /*
+             * Default handling if value == size field then omit
+             */
+            if (*tbool && (it->size > 0))
+                return -1;
+            if (!*tbool && !it->size)
+                return -1;
+        }
+        c = (unsigned char)*tbool;
+        cont = &c;
+        len = 1;
+        break;
 
-		case V_ASN1_BIT_STRING:
-		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
-							cout ? &cout : NULL);
-		break;
+    case V_ASN1_BIT_STRING:
+        return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+                                   cout ? &cout : NULL);
+        break;
 
-		case V_ASN1_INTEGER:
-		case V_ASN1_NEG_INTEGER:
-		case V_ASN1_ENUMERATED:
-		case V_ASN1_NEG_ENUMERATED:
-		/* These are all have the same content format
-		 * as ASN1_INTEGER
-		 */
-		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
-							cout ? &cout : NULL);
-		break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_NEG_INTEGER:
+    case V_ASN1_ENUMERATED:
+    case V_ASN1_NEG_ENUMERATED:
+        /*
+         * These are all have the same content format as ASN1_INTEGER
+         */
+        return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
+        break;
 
-		case V_ASN1_OCTET_STRING:
-		case V_ASN1_NUMERICSTRING:
-		case V_ASN1_PRINTABLESTRING:
-		case V_ASN1_T61STRING:
-		case V_ASN1_VIDEOTEXSTRING:
-		case V_ASN1_IA5STRING:
-		case V_ASN1_UTCTIME:
-		case V_ASN1_GENERALIZEDTIME:
-		case V_ASN1_GRAPHICSTRING:
-		case V_ASN1_VISIBLESTRING:
-		case V_ASN1_GENERALSTRING:
-		case V_ASN1_UNIVERSALSTRING:
-		case V_ASN1_BMPSTRING:
-		case V_ASN1_UTF8STRING:
-		case V_ASN1_SEQUENCE:
-		case V_ASN1_SET:
-		default:
-		/* All based on ASN1_STRING and handled the same */
-		strtmp = (ASN1_STRING *)*pval;
-		/* Special handling for NDEF */
-		if ((it->size == ASN1_TFLG_NDEF)
-			&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
-			{
-			if (cout)
-				{
-				strtmp->data = cout;
-				strtmp->length = 0;
-				}
-			/* Special return code */
-			return -2;
-			}
-		cont = strtmp->data;
-		len = strtmp->length;
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    default:
+        /* All based on ASN1_STRING and handled the same */
+        strtmp = (ASN1_STRING *)*pval;
+        /* Special handling for NDEF */
+        if ((it->size == ASN1_TFLG_NDEF)
+            && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+            if (cout) {
+                strtmp->data = cout;
+                strtmp->length = 0;
+            }
+            /* Special return code */
+            return -2;
+        }
+        cont = strtmp->data;
+        len = strtmp->length;
 
-		break;
+        break;
 
-		}
-	if (cout && len)
-		memcpy(cout, cont, len);
-	return len;
-	}
+    }
+    if (cout && len)
+        memcpy(cout, cont, len);
+    return len;
+}
diff --git a/src/crypto/asn1/tasn_fre.c b/src/crypto/asn1/tasn_fre.c
index d1317ae..609cb9f 100644
--- a/src/crypto/asn1/tasn_fre.c
+++ b/src/crypto/asn1/tasn_fre.c
@@ -59,206 +59,188 @@
 #include <openssl/asn1t.h>
 #include <openssl/mem.h>
 
-
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                   int combine);
 
 /* Free up an ASN1 structure */
 
 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
-	{
-	asn1_item_combine_free(&val, it, 0);
-	}
+{
+    asn1_item_combine_free(&val, it, 0);
+}
 
 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	asn1_item_combine_free(pval, it, 0);
-	}
+{
+    asn1_item_combine_free(pval, it, 0);
+}
 
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
-	{
-	const ASN1_TEMPLATE *tt = NULL, *seqtt;
-	const ASN1_EXTERN_FUNCS *ef;
-	const ASN1_COMPAT_FUNCS *cf;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_aux_cb *asn1_cb;
-	int i;
-	if (!pval)
-		return;
-	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
-		return;
-	if (aux && aux->asn1_cb)
-		asn1_cb = aux->asn1_cb;
-	else
-		asn1_cb = 0;
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                   int combine)
+{
+    const ASN1_TEMPLATE *tt = NULL, *seqtt;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_COMPAT_FUNCS *cf;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    int i;
+    if (!pval)
+        return;
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
 
-	switch(it->itype)
-		{
+    switch (it->itype) {
 
-		case ASN1_ITYPE_PRIMITIVE:
-		if (it->templates)
-			ASN1_template_free(pval, it->templates);
-		else
-			ASN1_primitive_free(pval, it);
-		break;
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            ASN1_template_free(pval, it->templates);
+        else
+            ASN1_primitive_free(pval, it);
+        break;
 
-		case ASN1_ITYPE_MSTRING:
-		ASN1_primitive_free(pval, it);
-		break;
+    case ASN1_ITYPE_MSTRING:
+        ASN1_primitive_free(pval, it);
+        break;
 
-		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
-			if (i == 2)
-				return;
-			}
-		i = asn1_get_choice_selector(pval, it);
-		if ((i >= 0) && (i < it->tcount))
-			{
-			ASN1_VALUE **pchval;
-			tt = it->templates + i;
-			pchval = asn1_get_field_ptr(pval, tt);
-			ASN1_template_free(pchval, tt);
-			}
-		if (asn1_cb)
-			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
-		if (!combine)
-			{
-			OPENSSL_free(*pval);
-			*pval = NULL;
-			}
-		break;
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+            tt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, tt);
+            ASN1_template_free(pchval, tt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (!combine) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
 
-		case ASN1_ITYPE_COMPAT:
-		cf = it->funcs;
-		if (cf && cf->asn1_free)
-			cf->asn1_free(*pval);
-		break;
+    case ASN1_ITYPE_COMPAT:
+        cf = it->funcs;
+        if (cf && cf->asn1_free)
+            cf->asn1_free(*pval);
+        break;
 
-		case ASN1_ITYPE_EXTERN:
-		ef = it->funcs;
-		if (ef && ef->asn1_ex_free)
-			ef->asn1_ex_free(pval, it);
-		break;
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_free)
+            ef->asn1_ex_free(pval, it);
+        break;
 
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		case ASN1_ITYPE_SEQUENCE:
-		if (!asn1_refcount_dec_and_test_zero(pval, it))
-			return;
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
-			if (i == 2)
-				return;
-			}		
-		asn1_enc_free(pval, it);
-		/* If we free up as normal we will invalidate any
-		 * ANY DEFINED BY field and we wont be able to 
-		 * determine the type of the field it defines. So
-		 * free up in reverse order.
-		 */
-		tt = it->templates + it->tcount - 1;
-		for (i = 0; i < it->tcount; tt--, i++)
-			{
-			ASN1_VALUE **pseqval;
-			seqtt = asn1_do_adb(pval, tt, 0);
-			if (!seqtt)
-				continue;
-			pseqval = asn1_get_field_ptr(pval, seqtt);
-			ASN1_template_free(pseqval, seqtt);
-			}
-		if (asn1_cb)
-			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
-		if (!combine)
-			{
-			OPENSSL_free(*pval);
-			*pval = NULL;
-			}
-		break;
-		}
-	}
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (!asn1_refcount_dec_and_test_zero(pval, it))
+            return;
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        asn1_enc_free(pval, it);
+        /*
+         * If we free up as normal we will invalidate any ANY DEFINED BY
+         * field and we wont be able to determine the type of the field it
+         * defines. So free up in reverse order.
+         */
+        tt = it->templates + it->tcount - 1;
+        for (i = 0; i < it->tcount; tt--, i++) {
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 0);
+            if (!seqtt)
+                continue;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            ASN1_template_free(pseqval, seqtt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (!combine) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
+    }
+}
 
 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-	{
-	size_t i;
-	if (tt->flags & ASN1_TFLG_SK_MASK)
-		{
-		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
-		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
-			{
-			ASN1_VALUE *vtmp;
-			vtmp = sk_ASN1_VALUE_value(sk, i);
-			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
-									0);
-			}
-		sk_ASN1_VALUE_free(sk);
-		*pval = NULL;
-		}
-	else
-		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
-						tt->flags & ASN1_TFLG_COMBINE);
-	}
+{
+    size_t i;
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            ASN1_VALUE *vtmp;
+            vtmp = sk_ASN1_VALUE_value(sk, i);
+            asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
+        }
+        sk_ASN1_VALUE_free(sk);
+        *pval = NULL;
+    } else
+        asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
+                               tt->flags & ASN1_TFLG_COMBINE);
+}
 
 void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	int utype;
-	if (it)
-		{
-		const ASN1_PRIMITIVE_FUNCS *pf;
-		pf = it->funcs;
-		if (pf && pf->prim_free)
-			{
-			pf->prim_free(pval, it);
-			return;
-			}
-		}
-	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
-	if (!it)
-		{
-		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
-		utype = typ->type;
-		pval = &typ->value.asn1_value;
-		if (!*pval)
-			return;
-		}
-	else if (it->itype == ASN1_ITYPE_MSTRING)
-		{
-		utype = -1;
-		if (!*pval)
-			return;
-		}
-	else
-		{
-		utype = it->utype;
-		if ((utype != V_ASN1_BOOLEAN) && !*pval)
-			return;
-		}
+{
+    int utype;
+    if (it) {
+        const ASN1_PRIMITIVE_FUNCS *pf;
+        pf = it->funcs;
+        if (pf && pf->prim_free) {
+            pf->prim_free(pval, it);
+            return;
+        }
+    }
+    /* Special case: if 'it' is NULL free contents of ASN1_TYPE */
+    if (!it) {
+        ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+        utype = typ->type;
+        pval = &typ->value.asn1_value;
+        if (!*pval)
+            return;
+    } else if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = -1;
+        if (!*pval)
+            return;
+    } else {
+        utype = it->utype;
+        if ((utype != V_ASN1_BOOLEAN) && !*pval)
+            return;
+    }
 
-	switch(utype)
-		{
-		case V_ASN1_OBJECT:
-		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
-		break;
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+        break;
 
-		case V_ASN1_BOOLEAN:
-		if (it)
-			*(ASN1_BOOLEAN *)pval = it->size;
-		else
-			*(ASN1_BOOLEAN *)pval = -1;
-		return;
+    case V_ASN1_BOOLEAN:
+        if (it)
+            *(ASN1_BOOLEAN *)pval = it->size;
+        else
+            *(ASN1_BOOLEAN *)pval = -1;
+        return;
 
-		case V_ASN1_NULL:
-		break;
+    case V_ASN1_NULL:
+        break;
 
-		case V_ASN1_ANY:
-		ASN1_primitive_free(pval, NULL);
-		OPENSSL_free(*pval);
-		break;
+    case V_ASN1_ANY:
+        ASN1_primitive_free(pval, NULL);
+        OPENSSL_free(*pval);
+        break;
 
-		default:
-		ASN1_STRING_free((ASN1_STRING *)*pval);
-		*pval = NULL;
-		break;
-		}
-	*pval = NULL;
-	}
+    default:
+        ASN1_STRING_free((ASN1_STRING *)*pval);
+        *pval = NULL;
+        break;
+    }
+    *pval = NULL;
+}
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index c68fe06..232fe46 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -63,336 +63,319 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
-
 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-								int combine);
+                                    int combine);
 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
-	{
-	ASN1_VALUE *ret = NULL;
-	if (ASN1_item_ex_new(&ret, it) > 0)
-		return ret;
-	return NULL;
-	}
+{
+    ASN1_VALUE *ret = NULL;
+    if (ASN1_item_ex_new(&ret, it) > 0)
+        return ret;
+    return NULL;
+}
 
 /* Allocate an ASN1 structure */
 
 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	return asn1_item_ex_combine_new(pval, it, 0);
-	}
+{
+    return asn1_item_ex_combine_new(pval, it, 0);
+}
 
 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-								int combine)
-	{
-	const ASN1_TEMPLATE *tt = NULL;
-	const ASN1_COMPAT_FUNCS *cf;
-	const ASN1_EXTERN_FUNCS *ef;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_aux_cb *asn1_cb;
-	ASN1_VALUE **pseqval;
-	int i;
-	if (aux && aux->asn1_cb)
-		asn1_cb = aux->asn1_cb;
-	else
-		asn1_cb = 0;
+                                    int combine)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    const ASN1_COMPAT_FUNCS *cf;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_VALUE **pseqval;
+    int i;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
 
 #ifdef CRYPTO_MDEBUG
-	if (it->sname)
-		CRYPTO_push_info(it->sname);
+    if (it->sname)
+        CRYPTO_push_info(it->sname);
 #endif
 
-	switch(it->itype)
-		{
+    switch (it->itype) {
 
-		case ASN1_ITYPE_EXTERN:
-		ef = it->funcs;
-		if (ef && ef->asn1_ex_new)
-			{
-			if (!ef->asn1_ex_new(pval, it))
-				goto memerr;
-			}
-		break;
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_new) {
+            if (!ef->asn1_ex_new(pval, it))
+                goto memerr;
+        }
+        break;
 
-		case ASN1_ITYPE_COMPAT:
-		cf = it->funcs;
-		if (cf && cf->asn1_new) {
-			*pval = cf->asn1_new();
-			if (!*pval)
-				goto memerr;
-		}
-		break;
+    case ASN1_ITYPE_COMPAT:
+        cf = it->funcs;
+        if (cf && cf->asn1_new) {
+            *pval = cf->asn1_new();
+            if (!*pval)
+                goto memerr;
+        }
+        break;
 
-		case ASN1_ITYPE_PRIMITIVE:
-		if (it->templates)
-			{
-			if (!ASN1_template_new(pval, it->templates))
-				goto memerr;
-			}
-		else if (!ASN1_primitive_new(pval, it))
-				goto memerr;
-		break;
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!ASN1_template_new(pval, it->templates))
+                goto memerr;
+        } else if (!ASN1_primitive_new(pval, it))
+            goto memerr;
+        break;
 
-		case ASN1_ITYPE_MSTRING:
-		if (!ASN1_primitive_new(pval, it))
-				goto memerr;
-		break;
+    case ASN1_ITYPE_MSTRING:
+        if (!ASN1_primitive_new(pval, it))
+            goto memerr;
+        break;
 
-		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
-			if (!i)
-				goto auxerr;
-			if (i==2)
-				{
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
 #ifdef CRYPTO_MDEBUG
-				if (it->sname)
-					CRYPTO_pop_info();
+                if (it->sname)
+                    CRYPTO_pop_info();
 #endif
-				return 1;
-				}
-			}
-		if (!combine)
-			{
-			*pval = OPENSSL_malloc(it->size);
-			if (!*pval)
-				goto memerr;
-			memset(*pval, 0, it->size);
-			}
-		asn1_set_choice_selector(pval, -1, it);
-		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
-				goto auxerr;
-		break;
+                return 1;
+            }
+        }
+        if (!combine) {
+            *pval = OPENSSL_malloc(it->size);
+            if (!*pval)
+                goto memerr;
+            memset(*pval, 0, it->size);
+        }
+        asn1_set_choice_selector(pval, -1, it);
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr;
+        break;
 
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		case ASN1_ITYPE_SEQUENCE:
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
-			if (!i)
-				goto auxerr;
-			if (i==2)
-				{
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
 #ifdef CRYPTO_MDEBUG
-				if (it->sname)
-					CRYPTO_pop_info();
+                if (it->sname)
+                    CRYPTO_pop_info();
 #endif
-				return 1;
-				}
-			}
-		if (!combine)
-			{
-			*pval = OPENSSL_malloc(it->size);
-			if (!*pval)
-				goto memerr;
-			memset(*pval, 0, it->size);
-			asn1_refcount_set_one(pval, it);
-			asn1_enc_init(pval, it);
-			}
-		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
-			{
-			pseqval = asn1_get_field_ptr(pval, tt);
-			if (!ASN1_template_new(pseqval, tt))
-				goto memerr;
-			}
-		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
-				goto auxerr;
-		break;
-	}
+                return 1;
+            }
+        }
+        if (!combine) {
+            *pval = OPENSSL_malloc(it->size);
+            if (!*pval)
+                goto memerr;
+            memset(*pval, 0, it->size);
+            asn1_refcount_set_one(pval, it);
+            asn1_enc_init(pval, it);
+        }
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            pseqval = asn1_get_field_ptr(pval, tt);
+            if (!ASN1_template_new(pseqval, tt))
+                goto memerr;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr;
+        break;
+    }
 #ifdef CRYPTO_MDEBUG
-	if (it->sname) CRYPTO_pop_info();
+    if (it->sname)
+        CRYPTO_pop_info();
 #endif
-	return 1;
+    return 1;
 
-	memerr:
-	OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-	ASN1_item_ex_free(pval, it);
+ memerr:
+    OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+    ASN1_item_ex_free(pval, it);
 #ifdef CRYPTO_MDEBUG
-	if (it->sname) CRYPTO_pop_info();
+    if (it->sname)
+        CRYPTO_pop_info();
 #endif
-	return 0;
+    return 0;
 
-	auxerr:
-	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
-	ASN1_item_ex_free(pval, it);
+ auxerr:
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
+    ASN1_item_ex_free(pval, it);
 #ifdef CRYPTO_MDEBUG
-	if (it->sname) CRYPTO_pop_info();
+    if (it->sname)
+        CRYPTO_pop_info();
 #endif
-	return 0;
+    return 0;
 
-	}
+}
 
 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	const ASN1_EXTERN_FUNCS *ef;
+{
+    const ASN1_EXTERN_FUNCS *ef;
 
-	switch(it->itype)
-		{
+    switch (it->itype) {
 
-		case ASN1_ITYPE_EXTERN:
-		ef = it->funcs;
-		if (ef && ef->asn1_ex_clear) 
-			ef->asn1_ex_clear(pval, it);
-		else *pval = NULL;
-		break;
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_clear)
+            ef->asn1_ex_clear(pval, it);
+        else
+            *pval = NULL;
+        break;
 
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            asn1_template_clear(pval, it->templates);
+        else
+            asn1_primitive_clear(pval, it);
+        break;
 
-		case ASN1_ITYPE_PRIMITIVE:
-		if (it->templates) 
-			asn1_template_clear(pval, it->templates);
-		else
-			asn1_primitive_clear(pval, it);
-		break;
+    case ASN1_ITYPE_MSTRING:
+        asn1_primitive_clear(pval, it);
+        break;
 
-		case ASN1_ITYPE_MSTRING:
-		asn1_primitive_clear(pval, it);
-		break;
-
-		case ASN1_ITYPE_COMPAT:
-		case ASN1_ITYPE_CHOICE:
-		case ASN1_ITYPE_SEQUENCE:
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		*pval = NULL;
-		break;
-		}
-	}
-
+    case ASN1_ITYPE_COMPAT:
+    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        *pval = NULL;
+        break;
+    }
+}
 
 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-	{
-	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
-	int ret;
-	if (tt->flags & ASN1_TFLG_OPTIONAL)
-		{
-		asn1_template_clear(pval, tt);
-		return 1;
-		}
-	/* If ANY DEFINED BY nothing to do */
+{
+    const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+    int ret;
+    if (tt->flags & ASN1_TFLG_OPTIONAL) {
+        asn1_template_clear(pval, tt);
+        return 1;
+    }
+    /* If ANY DEFINED BY nothing to do */
 
-	if (tt->flags & ASN1_TFLG_ADB_MASK)
-		{
-		*pval = NULL;
-		return 1;
-		}
+    if (tt->flags & ASN1_TFLG_ADB_MASK) {
+        *pval = NULL;
+        return 1;
+    }
 #ifdef CRYPTO_MDEBUG
-	if (tt->field_name)
-		CRYPTO_push_info(tt->field_name);
+    if (tt->field_name)
+        CRYPTO_push_info(tt->field_name);
 #endif
-	/* If SET OF or SEQUENCE OF, its a STACK */
-	if (tt->flags & ASN1_TFLG_SK_MASK)
-		{
-		STACK_OF(ASN1_VALUE) *skval;
-		skval = sk_ASN1_VALUE_new_null();
-		if (!skval)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			ret = 0;
-			goto done;
-			}
-		*pval = (ASN1_VALUE *)skval;
-		ret = 1;
-		goto done;
-		}
-	/* Otherwise pass it back to the item routine */
-	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
-	done:
+    /* If SET OF or SEQUENCE OF, its a STACK */
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *skval;
+        skval = sk_ASN1_VALUE_new_null();
+        if (!skval) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+            goto done;
+        }
+        *pval = (ASN1_VALUE *)skval;
+        ret = 1;
+        goto done;
+    }
+    /* Otherwise pass it back to the item routine */
+    ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
+ done:
 #ifdef CRYPTO_MDEBUG
-	if (it->sname)
-		CRYPTO_pop_info();
+    if (it->sname)
+        CRYPTO_pop_info();
 #endif
-	return ret;
-	}
+    return ret;
+}
 
 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-	{
-	/* If ADB or STACK just NULL the field */
-	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 
-		*pval = NULL;
-	else
-		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
-	}
+{
+    /* If ADB or STACK just NULL the field */
+    if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
+        *pval = NULL;
+    else
+        asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
 
-
-/* NB: could probably combine most of the real XXX_new() behaviour and junk
+/*
+ * NB: could probably combine most of the real XXX_new() behaviour and junk
  * all the old functions.
  */
 
 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	ASN1_TYPE *typ;
-	ASN1_STRING *str;
-	int utype;
+{
+    ASN1_TYPE *typ;
+    ASN1_STRING *str;
+    int utype;
 
-	if (!it)
-		return 0;
+    if (!it)
+        return 0;
 
-	if (it->funcs)
-		{
-		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
-		if (pf->prim_new)
-			return pf->prim_new(pval, it);
-		}
+    if (it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (pf->prim_new)
+            return pf->prim_new(pval, it);
+    }
 
-	if (it->itype == ASN1_ITYPE_MSTRING)
-		utype = -1;
-	else
-		utype = it->utype;
-	switch(utype)
-		{
-		case V_ASN1_OBJECT:
-		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
-		return 1;
+    if (it->itype == ASN1_ITYPE_MSTRING)
+        utype = -1;
+    else
+        utype = it->utype;
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+        return 1;
 
-		case V_ASN1_BOOLEAN:
-		*(ASN1_BOOLEAN *)pval = it->size;
-		return 1;
+    case V_ASN1_BOOLEAN:
+        *(ASN1_BOOLEAN *)pval = it->size;
+        return 1;
 
-		case V_ASN1_NULL:
-		*pval = (ASN1_VALUE *)1;
-		return 1;
+    case V_ASN1_NULL:
+        *pval = (ASN1_VALUE *)1;
+        return 1;
 
-		case V_ASN1_ANY:
-		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
-		if (!typ)
-			return 0;
-		typ->value.ptr = NULL;
-		typ->type = -1;
-		*pval = (ASN1_VALUE *)typ;
-		break;
+    case V_ASN1_ANY:
+        typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
+        if (!typ)
+            return 0;
+        typ->value.ptr = NULL;
+        typ->type = -1;
+        *pval = (ASN1_VALUE *)typ;
+        break;
 
-		default:
-		str = ASN1_STRING_type_new(utype);
-		if (it->itype == ASN1_ITYPE_MSTRING && str)
-			str->flags |= ASN1_STRING_FLAG_MSTRING;
-		*pval = (ASN1_VALUE *)str;
-		break;
-		}
-	if (*pval)
-		return 1;
-	return 0;
-	}
+    default:
+        str = ASN1_STRING_type_new(utype);
+        if (it->itype == ASN1_ITYPE_MSTRING && str)
+            str->flags |= ASN1_STRING_FLAG_MSTRING;
+        *pval = (ASN1_VALUE *)str;
+        break;
+    }
+    if (*pval)
+        return 1;
+    return 0;
+}
 
 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
-	{
-	int utype;
-	if (it && it->funcs)
-		{
-		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
-		if (pf->prim_clear)
-			pf->prim_clear(pval, it);
-		else 
-			*pval = NULL;
-		return;
-		}
-	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
-		utype = -1;
-	else
-		utype = it->utype;
-	if (utype == V_ASN1_BOOLEAN)
-		*(ASN1_BOOLEAN *)pval = it->size;
-	else *pval = NULL;
-	}
+{
+    int utype;
+    if (it && it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (pf->prim_clear)
+            pf->prim_clear(pval, it);
+        else
+            *pval = NULL;
+        return;
+    }
+    if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+        utype = -1;
+    else
+        utype = it->utype;
+    if (utype == V_ASN1_BOOLEAN)
+        *(ASN1_BOOLEAN *)pval = it->size;
+    else
+        *pval = NULL;
+}
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index a574055..dd20cb4 100644
--- a/src/crypto/asn1/tasn_prn.c
+++ b/src/crypto/asn1/tasn_prn.c
@@ -65,578 +65,532 @@
 
 #include "asn1_locl.h"
 
-
-
-/* Print routines.
+/*
+ * Print routines.
  */
 
 /* ASN1_PCTX routines */
 
-static ASN1_PCTX default_pctx = 
-	{
-	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
-	0,	/* nm_flags */
-	0,	/* cert_flags */
-	0,	/* oid_flags */
-	0	/* str_flags */
-	};
-	
+static ASN1_PCTX default_pctx = {
+    ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
+    0,                          /* nm_flags */
+    0,                          /* cert_flags */
+    0,                          /* oid_flags */
+    0                           /* str_flags */
+};
 
 ASN1_PCTX *ASN1_PCTX_new(void)
-	{
-	ASN1_PCTX *ret;
-	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return NULL;
-		}
-	ret->flags = 0;
-	ret->nm_flags = 0;
-	ret->cert_flags = 0;
-	ret->oid_flags = 0;
-	ret->str_flags = 0;
-	return ret;
-	}
+{
+    ASN1_PCTX *ret;
+    ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->flags = 0;
+    ret->nm_flags = 0;
+    ret->cert_flags = 0;
+    ret->oid_flags = 0;
+    ret->str_flags = 0;
+    return ret;
+}
 
 void ASN1_PCTX_free(ASN1_PCTX *p)
-	{
-	OPENSSL_free(p);
-	}
+{
+    OPENSSL_free(p);
+}
 
 unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
-	{
-	return p->flags;
-	}
+{
+    return p->flags;
+}
 
 void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
-	{
-	p->flags = flags;
-	}
+{
+    p->flags = flags;
+}
 
 unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
-	{
-	return p->nm_flags;
-	}
+{
+    return p->nm_flags;
+}
 
 void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
-	{
-	p->nm_flags = flags;
-	}
+{
+    p->nm_flags = flags;
+}
 
 unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
-	{
-	return p->cert_flags;
-	}
+{
+    return p->cert_flags;
+}
 
 void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
-	{
-	p->cert_flags = flags;
-	}
+{
+    p->cert_flags = flags;
+}
 
 unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
-	{
-	return p->oid_flags;
-	}
+{
+    return p->oid_flags;
+}
 
 void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
-	{
-	p->oid_flags = flags;
-	}
+{
+    p->oid_flags = flags;
+}
 
 unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
-	{
-	return p->str_flags;
-	}
+{
+    return p->str_flags;
+}
 
 void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
-	{
-	p->str_flags = flags;
-	}
+{
+    p->str_flags = flags;
+}
 
 /* Main print routines */
 
 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-				const ASN1_ITEM *it,
-				const char *fname, const char *sname,
-				int nohdr, const ASN1_PCTX *pctx);
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx);
 
 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
 
 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
-				const ASN1_ITEM *it, int indent,
-				const char *fname, const char *sname,
-				const ASN1_PCTX *pctx);
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx);
 
 static int asn1_print_fsname(BIO *out, int indent,
-			const char *fname, const char *sname,
-			const ASN1_PCTX *pctx);
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx);
 
 int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
-				const ASN1_ITEM *it, const ASN1_PCTX *pctx)
-	{
-	const char *sname;
-	if (pctx == NULL)
-		pctx = &default_pctx;
-	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
-		sname = NULL;
-	else
-		sname = it->sname;
-	return asn1_item_print_ctx(out, &ifld, indent, it,
-							NULL, sname, 0, pctx);
-	}
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+{
+    const char *sname;
+    if (pctx == NULL)
+        pctx = &default_pctx;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    else
+        sname = it->sname;
+    return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
+}
 
 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-				const ASN1_ITEM *it,
-				const char *fname, const char *sname,
-				int nohdr, const ASN1_PCTX *pctx)
-	{
-	const ASN1_TEMPLATE *tt;
-	const ASN1_EXTERN_FUNCS *ef;
-	ASN1_VALUE **tmpfld;
-	const ASN1_AUX *aux = it->funcs;
-	ASN1_aux_cb *asn1_cb;
-	ASN1_PRINT_ARG parg;
-	int i;
-	if (aux && aux->asn1_cb)
-		{
-		parg.out = out;
-		parg.indent = indent;
-		parg.pctx = pctx;
-		asn1_cb = aux->asn1_cb;
-		}
-	else asn1_cb = 0;
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx)
+{
+    const ASN1_TEMPLATE *tt;
+    const ASN1_EXTERN_FUNCS *ef;
+    ASN1_VALUE **tmpfld;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_PRINT_ARG parg;
+    int i;
+    if (aux && aux->asn1_cb) {
+        parg.out = out;
+        parg.indent = indent;
+        parg.pctx = pctx;
+        asn1_cb = aux->asn1_cb;
+    } else
+        asn1_cb = 0;
 
-	if(*fld == NULL)
-		{
-		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
-			{
-			if (!nohdr && !asn1_print_fsname(out, indent,
-							fname, sname, pctx))
-				return 0;
-			if (BIO_puts(out, "<ABSENT>\n") <= 0)
-				return 0;
-			}
-		return 1;
-		}
+    if (*fld == NULL) {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+            if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+                return 0;
+            if (BIO_puts(out, "<ABSENT>\n") <= 0)
+                return 0;
+        }
+        return 1;
+    }
 
-	switch(it->itype)
-		{
-		case ASN1_ITYPE_PRIMITIVE:
-		if(it->templates)
-			{
-			if (!asn1_template_print_ctx(out, fld, indent,
-							it->templates, pctx))
-				return 0;
-			break;
-			}
-		/* fall thru */
-		case ASN1_ITYPE_MSTRING:
-		if (!asn1_primitive_print(out, fld, it,
-				indent, fname, sname,pctx))
-			return 0;
-		break;
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!asn1_template_print_ctx(out, fld, indent,
+                                         it->templates, pctx))
+                return 0;
+            break;
+        }
+        /* fall thru */
+    case ASN1_ITYPE_MSTRING:
+        if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
+            return 0;
+        break;
 
-		case ASN1_ITYPE_EXTERN:
-		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-			return 0;
-		/* Use new style print routine if possible */
-		ef = it->funcs;
-		if (ef && ef->asn1_ex_print)
-			{
-			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
-			if (!i)
-				return 0;
-			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
-				return 0;
-			return 1;
-			}
-		else if (sname && 
-			BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
-			return 0;
-		break;
+    case ASN1_ITYPE_EXTERN:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        /* Use new style print routine if possible */
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_print) {
+            i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+            if (!i)
+                return 0;
+            if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+                return 0;
+            return 1;
+        } else if (sname &&
+                   BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+            return 0;
+        break;
 
-		case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_CHOICE:
 #if 0
-		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-			return 0;
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
 #endif
-		/* CHOICE type, get selector */
-		i = asn1_get_choice_selector(fld, it);
-		/* This should never happen... */
-		if((i < 0) || (i >= it->tcount))
-			{
-			if (BIO_printf(out,
-				"ERROR: selector [%d] invalid\n", i) <= 0)
-				return 0;
-			return 1;
-			}
-		tt = it->templates + i;
-		tmpfld = asn1_get_field_ptr(fld, tt);
-		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
-			return 0;
-		break;
+        /* CHOICE type, get selector */
+        i = asn1_get_choice_selector(fld, it);
+        /* This should never happen... */
+        if ((i < 0) || (i >= it->tcount)) {
+            if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
+                return 0;
+            return 1;
+        }
+        tt = it->templates + i;
+        tmpfld = asn1_get_field_ptr(fld, tt);
+        if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+            return 0;
+        break;
 
-		case ASN1_ITYPE_SEQUENCE:
-		case ASN1_ITYPE_NDEF_SEQUENCE:
-		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-			return 0;
-		if (fname || sname)
-			{
-			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
-				{
-				if (BIO_puts(out, " {\n") <= 0)
-					return 0;
-				}
-			else
-				{
-				if (BIO_puts(out, "\n") <= 0)
-					return 0;
-				}
-			}
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        if (fname || sname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+                if (BIO_puts(out, " {\n") <= 0)
+                    return 0;
+            } else {
+                if (BIO_puts(out, "\n") <= 0)
+                    return 0;
+            }
+        }
 
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
-			if (i == 0)
-				return 0;
-			if (i == 2)
-				return 1;
-			}
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+            if (i == 0)
+                return 0;
+            if (i == 2)
+                return 1;
+        }
 
-		/* Print each field entry */
-		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
-			{
-			const ASN1_TEMPLATE *seqtt;
-			seqtt = asn1_do_adb(fld, tt, 1);
-			if (!seqtt)
-				return 0;
-			tmpfld = asn1_get_field_ptr(fld, seqtt);
-			if (!asn1_template_print_ctx(out, tmpfld,
-						indent + 2, seqtt, pctx))
-				return 0;
-			}
-		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
-			{
-			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
-				return 0;
-			}
+        /* Print each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(fld, tt, 1);
+            if (!seqtt)
+                return 0;
+            tmpfld = asn1_get_field_ptr(fld, seqtt);
+            if (!asn1_template_print_ctx(out, tmpfld,
+                                         indent + 2, seqtt, pctx))
+                return 0;
+        }
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+                return 0;
+        }
 
-		if (asn1_cb)
-			{
-			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
-			if (i == 0)
-				return 0;
-			}
-		break;
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+            if (i == 0)
+                return 0;
+        }
+        break;
 
-		default:
-		BIO_printf(out, "Unprocessed type %d\n", it->itype);
-		return 0;
-		}
+    default:
+        BIO_printf(out, "Unprocessed type %d\n", it->itype);
+        return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
-	{
-	int flags;
-	size_t i;
-	const char *sname, *fname;
-	flags = tt->flags;
-	if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
-		sname = ASN1_ITEM_ptr(tt->item)->sname;
-	else
-		sname = NULL;
-	if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
-		fname = NULL;
-	else
-		fname = tt->field_name;
-	if(flags & ASN1_TFLG_SK_MASK)
-		{
-		const char *tname;
-		ASN1_VALUE *skitem;
-		STACK_OF(ASN1_VALUE) *stack;
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+    int flags;
+    size_t i;
+    const char *sname, *fname;
+    flags = tt->flags;
+    if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+        sname = ASN1_ITEM_ptr(tt->item)->sname;
+    else
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    else
+        fname = tt->field_name;
+    if (flags & ASN1_TFLG_SK_MASK) {
+        const char *tname;
+        ASN1_VALUE *skitem;
+        STACK_OF(ASN1_VALUE) *stack;
 
-		/* SET OF, SEQUENCE OF */
-		if (fname)
-			{
-			if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
-				{
-				if(flags & ASN1_TFLG_SET_OF)
-					tname = "SET";
-				else
-					tname = "SEQUENCE";
-				if (BIO_printf(out, "%*s%s OF %s {\n",
-					indent, "", tname, tt->field_name) <= 0)
-					return 0;
-				}
-			else if (BIO_printf(out, "%*s%s:\n", indent, "",
-					fname) <= 0)
-				return 0;
-			}
-		stack = (STACK_OF(ASN1_VALUE) *)*fld;
-		for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
-			{
-			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
-				return 0;
+        /* SET OF, SEQUENCE OF */
+        if (fname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+                if (flags & ASN1_TFLG_SET_OF)
+                    tname = "SET";
+                else
+                    tname = "SEQUENCE";
+                if (BIO_printf(out, "%*s%s OF %s {\n",
+                               indent, "", tname, tt->field_name) <= 0)
+                    return 0;
+            } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
+                return 0;
+        }
+        stack = (STACK_OF(ASN1_VALUE) *)*fld;
+        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+            if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+                return 0;
 
-			skitem = sk_ASN1_VALUE_value(stack, i);
-			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
-				ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
-				return 0;
-			}
-		if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
-				return 0;
-		if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
-			{
-			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
-				return 0;
-			}
-		return 1;
-		}
-	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
-							fname, sname, 0, pctx);
-	}
+            skitem = sk_ASN1_VALUE_value(stack, i);
+            if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+                                     ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
+                                     pctx))
+                return 0;
+        }
+        if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+            return 0;
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+                return 0;
+        }
+        return 1;
+    }
+    return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+                               fname, sname, 0, pctx);
+}
 
 static int asn1_print_fsname(BIO *out, int indent,
-			const char *fname, const char *sname,
-			const ASN1_PCTX *pctx)
-	{
-	static char spaces[] = "                    ";
-	const int nspaces = sizeof(spaces) - 1;
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx)
+{
+    static char spaces[] = "                    ";
+    const int nspaces = sizeof(spaces) - 1;
 
 #if 0
-	if (!sname && !fname)
-		return 1;
+    if (!sname && !fname)
+        return 1;
 #endif
 
-	while (indent > nspaces)
-		{
-		if (BIO_write(out, spaces, nspaces) != nspaces)
-			return 0;
-		indent -= nspaces;
-		}
-	if (BIO_write(out, spaces, indent) != indent)
-		return 0;
-	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
-		sname = NULL;
-	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
-		fname = NULL;
-	if (!sname && !fname)
-		return 1;
-	if (fname)
-		{
-		if (BIO_puts(out, fname) <= 0)
-			return 0;
-		}
-	if (sname)
-		{
-		if (fname)
-			{
-			if (BIO_printf(out, " (%s)", sname) <= 0)
-				return 0;
-			}
-		else
-			{
-			if (BIO_puts(out, sname) <= 0)
-				return 0;
-			}
-		}
-	if (BIO_write(out, ": ", 2) != 2)
-		return 0;
-	return 1;
-	}
+    while (indent > nspaces) {
+        if (BIO_write(out, spaces, nspaces) != nspaces)
+            return 0;
+        indent -= nspaces;
+    }
+    if (BIO_write(out, spaces, indent) != indent)
+        return 0;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    if (!sname && !fname)
+        return 1;
+    if (fname) {
+        if (BIO_puts(out, fname) <= 0)
+            return 0;
+    }
+    if (sname) {
+        if (fname) {
+            if (BIO_printf(out, " (%s)", sname) <= 0)
+                return 0;
+        } else {
+            if (BIO_puts(out, sname) <= 0)
+                return 0;
+        }
+    }
+    if (BIO_write(out, ": ", 2) != 2)
+        return 0;
+    return 1;
+}
 
 static int asn1_print_boolean_ctx(BIO *out, int boolval,
-							const ASN1_PCTX *pctx)
-	{
-	const char *str;
-	switch (boolval)
-		{
-		case -1:
-		str = "BOOL ABSENT";
-		break;
+                                  const ASN1_PCTX *pctx)
+{
+    const char *str;
+    switch (boolval) {
+    case -1:
+        str = "BOOL ABSENT";
+        break;
 
-		case 0:
-		str = "FALSE";
-		break;
+    case 0:
+        str = "FALSE";
+        break;
 
-		default:
-		str = "TRUE";
-		break;
+    default:
+        str = "TRUE";
+        break;
 
-		}
+    }
 
-	if (BIO_puts(out, str) <= 0)
-		return 0;
-	return 1;
+    if (BIO_puts(out, str) <= 0)
+        return 0;
+    return 1;
 
-	}
+}
 
 static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
-						const ASN1_PCTX *pctx)
-	{
-	BIGNUM *bn = NULL;
-	char *s = NULL;
-	int ret = 1;
+                                  const ASN1_PCTX *pctx)
+{
+    BIGNUM *bn = NULL;
+    char *s = NULL;
+    int ret = 1;
 
-	bn = ASN1_INTEGER_to_BN(str, NULL);
-	if (bn == NULL) {
-		return 0;
-	}
-	s = BN_bn2dec(bn);
-	BN_free(bn);
-	if (s == NULL) {
-		return 0;
-	}
+    bn = ASN1_INTEGER_to_BN(str, NULL);
+    if (bn == NULL) {
+        return 0;
+    }
+    s = BN_bn2dec(bn);
+    BN_free(bn);
+    if (s == NULL) {
+        return 0;
+    }
 
-	if (BIO_puts(out, s) <= 0) {
-		ret = 0;
-	}
-	OPENSSL_free(s);
-	return ret;
-	}
+    if (BIO_puts(out, s) <= 0) {
+        ret = 0;
+    }
+    OPENSSL_free(s);
+    return ret;
+}
 
 static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
-						const ASN1_PCTX *pctx)
-	{
-	char objbuf[80];
-	const char *ln;
-	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
-	if(!ln)
-		ln = "";
-	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
-	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
-		return 0;
-	return 1;
-	}
+                              const ASN1_PCTX *pctx)
+{
+    char objbuf[80];
+    const char *ln;
+    ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+    if (!ln)
+        ln = "";
+    OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+    if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+        return 0;
+    return 1;
+}
 
 static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
-						const ASN1_PCTX *pctx)
-	{
-	if (str->type == V_ASN1_BIT_STRING)
-		{
-		if (BIO_printf(out, " (%ld unused bits)\n",
-					str->flags & 0x7) <= 0)
-				return 0;
-		}
-	else if (BIO_puts(out, "\n") <= 0)
-		return 0;
-	if (str->length > 0 && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
-		return 0;
-	}
-	return 1;
-	}
+                                   const ASN1_PCTX *pctx)
+{
+    if (str->type == V_ASN1_BIT_STRING) {
+        if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
+            return 0;
+    } else if (BIO_puts(out, "\n") <= 0)
+        return 0;
+    if (str->length > 0
+        && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
+        return 0;
+    }
+    return 1;
+}
 
 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
-				const ASN1_ITEM *it, int indent,
-				const char *fname, const char *sname,
-				const ASN1_PCTX *pctx)
-	{
-	long utype;
-	ASN1_STRING *str;
-	int ret = 1, needlf = 1;
-	const char *pname;
-	const ASN1_PRIMITIVE_FUNCS *pf;
-	pf = it->funcs;
-	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
-			return 0;
-	if (pf && pf->prim_print)
-		return pf->prim_print(out, fld, it, indent, pctx);
-	str = (ASN1_STRING *)*fld;
-	if (it->itype == ASN1_ITYPE_MSTRING)
-		utype = str->type & ~V_ASN1_NEG;
-	else
-		utype = it->utype;
-	if (utype == V_ASN1_ANY)
-		{
-		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
-		utype = atype->type;
-		fld = &atype->value.asn1_value;
-		str = (ASN1_STRING *)*fld;
-		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
-			pname = NULL;
-		else 
-			pname = ASN1_tag2str(utype);
-		}
-	else
-		{
-		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
-			pname = ASN1_tag2str(utype);
-		else 
-			pname = NULL;
-		}
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx)
+{
+    long utype;
+    ASN1_STRING *str;
+    int ret = 1, needlf = 1;
+    const char *pname;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+        return 0;
+    if (pf && pf->prim_print)
+        return pf->prim_print(out, fld, it, indent, pctx);
+    str = (ASN1_STRING *)*fld;
+    if (it->itype == ASN1_ITYPE_MSTRING)
+        utype = str->type & ~V_ASN1_NEG;
+    else
+        utype = it->utype;
+    if (utype == V_ASN1_ANY) {
+        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+        utype = atype->type;
+        fld = &atype->value.asn1_value;
+        str = (ASN1_STRING *)*fld;
+        if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+            pname = NULL;
+        else
+            pname = ASN1_tag2str(utype);
+    } else {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+            pname = ASN1_tag2str(utype);
+        else
+            pname = NULL;
+    }
 
-	if (utype == V_ASN1_NULL)
-		{
-		if (BIO_puts(out, "NULL\n") <= 0)
-			return 0;
-		return 1;
-		}
+    if (utype == V_ASN1_NULL) {
+        if (BIO_puts(out, "NULL\n") <= 0)
+            return 0;
+        return 1;
+    }
 
-	if (pname)
-		{
-		if (BIO_puts(out, pname) <= 0)
-			return 0;
-		if (BIO_puts(out, ":") <= 0)
-			return 0;
-		}
+    if (pname) {
+        if (BIO_puts(out, pname) <= 0)
+            return 0;
+        if (BIO_puts(out, ":") <= 0)
+            return 0;
+    }
 
-	switch (utype)
-		{
-		case V_ASN1_BOOLEAN:
-			{
-			int boolval = *(int *)fld;
-			if (boolval == -1)
-				boolval = it->size;
-			ret = asn1_print_boolean_ctx(out, boolval, pctx);
-			}
-		break;
+    switch (utype) {
+    case V_ASN1_BOOLEAN:
+        {
+            int boolval = *(int *)fld;
+            if (boolval == -1)
+                boolval = it->size;
+            ret = asn1_print_boolean_ctx(out, boolval, pctx);
+        }
+        break;
 
-		case V_ASN1_INTEGER:
-		case V_ASN1_ENUMERATED:
-		ret = asn1_print_integer_ctx(out, str, pctx);
-		break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        ret = asn1_print_integer_ctx(out, str, pctx);
+        break;
 
-		case V_ASN1_UTCTIME:
-		ret = ASN1_UTCTIME_print(out, str);
-		break;
+    case V_ASN1_UTCTIME:
+        ret = ASN1_UTCTIME_print(out, str);
+        break;
 
-		case V_ASN1_GENERALIZEDTIME:
-		ret = ASN1_GENERALIZEDTIME_print(out, str);
-		break;
+    case V_ASN1_GENERALIZEDTIME:
+        ret = ASN1_GENERALIZEDTIME_print(out, str);
+        break;
 
-		case V_ASN1_OBJECT:
-		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
-		break;
+    case V_ASN1_OBJECT:
+        ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+        break;
 
-		case V_ASN1_OCTET_STRING:
-		case V_ASN1_BIT_STRING:
-		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
-		needlf = 0;
-		break;
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_BIT_STRING:
+        ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+        needlf = 0;
+        break;
 
-		case V_ASN1_SEQUENCE:
-		case V_ASN1_SET:
-		case V_ASN1_OTHER:
-		if (BIO_puts(out, "\n") <= 0)
-			return 0;
-		if (ASN1_parse_dump(out, str->data, str->length,
-						indent, 0) <= 0)
-			ret = 0;
-		needlf = 0;
-		break;
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_OTHER:
+        if (BIO_puts(out, "\n") <= 0)
+            return 0;
+        if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
+            ret = 0;
+        needlf = 0;
+        break;
 
-		default:
-		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+    default:
+        ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
 
-		}
-	if (!ret)
-		return 0;
-	if (needlf && BIO_puts(out, "\n") <= 0)
-		return 0;
-	return 1;
-	}
+    }
+    if (!ret)
+        return 0;
+    if (needlf && BIO_puts(out, "\n") <= 0)
+        return 0;
+    return 1;
+}
diff --git a/src/crypto/asn1/tasn_typ.c b/src/crypto/asn1/tasn_typ.c
index f004b0d..daf02ea 100644
--- a/src/crypto/asn1/tasn_typ.c
+++ b/src/crypto/asn1/tasn_typ.c
@@ -58,20 +58,19 @@
 
 #include <openssl/asn1t.h>
 
-
 /* Declarations for string types */
 
 #define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
-	IMPLEMENT_ASN1_TYPE(sname) \
-	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
-	sname *sname##_new(void) \
-	{ \
-		return ASN1_STRING_type_new(V_##sname); \
-	} \
-	void sname##_free(sname *x) \
-	{ \
-		ASN1_STRING_free(x); \
-	}
+        IMPLEMENT_ASN1_TYPE(sname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
+        sname *sname##_new(void) \
+        { \
+                return ASN1_STRING_type_new(V_##sname); \
+        } \
+        void sname##_free(sname *x) \
+        { \
+                ASN1_STRING_free(x); \
+        }
 
 IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
 IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
@@ -95,12 +94,16 @@
 
 IMPLEMENT_ASN1_TYPE(ASN1_ANY);
 
-/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */;
+/*
+ * Just swallow an ASN1_SEQUENCE in an ASN1_STRING
+ */ ;
 IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE);
 
 IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE);
 
-/* Multistring types */;
+/*
+ * Multistring types
+ */ ;
 
 IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE);
 IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE);
@@ -111,18 +114,23 @@
 IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING);
 IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING);
 
-/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */;
+/*
+ * Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE
+ */ ;
 IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1);
 IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1);
 IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0);
 
-/* Special, OCTET STRING with indefinite length constructed support */;
+/*
+ * Special, OCTET STRING with indefinite length constructed support
+ */ ;
 
 IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING,
-                       ASN1_TFLG_NDEF);
+ASN1_TFLG_NDEF);
 
-ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = ASN1_EX_TEMPLATE_TYPE(
-    ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY);
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
+    ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY,
+                          ASN1_ANY);
 ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY);
 
 ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0,
@@ -131,7 +139,6 @@
 ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY);
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY,
-                                            ASN1_SEQUENCE_ANY,
-                                            ASN1_SEQUENCE_ANY);
+ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY);
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY,
-                                            ASN1_SET_ANY);
+ASN1_SET_ANY);
diff --git a/src/crypto/asn1/x_bignum.c b/src/crypto/asn1/x_bignum.c
index 5867c4f..585d9d4 100644
--- a/src/crypto/asn1/x_bignum.c
+++ b/src/crypto/asn1/x_bignum.c
@@ -59,85 +59,95 @@
 #include <openssl/asn1t.h>
 #include <openssl/bn.h>
 
-
-/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
- * BIGNUM directly. Currently it ignores the sign which isn't a problem since all
- * BIGNUMs used are non negative and anything that looks negative is normally due
- * to an encoding error.
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
+ * since all BIGNUMs used are non negative and anything that looks negative
+ * is normally due to an encoding error.
  */
 
-#define BN_SENSITIVE	1
+#define BN_SENSITIVE    1
 
 static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
-static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                  int utype, char *free_cont, const ASN1_ITEM *it);
 
 static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
-	NULL, 0,
-	bn_new,
-	bn_free,
-	0,
-	bn_c2i,
-	bn_i2c,
-	NULL /* prim_print */,
+    NULL, 0,
+    bn_new,
+    bn_free,
+    0,
+    bn_c2i,
+    bn_i2c,
+    NULL /* prim_print */ ,
 };
 
 ASN1_ITEM_start(BIGNUM)
-	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
 ASN1_ITEM_end(BIGNUM)
 
 ASN1_ITEM_start(CBIGNUM)
-	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
 ASN1_ITEM_end(CBIGNUM)
 
 static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-	*pval = (ASN1_VALUE *)BN_new();
-	if(*pval) return 1;
-	else return 0;
+    *pval = (ASN1_VALUE *)BN_new();
+    if (*pval)
+        return 1;
+    else
+        return 0;
 }
 
 static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-	if(!*pval) return;
-	if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
-	else BN_free((BIGNUM *)*pval);
-	*pval = NULL;
+    if (!*pval)
+        return;
+    if (it->size & BN_SENSITIVE)
+        BN_clear_free((BIGNUM *)*pval);
+    else
+        BN_free((BIGNUM *)*pval);
+    *pval = NULL;
 }
 
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it)
 {
-	BIGNUM *bn;
-	int pad;
-	if(!*pval) return -1;
-	bn = (BIGNUM *)*pval;
-	/* If MSB set in an octet we need a padding byte */
-	if(BN_num_bits(bn) & 0x7) pad = 0;
-	else pad = 1;
-	if(cont) {
-		if(pad) *cont++ = 0;
-		BN_bn2bin(bn, cont);
-	}
-	return pad + BN_num_bytes(bn);
+    BIGNUM *bn;
+    int pad;
+    if (!*pval)
+        return -1;
+    bn = (BIGNUM *)*pval;
+    /* If MSB set in an octet we need a padding byte */
+    if (BN_num_bits(bn) & 0x7)
+        pad = 0;
+    else
+        pad = 1;
+    if (cont) {
+        if (pad)
+            *cont++ = 0;
+        BN_bn2bin(bn, cont);
+    }
+    return pad + BN_num_bytes(bn);
 }
 
 static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-		  int utype, char *free_cont, const ASN1_ITEM *it)
+                  int utype, char *free_cont, const ASN1_ITEM *it)
 {
-	BIGNUM *bn;
-	if(!*pval)
-		{
-		if (!bn_new(pval, it))
-			{
-			return 0;
-			}
-		}
-	bn  = (BIGNUM *)*pval;
-	if(!BN_bin2bn(cont, len, bn)) {
-		bn_free(pval, it);
-		return 0;
-	}
-	return 1;
+    BIGNUM *bn;
+    if (!*pval) {
+        if (!bn_new(pval, it)) {
+            return 0;
+        }
+    }
+    bn = (BIGNUM *)*pval;
+    if (!BN_bin2bn(cont, len, bn)) {
+        bn_free(pval, it);
+        return 0;
+    }
+    return 1;
 }
diff --git a/src/crypto/asn1/x_long.c b/src/crypto/asn1/x_long.c
index 7b1a6fe..bc4d275 100644
--- a/src/crypto/asn1/x_long.c
+++ b/src/crypto/asn1/x_long.c
@@ -63,120 +63,135 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
-/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
- * and a long directly.
+/*
+ * Custom primitive type for long handling. This converts between an
+ * ASN1_INTEGER and a long directly.
  */
 
-
 static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
-static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
-static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      int indent, const ASN1_PCTX *pctx);
 
 static const ASN1_PRIMITIVE_FUNCS long_pf = {
-	NULL, 0,
-	long_new,
-	long_free,
-	long_free,	/* Clear should set to initial value */
-	long_c2i,
-	long_i2c,
-	long_print
+    NULL, 0,
+    long_new,
+    long_free,
+    long_free,                  /* Clear should set to initial value */
+    long_c2i,
+    long_i2c,
+    long_print
 };
 
 ASN1_ITEM_start(LONG)
-	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
 ASN1_ITEM_end(LONG)
 
 ASN1_ITEM_start(ZLONG)
-	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
 ASN1_ITEM_end(ZLONG)
 
 static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-	*(long *)pval = it->size;
-	return 1;
+    *(long *)pval = it->size;
+    return 1;
 }
 
 static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-	*(long *)pval = it->size;
+    *(long *)pval = it->size;
 }
 
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it)
 {
-	long ltmp;
-	unsigned long utmp;
-	int clen, pad, i;
-	/* this exists to bypass broken gcc optimization */
-	char *cp = (char *)pval;
+    long ltmp;
+    unsigned long utmp;
+    int clen, pad, i;
+    /* this exists to bypass broken gcc optimization */
+    char *cp = (char *)pval;
 
-	/* use memcpy, because we may not be long aligned */
-	memcpy(&ltmp, cp, sizeof(long));
+    /* use memcpy, because we may not be long aligned */
+    memcpy(&ltmp, cp, sizeof(long));
 
-	if(ltmp == it->size) return -1;
-	/* Convert the long to positive: we subtract one if negative so
-	 * we can cleanly handle the padding if only the MSB of the leading
-	 * octet is set. 
-	 */
-	if(ltmp < 0) utmp = -ltmp - 1;
-	else utmp = ltmp;
-	clen = BN_num_bits_word(utmp);
-	/* If MSB of leading octet set we need to pad */
-	if(!(clen & 0x7)) pad = 1;
-	else pad = 0;
+    if (ltmp == it->size)
+        return -1;
+    /*
+     * Convert the long to positive: we subtract one if negative so we can
+     * cleanly handle the padding if only the MSB of the leading octet is
+     * set.
+     */
+    if (ltmp < 0)
+        utmp = -ltmp - 1;
+    else
+        utmp = ltmp;
+    clen = BN_num_bits_word(utmp);
+    /* If MSB of leading octet set we need to pad */
+    if (!(clen & 0x7))
+        pad = 1;
+    else
+        pad = 0;
 
-	/* Convert number of bits to number of octets */
-	clen = (clen + 7) >> 3;
+    /* Convert number of bits to number of octets */
+    clen = (clen + 7) >> 3;
 
-	if(cont) {
-		if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
-		for(i = clen - 1; i >= 0; i--) {
-			cont[i] = (unsigned char)(utmp & 0xff);
-			if(ltmp < 0) cont[i] ^= 0xff;
-			utmp >>= 8;
-		}
-	}
-	return clen + pad;
+    if (cont) {
+        if (pad)
+            *cont++ = (ltmp < 0) ? 0xff : 0;
+        for (i = clen - 1; i >= 0; i--) {
+            cont[i] = (unsigned char)(utmp & 0xff);
+            if (ltmp < 0)
+                cont[i] ^= 0xff;
+            utmp >>= 8;
+        }
+    }
+    return clen + pad;
 }
 
 static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-		    int utype, char *free_cont, const ASN1_ITEM *it)
+                    int utype, char *free_cont, const ASN1_ITEM *it)
 {
-	int neg, i;
-	long ltmp;
-	unsigned long utmp = 0;
-	char *cp = (char *)pval;
-	if(len > (int)sizeof(long)) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
-		return 0;
-	}
-	/* Is it negative? */
-	if(len && (cont[0] & 0x80)) neg = 1;
-	else neg = 0;
-	utmp = 0;
-	for(i = 0; i < len; i++) {
-		utmp <<= 8;
-		if(neg) utmp |= cont[i] ^ 0xff;
-		else utmp |= cont[i];
-	}
-	ltmp = (long)utmp;
-	if(neg) {
-		ltmp++;
-		ltmp = -ltmp;
-	}
-	if(ltmp == it->size) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
-		return 0;
-	}
-	memcpy(cp, &ltmp, sizeof(long));
-	return 1;
+    int neg, i;
+    long ltmp;
+    unsigned long utmp = 0;
+    char *cp = (char *)pval;
+    if (len > (int)sizeof(long)) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    /* Is it negative? */
+    if (len && (cont[0] & 0x80))
+        neg = 1;
+    else
+        neg = 0;
+    utmp = 0;
+    for (i = 0; i < len; i++) {
+        utmp <<= 8;
+        if (neg)
+            utmp |= cont[i] ^ 0xff;
+        else
+            utmp |= cont[i];
+    }
+    ltmp = (long)utmp;
+    if (neg) {
+        ltmp++;
+        ltmp = -ltmp;
+    }
+    if (ltmp == it->size) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    memcpy(cp, &ltmp, sizeof(long));
+    return 1;
 }
 
 static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
-			int indent, const ASN1_PCTX *pctx)
-	{
-	return BIO_printf(out, "%ld\n", *(long *)pval);
-	}
+                      int indent, const ASN1_PCTX *pctx)
+{
+    return BIO_printf(out, "%ld\n", *(long *)pval);
+}
diff --git a/src/crypto/base64/base64_test.cc b/src/crypto/base64/base64_test.cc
index fde0b46..da016e6 100644
--- a/src/crypto/base64/base64_test.cc
+++ b/src/crypto/base64/base64_test.cc
@@ -116,7 +116,6 @@
 
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!TestEncode() ||
       !TestDecode()) {
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index 6864f6f..844fba7 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -64,7 +64,7 @@
 #include <openssl/mem.h>
 
 
-BIO *BIO_new_mem_buf(void *buf, int len) {
+BIO *BIO_new_mem_buf(const void *buf, int len) {
   BIO *ret;
   BUF_MEM *b;
   const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
@@ -80,7 +80,8 @@
   }
 
   b = (BUF_MEM *)ret->ptr;
-  b->data = buf;
+  /* BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. */
+  b->data = (void *)buf;
   b->length = size;
   b->max = size;
 
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index 4d7dfe2..3615ab4 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -331,7 +331,7 @@
 
 static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
                      size_t expected_len, size_t max_len) {
-  ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(data), data_len));
+  ScopedBIO bio(BIO_new_mem_buf(data, data_len));
 
   uint8_t *out;
   size_t out_len;
@@ -412,7 +412,6 @@
 
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
 #if defined(OPENSSL_WINDOWS)
   // Initialize Winsock.
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
index 9d0cb3c..1557451 100644
--- a/src/crypto/bio/buffer.c
+++ b/src/crypto/bio/buffer.c
@@ -100,7 +100,7 @@
   if (ctx->ibuf == NULL) {
     goto err1;
   }
-  ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+  ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
   if (ctx->obuf == NULL) {
     goto err2;
   }
@@ -340,13 +340,13 @@
       p1 = ctx->ibuf;
       p2 = ctx->obuf;
       if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
-        p1 = (char *)OPENSSL_malloc(ibs);
+        p1 = OPENSSL_malloc(ibs);
         if (p1 == NULL) {
           goto malloc_error;
         }
       }
       if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
-        p2 = (char *)OPENSSL_malloc(obs);
+        p2 = OPENSSL_malloc(obs);
         if (p2 == NULL) {
           if (p1 != ctx->ibuf) {
             OPENSSL_free(p1);
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 0b0bf13..01d49b1 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -58,7 +58,6 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <stdio.h>
 #include <string.h>
 
 #if !defined(OPENSSL_WINDOWS)
@@ -542,3 +541,7 @@
 int BIO_set_nbio(BIO *bio, int on) {
   return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL);
 }
+
+int BIO_do_connect(BIO *bio) {
+  return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL);
+}
diff --git a/src/crypto/bio/fd.c b/src/crypto/bio/fd.c
index 0b3484c..12e6a72 100644
--- a/src/crypto/bio/fd.c
+++ b/src/crypto/bio/fd.c
@@ -72,6 +72,8 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "internal.h"
+
 
 static int bio_fd_non_fatal_error(int err) {
   if (
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index 9e29b43..b903bc2 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -87,47 +87,11 @@
 #define BIO_FP_WRITE 0x04
 #define BIO_FP_APPEND 0x08
 
-static FILE *open_file(const char *filename, const char *mode) {
-#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
-  int sz, len_0 = (int)strlen(filename) + 1;
-  DWORD flags;
-
-  /* Basically there are three cases to cover: a) filename is pure ASCII
-   * string; b) actual UTF-8 encoded string and c) locale-ized string, i.e. one
-   * containing 8-bit characters that are meaningful in current system locale.
-   * If filename is pure ASCII or real UTF-8 encoded string,
-   * MultiByteToWideChar succeeds and _wfopen works. If filename is locale-ized
-   * string, chances are that MultiByteToWideChar fails reporting
-   * ERROR_NO_UNICODE_TRANSLATION, in which case we fall back to fopen... */
-  if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
-                                filename, len_0, NULL, 0)) > 0 ||
-      (GetLastError() == ERROR_INVALID_FLAGS &&
-       (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), filename, len_0, NULL,
-                                 0)) > 0)) {
-    WCHAR wmode[8];
-    WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
-
-    if (MultiByteToWideChar(CP_UTF8, flags, filename, len_0, wfilename, sz) &&
-        MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, wmode,
-                            sizeof(wmode) / sizeof(wmode[0])) &&
-        (file = _wfopen(wfilename, wmode)) == NULL &&
-        (errno == ENOENT ||
-         errno == EBADF)) /* UTF-8 decode succeeded, but no file, filename
-                           * could still have been locale-ized... */
-      return fopen(filename, mode);
-  } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
-    return fopen(filename, mode);
-  }
-#else
-  return fopen(filename, mode);
-#endif
-}
-
 BIO *BIO_new_file(const char *filename, const char *mode) {
   BIO *ret;
   FILE *file;
 
-  file = open_file(filename, mode);
+  file = fopen(filename, mode);
   if (file == NULL) {
     OPENSSL_PUT_SYSTEM_ERROR();
 
@@ -256,7 +220,7 @@
         ret = 0;
         break;
       }
-      fp = open_file(ptr, p);
+      fp = fopen(ptr, p);
       if (fp == NULL) {
         OPENSSL_PUT_SYSTEM_ERROR();
         ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
diff --git a/src/crypto/bio/internal.h b/src/crypto/bio/internal.h
index d9a34f1..eb6b26f 100644
--- a/src/crypto/bio/internal.h
+++ b/src/crypto/bio/internal.h
@@ -67,6 +67,9 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #else
+#pragma warning(push, 3)
+#include <winsock2.h>
+#pragma warning(pop)
 typedef int socklen_t;
 #endif
 
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index fba4be2..2da2d20 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -742,7 +742,7 @@
     bio_free,     NULL /* no bio_callback_ctrl */
 };
 
-const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
+static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
 
 int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
                      BIO** bio2_p, size_t writebuf2) {
diff --git a/src/crypto/bio/socket.c b/src/crypto/bio/socket.c
index 98f32a6..3ef6967 100644
--- a/src/crypto/bio/socket.c
+++ b/src/crypto/bio/socket.c
@@ -110,7 +110,11 @@
   }
 
   bio_clear_socket_error();
+#if defined(OPENSSL_WINDOWS)
   ret = recv(b->num, out, outl, 0);
+#else
+  ret = read(b->num, out, outl);
+#endif
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
     if (bio_fd_should_retry(ret)) {
@@ -124,7 +128,11 @@
   int ret;
 
   bio_clear_socket_error();
+#if defined(OPENSSL_WINDOWS)
   ret = send(b->num, in, inl, 0);
+#else
+  ret = write(b->num, in, inl);
+#endif
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
     if (bio_fd_should_retry(ret)) {
diff --git a/src/crypto/bn/asm/armv4-mont.pl b/src/crypto/bn/asm/armv4-mont.pl
index 4206fd8..b751112 100644
--- a/src/crypto/bn/asm/armv4-mont.pl
+++ b/src/crypto/bn/asm/armv4-mont.pl
@@ -91,7 +91,6 @@
 #endif
 
 .global	bn_mul_mont
-.hidden	bn_mul_mont
 .type	bn_mul_mont,%function
 
 .align	5
@@ -108,7 +107,7 @@
 #ifdef	__APPLE__
 	ldr	r0,[r0]
 #endif
-	tst	r0,#1			@ NEON available?
+	tst	r0,#ARMV7_NEON		@ NEON available?
 	ldmia	sp, {r0,r2}
 	beq	.Lialu
 	add	sp,sp,#8
diff --git a/src/crypto/bn/asm/rsaz-avx2.pl b/src/crypto/bn/asm/rsaz-avx2.pl
old mode 100644
new mode 100755
index bbceccb..6b57bd0
--- a/src/crypto/bn/asm/rsaz-avx2.pl
+++ b/src/crypto/bn/asm/rsaz-avx2.pl
@@ -427,7 +427,7 @@
 $TEMP3 = $Y1;
 $TEMP4 = $Y2;
 $code.=<<___;
-	#we need to fix indexes 32-39 to avoid overflow
+	# we need to fix indices 32-39 to avoid overflow
 	vmovdqu		32*8(%rsp), $ACC8		# 32*8-192($tp0),
 	vmovdqu		32*9(%rsp), $ACC1		# 32*9-192($tp0)
 	vmovdqu		32*10(%rsp), $ACC2		# 32*10-192($tp0)
@@ -1576,68 +1576,128 @@
 .type	rsaz_1024_gather5_avx2,\@abi-omnipotent
 .align	32
 rsaz_1024_gather5_avx2:
+	vzeroupper
+	mov	%rsp,%r11
 ___
 $code.=<<___ if ($win64);
 	lea	-0x88(%rsp),%rax
-	vzeroupper
 .LSEH_begin_rsaz_1024_gather5:
 	# I can't trust assembler to use specific encoding:-(
-	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax),%rsp
-	.byte	0xc5,0xf8,0x29,0x70,0xe0	#vmovaps %xmm6,-0x20(%rax)
-	.byte	0xc5,0xf8,0x29,0x78,0xf0	#vmovaps %xmm7,-0x10(%rax)
-	.byte	0xc5,0x78,0x29,0x40,0x00	#vmovaps %xmm8,0(%rax)
-	.byte	0xc5,0x78,0x29,0x48,0x10	#vmovaps %xmm9,0x10(%rax)
-	.byte	0xc5,0x78,0x29,0x50,0x20	#vmovaps %xmm10,0x20(%rax)
-	.byte	0xc5,0x78,0x29,0x58,0x30	#vmovaps %xmm11,0x30(%rax)
-	.byte	0xc5,0x78,0x29,0x60,0x40	#vmovaps %xmm12,0x40(%rax)
-	.byte	0xc5,0x78,0x29,0x68,0x50	#vmovaps %xmm13,0x50(%rax)
-	.byte	0xc5,0x78,0x29,0x70,0x60	#vmovaps %xmm14,0x60(%rax)
-	.byte	0xc5,0x78,0x29,0x78,0x70	#vmovaps %xmm15,0x70(%rax)
+	.byte	0x48,0x8d,0x60,0xe0		# lea	-0x20(%rax),%rsp
+	.byte	0xc5,0xf8,0x29,0x70,0xe0	# vmovaps %xmm6,-0x20(%rax)
+	.byte	0xc5,0xf8,0x29,0x78,0xf0	# vmovaps %xmm7,-0x10(%rax)
+	.byte	0xc5,0x78,0x29,0x40,0x00	# vmovaps %xmm8,0(%rax)
+	.byte	0xc5,0x78,0x29,0x48,0x10	# vmovaps %xmm9,0x10(%rax)
+	.byte	0xc5,0x78,0x29,0x50,0x20	# vmovaps %xmm10,0x20(%rax)
+	.byte	0xc5,0x78,0x29,0x58,0x30	# vmovaps %xmm11,0x30(%rax)
+	.byte	0xc5,0x78,0x29,0x60,0x40	# vmovaps %xmm12,0x40(%rax)
+	.byte	0xc5,0x78,0x29,0x68,0x50	# vmovaps %xmm13,0x50(%rax)
+	.byte	0xc5,0x78,0x29,0x70,0x60	# vmovaps %xmm14,0x60(%rax)
+	.byte	0xc5,0x78,0x29,0x78,0x70	# vmovaps %xmm15,0x70(%rax)
 ___
 $code.=<<___;
-	lea	.Lgather_table(%rip),%r11
-	mov	$power,%eax
-	and	\$3,$power
-	shr	\$2,%eax			# cache line number
-	shl	\$4,$power			# offset within cache line
+	lea	-0x100(%rsp),%rsp
+	and	\$-32, %rsp
+	lea	.Linc(%rip), %r10
+	lea	-128(%rsp),%rax			# control u-op density
 
-	vmovdqu		-32(%r11),%ymm7		# .Lgather_permd
-	vpbroadcastb	8(%r11,%rax), %xmm8
-	vpbroadcastb	7(%r11,%rax), %xmm9
-	vpbroadcastb	6(%r11,%rax), %xmm10
-	vpbroadcastb	5(%r11,%rax), %xmm11
-	vpbroadcastb	4(%r11,%rax), %xmm12
-	vpbroadcastb	3(%r11,%rax), %xmm13
-	vpbroadcastb	2(%r11,%rax), %xmm14
-	vpbroadcastb	1(%r11,%rax), %xmm15
+	vmovd		$power, %xmm4
+	vmovdqa		(%r10),%ymm0
+	vmovdqa		32(%r10),%ymm1
+	vmovdqa		64(%r10),%ymm5
+	vpbroadcastd	%xmm4,%ymm4
 
-	lea	64($inp,$power),$inp
-	mov	\$64,%r11			# size optimization
-	mov	\$9,%eax
-	jmp	.Loop_gather_1024
+	vpaddd		%ymm5, %ymm0, %ymm2
+	vpcmpeqd	%ymm4, %ymm0, %ymm0
+	vpaddd		%ymm5, %ymm1, %ymm3
+	vpcmpeqd	%ymm4, %ymm1, %ymm1
+	vmovdqa		%ymm0, 32*0+128(%rax)
+	vpaddd		%ymm5, %ymm2, %ymm0
+	vpcmpeqd	%ymm4, %ymm2, %ymm2
+	vmovdqa		%ymm1, 32*1+128(%rax)
+	vpaddd		%ymm5, %ymm3, %ymm1
+	vpcmpeqd	%ymm4, %ymm3, %ymm3
+	vmovdqa		%ymm2, 32*2+128(%rax)
+	vpaddd		%ymm5, %ymm0, %ymm2
+	vpcmpeqd	%ymm4, %ymm0, %ymm0
+	vmovdqa		%ymm3, 32*3+128(%rax)
+	vpaddd		%ymm5, %ymm1, %ymm3
+	vpcmpeqd	%ymm4, %ymm1, %ymm1
+	vmovdqa		%ymm0, 32*4+128(%rax)
+	vpaddd		%ymm5, %ymm2, %ymm8
+	vpcmpeqd	%ymm4, %ymm2, %ymm2
+	vmovdqa		%ymm1, 32*5+128(%rax)
+	vpaddd		%ymm5, %ymm3, %ymm9
+	vpcmpeqd	%ymm4, %ymm3, %ymm3
+	vmovdqa		%ymm2, 32*6+128(%rax)
+	vpaddd		%ymm5, %ymm8, %ymm10
+	vpcmpeqd	%ymm4, %ymm8, %ymm8
+	vmovdqa		%ymm3, 32*7+128(%rax)
+	vpaddd		%ymm5, %ymm9, %ymm11
+	vpcmpeqd	%ymm4, %ymm9, %ymm9
+	vpaddd		%ymm5, %ymm10, %ymm12
+	vpcmpeqd	%ymm4, %ymm10, %ymm10
+	vpaddd		%ymm5, %ymm11, %ymm13
+	vpcmpeqd	%ymm4, %ymm11, %ymm11
+	vpaddd		%ymm5, %ymm12, %ymm14
+	vpcmpeqd	%ymm4, %ymm12, %ymm12
+	vpaddd		%ymm5, %ymm13, %ymm15
+	vpcmpeqd	%ymm4, %ymm13, %ymm13
+	vpcmpeqd	%ymm4, %ymm14, %ymm14
+	vpcmpeqd	%ymm4, %ymm15, %ymm15
 
-.align	32
+	vmovdqa	-32(%r10),%ymm7			# .Lgather_permd
+	lea	128($inp), $inp
+	mov	\$9,$power
+
 .Loop_gather_1024:
-	vpand		-64($inp),		%xmm8,%xmm0
-	vpand		($inp),			%xmm9,%xmm1
-	vpand		64($inp),		%xmm10,%xmm2
-	vpand		($inp,%r11,2),		%xmm11,%xmm3
-	 vpor					%xmm0,%xmm1,%xmm1
-	vpand		64($inp,%r11,2),	%xmm12,%xmm4
-	 vpor					%xmm2,%xmm3,%xmm3
-	vpand		($inp,%r11,4),		%xmm13,%xmm5
-	 vpor					%xmm1,%xmm3,%xmm3
-	vpand		64($inp,%r11,4),	%xmm14,%xmm6
-	 vpor					%xmm4,%xmm5,%xmm5
-	vpand		-128($inp,%r11,8),	%xmm15,%xmm2
-	lea		($inp,%r11,8),$inp
-	 vpor					%xmm3,%xmm5,%xmm5
-	 vpor					%xmm2,%xmm6,%xmm6
-	 vpor					%xmm5,%xmm6,%xmm6
-	vpermd		%ymm6,%ymm7,%ymm6
-	vmovdqu		%ymm6,($out)
+	vmovdqa		32*0-128($inp),	%ymm0
+	vmovdqa		32*1-128($inp),	%ymm1
+	vmovdqa		32*2-128($inp),	%ymm2
+	vmovdqa		32*3-128($inp),	%ymm3
+	vpand		32*0+128(%rax),	%ymm0,	%ymm0
+	vpand		32*1+128(%rax),	%ymm1,	%ymm1
+	vpand		32*2+128(%rax),	%ymm2,	%ymm2
+	vpor		%ymm0, %ymm1, %ymm4
+	vpand		32*3+128(%rax),	%ymm3,	%ymm3
+	vmovdqa		32*4-128($inp),	%ymm0
+	vmovdqa		32*5-128($inp),	%ymm1
+	vpor		%ymm2, %ymm3, %ymm5
+	vmovdqa		32*6-128($inp),	%ymm2
+	vmovdqa		32*7-128($inp),	%ymm3
+	vpand		32*4+128(%rax),	%ymm0,	%ymm0
+	vpand		32*5+128(%rax),	%ymm1,	%ymm1
+	vpand		32*6+128(%rax),	%ymm2,	%ymm2
+	vpor		%ymm0, %ymm4, %ymm4
+	vpand		32*7+128(%rax),	%ymm3,	%ymm3
+	vpand		32*8-128($inp),	%ymm8,	%ymm0
+	vpor		%ymm1, %ymm5, %ymm5
+	vpand		32*9-128($inp),	%ymm9,	%ymm1
+	vpor		%ymm2, %ymm4, %ymm4
+	vpand		32*10-128($inp),%ymm10,	%ymm2
+	vpor		%ymm3, %ymm5, %ymm5
+	vpand		32*11-128($inp),%ymm11,	%ymm3
+	vpor		%ymm0, %ymm4, %ymm4
+	vpand		32*12-128($inp),%ymm12,	%ymm0
+	vpor		%ymm1, %ymm5, %ymm5
+	vpand		32*13-128($inp),%ymm13,	%ymm1
+	vpor		%ymm2, %ymm4, %ymm4
+	vpand		32*14-128($inp),%ymm14,	%ymm2
+	vpor		%ymm3, %ymm5, %ymm5
+	vpand		32*15-128($inp),%ymm15,	%ymm3
+	lea		32*16($inp), $inp
+	vpor		%ymm0, %ymm4, %ymm4
+	vpor		%ymm1, %ymm5, %ymm5
+	vpor		%ymm2, %ymm4, %ymm4
+	vpor		%ymm3, %ymm5, %ymm5
+
+	vpor		%ymm5, %ymm4, %ymm4
+	vextracti128	\$1, %ymm4, %xmm5	# upper half is cleared
+	vpor		%xmm4, %xmm5, %xmm5
+	vpermd		%ymm5,%ymm7,%ymm5
+	vmovdqu		%ymm5,($out)
 	lea		32($out),$out
-	dec	%eax
+	dec	$power
 	jnz	.Loop_gather_1024
 
 	vpxor	%ymm0,%ymm0,%ymm0
@@ -1645,20 +1705,20 @@
 	vzeroupper
 ___
 $code.=<<___ if ($win64);
-	movaps	(%rsp),%xmm6
-	movaps	0x10(%rsp),%xmm7
-	movaps	0x20(%rsp),%xmm8
-	movaps	0x30(%rsp),%xmm9
-	movaps	0x40(%rsp),%xmm10
-	movaps	0x50(%rsp),%xmm11
-	movaps	0x60(%rsp),%xmm12
-	movaps	0x70(%rsp),%xmm13
-	movaps	0x80(%rsp),%xmm14
-	movaps	0x90(%rsp),%xmm15
-	lea	0xa8(%rsp),%rsp
+	movaps	-0xa8(%r11),%xmm6
+	movaps	-0x98(%r11),%xmm7
+	movaps	-0x88(%r11),%xmm8
+	movaps	-0x78(%r11),%xmm9
+	movaps	-0x68(%r11),%xmm10
+	movaps	-0x58(%r11),%xmm11
+	movaps	-0x48(%r11),%xmm12
+	movaps	-0x38(%r11),%xmm13
+	movaps	-0x28(%r11),%xmm14
+	movaps	-0x18(%r11),%xmm15
 .LSEH_end_rsaz_1024_gather5:
 ___
 $code.=<<___;
+	lea	(%r11),%rsp
 	ret
 .size	rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2
 ___
@@ -1692,8 +1752,10 @@
 	.long	0,2,4,6,7,7,7,7
 .Lgather_permd:
 	.long	0,7,1,7,2,7,3,7
-.Lgather_table:
-	.byte	0,0,0,0,0,0,0,0, 0xff,0,0,0,0,0,0,0
+.Linc:
+	.long	0,0,0,0, 1,1,1,1
+	.long	2,2,2,2, 3,3,3,3
+	.long	4,4,4,4, 4,4,4,4
 .align	64
 ___
 
@@ -1821,18 +1883,19 @@
 	.rva	rsaz_se_handler
 	.rva	.Lmul_1024_body,.Lmul_1024_epilogue
 .LSEH_info_rsaz_1024_gather5:
-	.byte	0x01,0x33,0x16,0x00
-	.byte	0x36,0xf8,0x09,0x00	#vmovaps 0x90(rsp),xmm15
-	.byte	0x31,0xe8,0x08,0x00	#vmovaps 0x80(rsp),xmm14
-	.byte	0x2c,0xd8,0x07,0x00	#vmovaps 0x70(rsp),xmm13
-	.byte	0x27,0xc8,0x06,0x00	#vmovaps 0x60(rsp),xmm12
-	.byte	0x22,0xb8,0x05,0x00	#vmovaps 0x50(rsp),xmm11
-	.byte	0x1d,0xa8,0x04,0x00	#vmovaps 0x40(rsp),xmm10
-	.byte	0x18,0x98,0x03,0x00	#vmovaps 0x30(rsp),xmm9
-	.byte	0x13,0x88,0x02,0x00	#vmovaps 0x20(rsp),xmm8
-	.byte	0x0e,0x78,0x01,0x00	#vmovaps 0x10(rsp),xmm7
-	.byte	0x09,0x68,0x00,0x00	#vmovaps 0x00(rsp),xmm6
-	.byte	0x04,0x01,0x15,0x00	#sub	rsp,0xa8
+	.byte	0x01,0x36,0x17,0x0b
+	.byte	0x36,0xf8,0x09,0x00	# vmovaps 0x90(rsp),xmm15
+	.byte	0x31,0xe8,0x08,0x00	# vmovaps 0x80(rsp),xmm14
+	.byte	0x2c,0xd8,0x07,0x00	# vmovaps 0x70(rsp),xmm13
+	.byte	0x27,0xc8,0x06,0x00	# vmovaps 0x60(rsp),xmm12
+	.byte	0x22,0xb8,0x05,0x00	# vmovaps 0x50(rsp),xmm11
+	.byte	0x1d,0xa8,0x04,0x00	# vmovaps 0x40(rsp),xmm10
+	.byte	0x18,0x98,0x03,0x00	# vmovaps 0x30(rsp),xmm9
+	.byte	0x13,0x88,0x02,0x00	# vmovaps 0x20(rsp),xmm8
+	.byte	0x0e,0x78,0x01,0x00	# vmovaps 0x10(rsp),xmm7
+	.byte	0x09,0x68,0x00,0x00	# vmovaps 0x00(rsp),xmm6
+	.byte	0x04,0x01,0x15,0x00	# sub	  rsp,0xa8
+	.byte	0x00,0xb3,0x00,0x00	# set_frame r11
 ___
 }
 
diff --git a/src/crypto/bn/asm/rsaz-x86_64.pl b/src/crypto/bn/asm/rsaz-x86_64.pl
old mode 100644
new mode 100755
index 4113d53..c38bde9
--- a/src/crypto/bn/asm/rsaz-x86_64.pl
+++ b/src/crypto/bn/asm/rsaz-x86_64.pl
@@ -902,9 +902,76 @@
 	push	%r14
 	push	%r15
 
-	mov	$pwr, $pwr
-	subq	\$128+24, %rsp
+	subq	\$`128+24+($win64?0xb0:0)`, %rsp
+___
+$code.=<<___	if ($win64);
+	movaps	%xmm6,0xa0(%rsp)
+	movaps	%xmm7,0xb0(%rsp)
+	movaps	%xmm8,0xc0(%rsp)
+	movaps	%xmm9,0xd0(%rsp)
+	movaps	%xmm10,0xe0(%rsp)
+	movaps	%xmm11,0xf0(%rsp)
+	movaps	%xmm12,0x100(%rsp)
+	movaps	%xmm13,0x110(%rsp)
+	movaps	%xmm14,0x120(%rsp)
+	movaps	%xmm15,0x130(%rsp)
+___
+$code.=<<___;
 .Lmul_gather4_body:
+	movd	$pwr,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1	# 00000002000000020000000200000002
+	movdqa	.Linc(%rip),%xmm0	# 00000001000000010000000000000000
+
+	pshufd	\$0,%xmm8,%xmm8		# broadcast $power
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..15 to $power
+#
+for($i=0;$i<4;$i++) {
+$code.=<<___;
+	paddd	%xmm`$i`,%xmm`$i+1`
+	pcmpeqd	%xmm8,%xmm`$i`
+	movdqa	%xmm7,%xmm`$i+3`
+___
+}
+for(;$i<7;$i++) {
+$code.=<<___;
+	paddd	%xmm`$i`,%xmm`$i+1`
+	pcmpeqd	%xmm8,%xmm`$i`
+___
+}
+$code.=<<___;
+	pcmpeqd	%xmm8,%xmm7
+
+	movdqa	16*0($bp),%xmm8
+	movdqa	16*1($bp),%xmm9
+	movdqa	16*2($bp),%xmm10
+	movdqa	16*3($bp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	16*4($bp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	16*5($bp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	16*6($bp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	16*7($bp),%xmm15
+	leaq	128($bp), %rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	\$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
 ___
 $code.=<<___ if ($addx);
 	movl	\$0x80100,%r11d
@@ -913,45 +980,38 @@
 	je	.Lmulx_gather
 ___
 $code.=<<___;
-	movl	64($bp,$pwr,4), %eax
-	movq	$out, %xmm0		# off-load arguments
-	movl	($bp,$pwr,4), %ebx
-	movq	$mod, %xmm1
-	movq	$n0, 128(%rsp)
+	movq	%xmm8,%rbx
 
-	shlq	\$32, %rax
-	or	%rax, %rbx
+	movq	$n0, 128(%rsp)		# off-load arguments
+	movq	$out, 128+8(%rsp)
+	movq	$mod, 128+16(%rsp)
+
 	movq	($ap), %rax
 	 movq	8($ap), %rcx
-	 leaq	128($bp,$pwr,4), %rbp
 	mulq	%rbx			# 0 iteration
 	movq	%rax, (%rsp)
 	movq	%rcx, %rax
 	movq	%rdx, %r8
 
 	mulq	%rbx
-	 movd	(%rbp), %xmm4
 	addq	%rax, %r8
 	movq	16($ap), %rax
 	movq	%rdx, %r9
 	adcq	\$0, %r9
 
 	mulq	%rbx
-	 movd	64(%rbp), %xmm5
 	addq	%rax, %r9
 	movq	24($ap), %rax
 	movq	%rdx, %r10
 	adcq	\$0, %r10
 
 	mulq	%rbx
-	 pslldq	\$4, %xmm5
 	addq	%rax, %r10
 	movq	32($ap), %rax
 	movq	%rdx, %r11
 	adcq	\$0, %r11
 
 	mulq	%rbx
-	 por	%xmm5, %xmm4
 	addq	%rax, %r11
 	movq	40($ap), %rax
 	movq	%rdx, %r12
@@ -964,14 +1024,12 @@
 	adcq	\$0, %r13
 
 	mulq	%rbx
-	 leaq	128(%rbp), %rbp
 	addq	%rax, %r13
 	movq	56($ap), %rax
 	movq	%rdx, %r14
 	adcq	\$0, %r14
 	
 	mulq	%rbx
-	 movq	%xmm4, %rbx
 	addq	%rax, %r14
 	 movq	($ap), %rax
 	movq	%rdx, %r15
@@ -983,6 +1041,35 @@
 
 .align	32
 .Loop_mul_gather:
+	movdqa	16*0(%rbp),%xmm8
+	movdqa	16*1(%rbp),%xmm9
+	movdqa	16*2(%rbp),%xmm10
+	movdqa	16*3(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	16*4(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	16*5(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	16*6(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	16*7(%rbp),%xmm15
+	leaq	128(%rbp), %rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	\$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,%rbx
+
 	mulq	%rbx
 	addq	%rax, %r8
 	movq	8($ap), %rax
@@ -991,7 +1078,6 @@
 	adcq	\$0, %r8
 
 	mulq	%rbx
-	 movd	(%rbp), %xmm4
 	addq	%rax, %r9
 	movq	16($ap), %rax
 	adcq	\$0, %rdx
@@ -1000,7 +1086,6 @@
 	adcq	\$0, %r9
 
 	mulq	%rbx
-	 movd	64(%rbp), %xmm5
 	addq	%rax, %r10
 	movq	24($ap), %rax
 	adcq	\$0, %rdx
@@ -1009,7 +1094,6 @@
 	adcq	\$0, %r10
 
 	mulq	%rbx
-	 pslldq	\$4, %xmm5
 	addq	%rax, %r11
 	movq	32($ap), %rax
 	adcq	\$0, %rdx
@@ -1018,7 +1102,6 @@
 	adcq	\$0, %r11
 
 	mulq	%rbx
-	 por	%xmm5, %xmm4
 	addq	%rax, %r12
 	movq	40($ap), %rax
 	adcq	\$0, %rdx
@@ -1043,7 +1126,6 @@
 	adcq	\$0, %r14
 
 	mulq	%rbx
-	 movq	%xmm4, %rbx
 	addq	%rax, %r15
 	 movq	($ap), %rax
 	adcq	\$0, %rdx
@@ -1051,7 +1133,6 @@
 	movq	%rdx, %r15	
 	adcq	\$0, %r15
 
-	leaq	128(%rbp), %rbp
 	leaq	8(%rdi), %rdi
 
 	decl	%ecx
@@ -1066,8 +1147,8 @@
 	movq	%r14, 48(%rdi)
 	movq	%r15, 56(%rdi)
 
-	movq	%xmm0, $out
-	movq	%xmm1, %rbp
+	movq	128+8(%rsp), $out
+	movq	128+16(%rsp), %rbp
 
 	movq	(%rsp), %r8
 	movq	8(%rsp), %r9
@@ -1085,45 +1166,37 @@
 
 .align	32
 .Lmulx_gather:
-	mov	64($bp,$pwr,4), %eax
-	movq	$out, %xmm0		# off-load arguments
-	lea	128($bp,$pwr,4), %rbp
-	mov	($bp,$pwr,4), %edx
-	movq	$mod, %xmm1
-	mov	$n0, 128(%rsp)
+	movq	%xmm8,%rdx
 
-	shl	\$32, %rax
-	or	%rax, %rdx
+	mov	$n0, 128(%rsp)		# off-load arguments
+	mov	$out, 128+8(%rsp)
+	mov	$mod, 128+16(%rsp)
+
 	mulx	($ap), %rbx, %r8	# 0 iteration
 	mov	%rbx, (%rsp)
 	xor	%edi, %edi		# cf=0, of=0
 
 	mulx	8($ap), %rax, %r9
-	 movd	(%rbp), %xmm4
 
 	mulx	16($ap), %rbx, %r10
-	 movd	64(%rbp), %xmm5
 	adcx	%rax, %r8
 
 	mulx	24($ap), %rax, %r11
-	 pslldq	\$4, %xmm5
 	adcx	%rbx, %r9
 
 	mulx	32($ap), %rbx, %r12
-	 por	%xmm5, %xmm4
 	adcx	%rax, %r10
 
 	mulx	40($ap), %rax, %r13
 	adcx	%rbx, %r11
 
 	mulx	48($ap), %rbx, %r14
-	 lea	128(%rbp), %rbp
 	adcx	%rax, %r12
 	
 	mulx	56($ap), %rax, %r15
-	 movq	%xmm4, %rdx
 	adcx	%rbx, %r13
 	adcx	%rax, %r14
+	.byte	0x67
 	mov	%r8, %rbx
 	adcx	%rdi, %r15		# %rdi is 0
 
@@ -1132,24 +1205,48 @@
 
 .align	32
 .Loop_mulx_gather:
-	mulx	($ap), %rax, %r8
+	movdqa	16*0(%rbp),%xmm8
+	movdqa	16*1(%rbp),%xmm9
+	movdqa	16*2(%rbp),%xmm10
+	movdqa	16*3(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	16*4(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	16*5(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	16*6(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	16*7(%rbp),%xmm15
+	leaq	128(%rbp), %rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	\$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,%rdx
+
+	.byte	0xc4,0x62,0xfb,0xf6,0x86,0x00,0x00,0x00,0x00	# mulx	($ap), %rax, %r8
 	adcx	%rax, %rbx
 	adox	%r9, %r8
 
 	mulx	8($ap), %rax, %r9
-	.byte	0x66,0x0f,0x6e,0xa5,0x00,0x00,0x00,0x00		# movd	(%rbp), %xmm4
 	adcx	%rax, %r8
 	adox	%r10, %r9
 
 	mulx	16($ap), %rax, %r10
-	 movd	64(%rbp), %xmm5
-	 lea	128(%rbp), %rbp
 	adcx	%rax, %r9
 	adox	%r11, %r10
 
 	.byte	0xc4,0x62,0xfb,0xf6,0x9e,0x18,0x00,0x00,0x00	# mulx	24($ap), %rax, %r11
-	 pslldq	\$4, %xmm5
-	 por	%xmm5, %xmm4
 	adcx	%rax, %r10
 	adox	%r12, %r11
 
@@ -1163,10 +1260,10 @@
 
 	.byte	0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00	# mulx	48($ap), %rax, %r14
 	adcx	%rax, %r13
+	.byte	0x67
 	adox	%r15, %r14
 
 	mulx	56($ap), %rax, %r15
-	 movq	%xmm4, %rdx
 	 mov	%rbx, 64(%rsp,%rcx,8)
 	adcx	%rax, %r14
 	adox	%rdi, %r15
@@ -1185,10 +1282,10 @@
 	mov	%r14, 64+48(%rsp)
 	mov	%r15, 64+56(%rsp)
 
-	movq	%xmm0, $out
-	movq	%xmm1, %rbp
+	mov	128(%rsp), %rdx		# pull arguments
+	mov	128+8(%rsp), $out
+	mov	128+16(%rsp), %rbp
 
-	mov	128(%rsp), %rdx		# pull $n0
 	mov	(%rsp), %r8
 	mov	8(%rsp), %r9
 	mov	16(%rsp), %r10
@@ -1216,6 +1313,21 @@
 	call	__rsaz_512_subtract
 
 	leaq	128+24+48(%rsp), %rax
+___
+$code.=<<___	if ($win64);
+	movaps	0xa0-0xc8(%rax),%xmm6
+	movaps	0xb0-0xc8(%rax),%xmm7
+	movaps	0xc0-0xc8(%rax),%xmm8
+	movaps	0xd0-0xc8(%rax),%xmm9
+	movaps	0xe0-0xc8(%rax),%xmm10
+	movaps	0xf0-0xc8(%rax),%xmm11
+	movaps	0x100-0xc8(%rax),%xmm12
+	movaps	0x110-0xc8(%rax),%xmm13
+	movaps	0x120-0xc8(%rax),%xmm14
+	movaps	0x130-0xc8(%rax),%xmm15
+	lea	0xb0(%rax),%rax
+___
+$code.=<<___;
 	movq	-48(%rax), %r15
 	movq	-40(%rax), %r14
 	movq	-32(%rax), %r13
@@ -1245,7 +1357,7 @@
 	mov	$pwr, $pwr
 	subq	\$128+24, %rsp
 .Lmul_scatter4_body:
-	leaq	($tbl,$pwr,4), $tbl
+	leaq	($tbl,$pwr,8), $tbl
 	movq	$out, %xmm0		# off-load arguments
 	movq	$mod, %xmm1
 	movq	$tbl, %xmm2
@@ -1316,30 +1428,14 @@
 
 	call	__rsaz_512_subtract
 
-	movl	%r8d, 64*0($inp)	# scatter
-	shrq	\$32, %r8
-	movl	%r9d, 64*2($inp)
-	shrq	\$32, %r9
-	movl	%r10d, 64*4($inp)
-	shrq	\$32, %r10
-	movl	%r11d, 64*6($inp)
-	shrq	\$32, %r11
-	movl	%r12d, 64*8($inp)
-	shrq	\$32, %r12
-	movl	%r13d, 64*10($inp)
-	shrq	\$32, %r13
-	movl	%r14d, 64*12($inp)
-	shrq	\$32, %r14
-	movl	%r15d, 64*14($inp)
-	shrq	\$32, %r15
-	movl	%r8d, 64*1($inp)
-	movl	%r9d, 64*3($inp)
-	movl	%r10d, 64*5($inp)
-	movl	%r11d, 64*7($inp)
-	movl	%r12d, 64*9($inp)
-	movl	%r13d, 64*11($inp)
-	movl	%r14d, 64*13($inp)
-	movl	%r15d, 64*15($inp)
+	movq	%r8, 128*0($inp)	# scatter
+	movq	%r9, 128*1($inp)
+	movq	%r10, 128*2($inp)
+	movq	%r11, 128*3($inp)
+	movq	%r12, 128*4($inp)
+	movq	%r13, 128*5($inp)
+	movq	%r14, 128*6($inp)
+	movq	%r15, 128*7($inp)
 
 	leaq	128+24+48(%rsp), %rax
 	movq	-48(%rax), %r15
@@ -1943,16 +2039,14 @@
 .type	rsaz_512_scatter4,\@abi-omnipotent
 .align	16
 rsaz_512_scatter4:
-	leaq	($out,$power,4), $out
+	leaq	($out,$power,8), $out
 	movl	\$8, %r9d
 	jmp	.Loop_scatter
 .align	16
 .Loop_scatter:
 	movq	($inp), %rax
 	leaq	8($inp), $inp
-	movl	%eax, ($out)
-	shrq	\$32, %rax
-	movl	%eax, 64($out)
+	movq	%rax, ($out)
 	leaq	128($out), $out
 	decl	%r9d
 	jnz	.Loop_scatter
@@ -1963,22 +2057,106 @@
 .type	rsaz_512_gather4,\@abi-omnipotent
 .align	16
 rsaz_512_gather4:
-	leaq	($inp,$power,4), $inp
+___
+$code.=<<___	if ($win64);
+.LSEH_begin_rsaz_512_gather4:
+	.byte	0x48,0x81,0xec,0xa8,0x00,0x00,0x00	# sub    $0xa8,%rsp
+	.byte	0x0f,0x29,0x34,0x24			# movaps %xmm6,(%rsp)
+	.byte	0x0f,0x29,0x7c,0x24,0x10		# movaps %xmm7,0x10(%rsp)
+	.byte	0x44,0x0f,0x29,0x44,0x24,0x20		# movaps %xmm8,0x20(%rsp)
+	.byte	0x44,0x0f,0x29,0x4c,0x24,0x30		# movaps %xmm9,0x30(%rsp)
+	.byte	0x44,0x0f,0x29,0x54,0x24,0x40		# movaps %xmm10,0x40(%rsp)
+	.byte	0x44,0x0f,0x29,0x5c,0x24,0x50		# movaps %xmm11,0x50(%rsp)
+	.byte	0x44,0x0f,0x29,0x64,0x24,0x60		# movaps %xmm12,0x60(%rsp)
+	.byte	0x44,0x0f,0x29,0x6c,0x24,0x70		# movaps %xmm13,0x70(%rsp)
+	.byte	0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0	# movaps %xmm14,0x80(%rsp)
+	.byte	0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0	# movaps %xmm15,0x90(%rsp)
+___
+$code.=<<___;
+	movd	$power,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1	# 00000002000000020000000200000002
+	movdqa	.Linc(%rip),%xmm0	# 00000001000000010000000000000000
+
+	pshufd	\$0,%xmm8,%xmm8		# broadcast $power
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..15 to $power
+#
+for($i=0;$i<4;$i++) {
+$code.=<<___;
+	paddd	%xmm`$i`,%xmm`$i+1`
+	pcmpeqd	%xmm8,%xmm`$i`
+	movdqa	%xmm7,%xmm`$i+3`
+___
+}
+for(;$i<7;$i++) {
+$code.=<<___;
+	paddd	%xmm`$i`,%xmm`$i+1`
+	pcmpeqd	%xmm8,%xmm`$i`
+___
+}
+$code.=<<___;
+	pcmpeqd	%xmm8,%xmm7
 	movl	\$8, %r9d
 	jmp	.Loop_gather
 .align	16
 .Loop_gather:
-	movl	($inp), %eax
-	movl	64($inp), %r8d
+	movdqa	16*0($inp),%xmm8
+	movdqa	16*1($inp),%xmm9
+	movdqa	16*2($inp),%xmm10
+	movdqa	16*3($inp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	16*4($inp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	16*5($inp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	16*6($inp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	16*7($inp),%xmm15
 	leaq	128($inp), $inp
-	shlq	\$32, %r8
-	or	%r8, %rax
-	movq	%rax, ($out)
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	\$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,($out)
 	leaq	8($out), $out
 	decl	%r9d
 	jnz	.Loop_gather
+___
+$code.=<<___	if ($win64);
+	movaps	0x00(%rsp),%xmm6
+	movaps	0x10(%rsp),%xmm7
+	movaps	0x20(%rsp),%xmm8
+	movaps	0x30(%rsp),%xmm9
+	movaps	0x40(%rsp),%xmm10
+	movaps	0x50(%rsp),%xmm11
+	movaps	0x60(%rsp),%xmm12
+	movaps	0x70(%rsp),%xmm13
+	movaps	0x80(%rsp),%xmm14
+	movaps	0x90(%rsp),%xmm15
+	add	\$0xa8,%rsp
+___
+$code.=<<___;
 	ret
+.LSEH_end_rsaz_512_gather4:
 .size	rsaz_512_gather4,.-rsaz_512_gather4
+
+.align	64
+.Linc:
+	.long	0,0, 1,1
+	.long	2,2, 2,2
 ___
 }
 
@@ -2026,6 +2204,18 @@
 
 	lea	128+24+48(%rax),%rax
 
+	lea	.Lmul_gather4_epilogue(%rip),%rbx
+	cmp	%r10,%rbx
+	jne	.Lse_not_in_mul_gather4
+
+	lea	0xb0(%rax),%rax
+
+	lea	-48-0xa8(%rax),%rsi
+	lea	512($context),%rdi
+	mov	\$20,%ecx
+	.long	0xa548f3fc		# cld; rep movsq
+
+.Lse_not_in_mul_gather4:
 	mov	-8(%rax),%rbx
 	mov	-16(%rax),%rbp
 	mov	-24(%rax),%r12
@@ -2077,7 +2267,7 @@
 	pop	%rdi
 	pop	%rsi
 	ret
-.size	sqr_handler,.-sqr_handler
+.size	se_handler,.-se_handler
 
 .section	.pdata
 .align	4
@@ -2101,6 +2291,10 @@
 	.rva	.LSEH_end_rsaz_512_mul_by_one
 	.rva	.LSEH_info_rsaz_512_mul_by_one
 
+	.rva	.LSEH_begin_rsaz_512_gather4
+	.rva	.LSEH_end_rsaz_512_gather4
+	.rva	.LSEH_info_rsaz_512_gather4
+
 .section	.xdata
 .align	8
 .LSEH_info_rsaz_512_sqr:
@@ -2123,6 +2317,19 @@
 	.byte	9,0,0,0
 	.rva	se_handler
 	.rva	.Lmul_by_one_body,.Lmul_by_one_epilogue		# HandlerData[]
+.LSEH_info_rsaz_512_gather4:
+	.byte	0x01,0x46,0x16,0x00
+	.byte	0x46,0xf8,0x09,0x00	# vmovaps 0x90(rsp),xmm15
+	.byte	0x3d,0xe8,0x08,0x00	# vmovaps 0x80(rsp),xmm14
+	.byte	0x34,0xd8,0x07,0x00	# vmovaps 0x70(rsp),xmm13
+	.byte	0x2e,0xc8,0x06,0x00	# vmovaps 0x60(rsp),xmm12
+	.byte	0x28,0xb8,0x05,0x00	# vmovaps 0x50(rsp),xmm11
+	.byte	0x22,0xa8,0x04,0x00	# vmovaps 0x40(rsp),xmm10
+	.byte	0x1c,0x98,0x03,0x00	# vmovaps 0x30(rsp),xmm9
+	.byte	0x16,0x88,0x02,0x00	# vmovaps 0x20(rsp),xmm8
+	.byte	0x10,0x78,0x01,0x00	# vmovaps 0x10(rsp),xmm7
+	.byte	0x0b,0x68,0x00,0x00	# vmovaps 0x00(rsp),xmm6
+	.byte	0x07,0x01,0x15,0x00	# sub     rsp,0xa8
 ___
 }
 
diff --git a/src/crypto/bn/asm/x86_64-gcc.c b/src/crypto/bn/asm/x86_64-gcc.c
index 0496b95..214c12a 100644
--- a/src/crypto/bn/asm/x86_64-gcc.c
+++ b/src/crypto/bn/asm/x86_64-gcc.c
@@ -1,9 +1,3 @@
-#include <openssl/bn.h>
-
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS)
-
-#include "../internal.h"
-
 /* x86_64 BIGNUM accelerator version 0.1, December 2002.
  *
  * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
@@ -56,7 +50,13 @@
  *    machine.
  */
 
- /* TODO(davidben): Get this file working on Windows x64. */
+#include <openssl/bn.h>
+
+/* TODO(davidben): Get this file working on Windows x64. */
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
+
+#include "../internal.h"
+
 
 #undef mul
 #undef mul_add
@@ -186,14 +186,6 @@
   }
 }
 
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
-  BN_ULONG ret, waste;
-
-  asm("divq	%4" : "=a"(ret), "=d"(waste) : "a"(l), "d"(h), "g"(d) : "cc");
-
-  return ret;
-}
-
 BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                       int n) {
   BN_ULONG ret;
@@ -220,7 +212,6 @@
   return ret & 1;
 }
 
-#ifndef SIMICS
 BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                       int n) {
   BN_ULONG ret;
@@ -246,65 +237,6 @@
 
   return ret & 1;
 }
-#else
-/* Simics 1.4<7 has buggy sbbq:-( */
-#define BN_MASK2 0xffffffffffffffffL
-BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
-  BN_ULONG t1, t2;
-  int c = 0;
-
-  if (n <= 0) {
-    return (BN_ULONG)0;
-  }
-
-  for (;;) {
-    t1 = a[0];
-    t2 = b[0];
-    r[0] = (t1 - t2 - c) & BN_MASK2;
-    if (t1 != t2) {
-      c = (t1 < t2);
-    }
-    if (--n <= 0) {
-      break;
-    }
-
-    t1 = a[1];
-    t2 = b[1];
-    r[1] = (t1 - t2 - c) & BN_MASK2;
-    if (t1 != t2) {
-      c = (t1 < t2);
-    }
-    if (--n <= 0) {
-      break;
-    }
-
-    t1 = a[2];
-    t2 = b[2];
-    r[2] = (t1 - t2 - c) & BN_MASK2;
-    if (t1 != t2) {
-      c = (t1 < t2);
-    }
-    if (--n <= 0) {
-      break;
-    }
-
-    t1 = a[3];
-    t2 = b[3];
-    r[3] = (t1 - t2 - c) & BN_MASK2;
-    if (t1 != t2) {
-      c = (t1 < t2);
-    }
-    if (--n <= 0) {
-      break;
-    }
-
-    a += 4;
-    b += 4;
-    r += 4;
-  }
-  return c;
-}
-#endif
 
 /* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
 /* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
@@ -596,4 +528,4 @@
   r[7] = c2;
 }
 
-#endif  /* !NO_ASM && X86_64 && !WINDOWS */
+#endif  /* !NO_ASM && X86_64 && __GNUC__ */
diff --git a/src/crypto/bn/asm/x86_64-mont.pl b/src/crypto/bn/asm/x86_64-mont.pl
old mode 100644
new mode 100755
index 04c4bea..1ca2b1e
--- a/src/crypto/bn/asm/x86_64-mont.pl
+++ b/src/crypto/bn/asm/x86_64-mont.pl
@@ -761,100 +761,126 @@
 	# 4096. this is done to allow memory disambiguation logic
 	# do its job.
 	#
-	lea	-64(%rsp,$num,4),%r11
+	lea	-64(%rsp,$num,2),%r11
 	mov	($n0),$n0		# *n0
 	sub	$aptr,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lsqr8x_sp_alt
 	sub	%r11,%rsp		# align with $aptr
-	lea	-64(%rsp,$num,4),%rsp	# alloca(frame+4*$num)
+	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
 	jmp	.Lsqr8x_sp_done
 
 .align	32
 .Lsqr8x_sp_alt:
-	lea	4096-64(,$num,4),%r10	# 4096-frame-4*$num
-	lea	-64(%rsp,$num,4),%rsp	# alloca(frame+4*$num)
+	lea	4096-64(,$num,2),%r10	# 4096-frame-2*$num
+	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
 	sub	%r11,%rsp
 .Lsqr8x_sp_done:
 	and	\$-64,%rsp
-	mov	$num,%r10	
+	mov	$num,%r10
 	neg	$num
 
-	lea	64(%rsp,$num,2),%r11	# copy of modulus
 	mov	$n0,  32(%rsp)
 	mov	%rax, 40(%rsp)		# save original %rsp
 .Lsqr8x_body:
 
-	mov	$num,$i
-	movq	%r11, %xmm2		# save pointer to modulus copy
-	shr	\$3+2,$i
-	mov	OPENSSL_ia32cap_P+8(%rip),%eax
-	jmp	.Lsqr8x_copy_n
-
-.align	32
-.Lsqr8x_copy_n:
-	movq	8*0($nptr),%xmm0
-	movq	8*1($nptr),%xmm1
-	movq	8*2($nptr),%xmm3
-	movq	8*3($nptr),%xmm4
-	lea	8*4($nptr),$nptr
-	movdqa	%xmm0,16*0(%r11)
-	movdqa	%xmm1,16*1(%r11)
-	movdqa	%xmm3,16*2(%r11)
-	movdqa	%xmm4,16*3(%r11)
-	lea	16*4(%r11),%r11
-	dec	$i
-	jnz	.Lsqr8x_copy_n
-
+	movq	$nptr, %xmm2		# save pointer to modulus
 	pxor	%xmm0,%xmm0
 	movq	$rptr,%xmm1		# save $rptr
 	movq	%r10, %xmm3		# -$num
 ___
 $code.=<<___ if ($addx);
+	mov	OPENSSL_ia32cap_P+8(%rip),%eax
 	and	\$0x80100,%eax
 	cmp	\$0x80100,%eax
 	jne	.Lsqr8x_nox
 
 	call	bn_sqrx8x_internal	# see x86_64-mont5 module
-
-	pxor	%xmm0,%xmm0
-	lea	48(%rsp),%rax
-	lea	64(%rsp,$num,2),%rdx
-	shr	\$3+2,$num
-	mov	40(%rsp),%rsi		# restore %rsp
-	jmp	.Lsqr8x_zero
+					# %rax	top-most carry
+					# %rbp	nptr
+					# %rcx	-8*num
+					# %r8	end of tp[2*num]
+	lea	(%r8,%rcx),%rbx
+	mov	%rcx,$num
+	mov	%rcx,%rdx
+	movq	%xmm1,$rptr
+	sar	\$3+2,%rcx		# %cf=0
+	jmp	.Lsqr8x_sub
 
 .align	32
 .Lsqr8x_nox:
 ___
 $code.=<<___;
 	call	bn_sqr8x_internal	# see x86_64-mont5 module
-
-	pxor	%xmm0,%xmm0
-	lea	48(%rsp),%rax
-	lea	64(%rsp,$num,2),%rdx
-	shr	\$3+2,$num
-	mov	40(%rsp),%rsi		# restore %rsp
-	jmp	.Lsqr8x_zero
+					# %rax	top-most carry
+					# %rbp	nptr
+					# %r8	-8*num
+					# %rdi	end of tp[2*num]
+	lea	(%rdi,$num),%rbx
+	mov	$num,%rcx
+	mov	$num,%rdx
+	movq	%xmm1,$rptr
+	sar	\$3+2,%rcx		# %cf=0
+	jmp	.Lsqr8x_sub
 
 .align	32
-.Lsqr8x_zero:
-	movdqa	%xmm0,16*0(%rax)	# wipe t
-	movdqa	%xmm0,16*1(%rax)
-	movdqa	%xmm0,16*2(%rax)
-	movdqa	%xmm0,16*3(%rax)
-	lea	16*4(%rax),%rax
-	movdqa	%xmm0,16*0(%rdx)	# wipe n
-	movdqa	%xmm0,16*1(%rdx)
-	movdqa	%xmm0,16*2(%rdx)
-	movdqa	%xmm0,16*3(%rdx)
-	lea	16*4(%rdx),%rdx
-	dec	$num
-	jnz	.Lsqr8x_zero
+.Lsqr8x_sub:
+	mov	8*0(%rbx),%r12
+	mov	8*1(%rbx),%r13
+	mov	8*2(%rbx),%r14
+	mov	8*3(%rbx),%r15
+	lea	8*4(%rbx),%rbx
+	sbb	8*0(%rbp),%r12
+	sbb	8*1(%rbp),%r13
+	sbb	8*2(%rbp),%r14
+	sbb	8*3(%rbp),%r15
+	lea	8*4(%rbp),%rbp
+	mov	%r12,8*0($rptr)
+	mov	%r13,8*1($rptr)
+	mov	%r14,8*2($rptr)
+	mov	%r15,8*3($rptr)
+	lea	8*4($rptr),$rptr
+	inc	%rcx			# preserves %cf
+	jnz	.Lsqr8x_sub
+
+	sbb	\$0,%rax		# top-most carry
+	lea	(%rbx,$num),%rbx	# rewind
+	lea	($rptr,$num),$rptr	# rewind
+
+	movq	%rax,%xmm1
+	pxor	%xmm0,%xmm0
+	pshufd	\$0,%xmm1,%xmm1
+	mov	40(%rsp),%rsi		# restore %rsp
+	jmp	.Lsqr8x_cond_copy
+
+.align	32
+.Lsqr8x_cond_copy:
+	movdqa	16*0(%rbx),%xmm2
+	movdqa	16*1(%rbx),%xmm3
+	lea	16*2(%rbx),%rbx
+	movdqu	16*0($rptr),%xmm4
+	movdqu	16*1($rptr),%xmm5
+	lea	16*2($rptr),$rptr
+	movdqa	%xmm0,-16*2(%rbx)	# zero tp
+	movdqa	%xmm0,-16*1(%rbx)
+	movdqa	%xmm0,-16*2(%rbx,%rdx)
+	movdqa	%xmm0,-16*1(%rbx,%rdx)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-16*2($rptr)
+	movdqu	%xmm5,-16*1($rptr)
+	add	\$32,$num
+	jnz	.Lsqr8x_cond_copy
 
 	mov	\$1,%rax
 	mov	-48(%rsi),%r15
@@ -1121,64 +1147,75 @@
 	adc	$zero,%r15		# modulo-scheduled
 	sub	0*8($tptr),$zero	# pull top-most carry
 	adc	%r15,%r14
-	mov	-8($nptr),$mi
 	sbb	%r15,%r15		# top-most carry
 	mov	%r14,-1*8($tptr)
 
 	cmp	16(%rsp),$bptr
 	jne	.Lmulx4x_outer
 
-	sub	%r14,$mi		# compare top-most words
-	sbb	$mi,$mi
-	or	$mi,%r15
-
-	neg	$num
-	xor	%rdx,%rdx
-	mov	32(%rsp),$rptr		# restore rp
 	lea	64(%rsp),$tptr
-
-	pxor	%xmm0,%xmm0
-	mov	0*8($nptr,$num),%r8
-	mov	1*8($nptr,$num),%r9
-	neg	%r8
-	jmp	.Lmulx4x_sub_entry
+	sub	$num,$nptr		# rewind $nptr
+	neg	%r15
+	mov	$num,%rdx
+	shr	\$3+2,$num		# %cf=0
+	mov	32(%rsp),$rptr		# restore rp
+	jmp	.Lmulx4x_sub
 
 .align	32
 .Lmulx4x_sub:
-	mov	0*8($nptr,$num),%r8
-	mov	1*8($nptr,$num),%r9
-	not	%r8
-.Lmulx4x_sub_entry:
-	mov	2*8($nptr,$num),%r10
-	not	%r9
-	and	%r15,%r8
-	mov	3*8($nptr,$num),%r11
-	not	%r10
-	and	%r15,%r9
-	not	%r11
-	and	%r15,%r10
-	and	%r15,%r11
-
-	neg	%rdx			# mov %rdx,%cf
-	adc	0*8($tptr),%r8
-	adc	1*8($tptr),%r9
-	movdqa	%xmm0,($tptr)
-	adc	2*8($tptr),%r10
-	adc	3*8($tptr),%r11
-	movdqa	%xmm0,16($tptr)
-	lea	4*8($tptr),$tptr
-	sbb	%rdx,%rdx		# mov %cf,%rdx
-
-	mov	%r8,0*8($rptr)
-	mov	%r9,1*8($rptr)
-	mov	%r10,2*8($rptr)
-	mov	%r11,3*8($rptr)
-	lea	4*8($rptr),$rptr
-
-	add	\$32,$num
+	mov	8*0($tptr),%r11
+	mov	8*1($tptr),%r12
+	mov	8*2($tptr),%r13
+	mov	8*3($tptr),%r14
+	lea	8*4($tptr),$tptr
+	sbb	8*0($nptr),%r11
+	sbb	8*1($nptr),%r12
+	sbb	8*2($nptr),%r13
+	sbb	8*3($nptr),%r14
+	lea	8*4($nptr),$nptr
+	mov	%r11,8*0($rptr)
+	mov	%r12,8*1($rptr)
+	mov	%r13,8*2($rptr)
+	mov	%r14,8*3($rptr)
+	lea	8*4($rptr),$rptr
+	dec	$num			# preserves %cf
 	jnz	.Lmulx4x_sub
 
+	sbb	\$0,%r15		# top-most carry
+	lea	64(%rsp),$tptr
+	sub	%rdx,$rptr		# rewind
+
+	movq	%r15,%xmm1
+	pxor	%xmm0,%xmm0
+	pshufd	\$0,%xmm1,%xmm1
 	mov	40(%rsp),%rsi		# restore %rsp
+	jmp	.Lmulx4x_cond_copy
+
+.align	32
+.Lmulx4x_cond_copy:
+	movdqa	16*0($tptr),%xmm2
+	movdqa	16*1($tptr),%xmm3
+	lea	16*2($tptr),$tptr
+	movdqu	16*0($rptr),%xmm4
+	movdqu	16*1($rptr),%xmm5
+	lea	16*2($rptr),$rptr
+	movdqa	%xmm0,-16*2($tptr)	# zero tp
+	movdqa	%xmm0,-16*1($tptr)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-16*2($rptr)
+	movdqu	%xmm5,-16*1($rptr)
+	sub	\$32,%rdx
+	jnz	.Lmulx4x_cond_copy
+
+	mov	%rdx,($tptr)
+
 	mov	\$1,%rax
 	mov	-48(%rsi),%r15
 	mov	-40(%rsi),%r14
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
old mode 100644
new mode 100755
index 3c5a8fc..ced3acb
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -86,58 +86,111 @@
 .Lmul_enter:
 	mov	${num}d,${num}d
 	mov	%rsp,%rax
-	mov	`($win64?56:8)`(%rsp),%r10d	# load 7th argument
+	movd	`($win64?56:8)`(%rsp),%xmm5	# load 7th argument
+	lea	.Linc(%rip),%r10
 	push	%rbx
 	push	%rbp
 	push	%r12
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
+
 	lea	2($num),%r11
 	neg	%r11
-	lea	(%rsp,%r11,8),%rsp	# tp=alloca(8*(num+2))
+	lea	-264(%rsp,%r11,8),%rsp	# tp=alloca(8*(num+2)+256+8)
 	and	\$-1024,%rsp		# minimize TLB usage
 
 	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
 .Lmul_body:
-	mov	$bp,%r12		# reassign $bp
+	lea	128($bp),%r12		# reassign $bp (+size optimization)
 ___
 		$bp="%r12";
 		$STRIDE=2**5*8;		# 5 is "window size"
 		$N=$STRIDE/4;		# should match cache line size
 $code.=<<___;
-	mov	%r10,%r11
-	shr	\$`log($N/8)/log(2)`,%r10
-	and	\$`$N/8-1`,%r11
-	not	%r10
-	lea	.Lmagic_masks(%rip),%rax
-	and	\$`2**5/($N/8)-1`,%r10	# 5 is "window size"
-	lea	96($bp,%r11,8),$bp	# pointer within 1st cache line
-	movq	0(%rax,%r10,8),%xmm4	# set of masks denoting which
-	movq	8(%rax,%r10,8),%xmm5	# cache line contains element
-	movq	16(%rax,%r10,8),%xmm6	# denoted by 7th argument
-	movq	24(%rax,%r10,8),%xmm7
+	movdqa	0(%r10),%xmm0		# 00000001000000010000000000000000
+	movdqa	16(%r10),%xmm1		# 00000002000000020000000200000002
+	lea	24-112(%rsp,$num,8),%r10# place the mask after tp[num+3] (+ICache optimization)
+	and	\$-16,%r10
 
-	movq	`0*$STRIDE/4-96`($bp),%xmm0
-	movq	`1*$STRIDE/4-96`($bp),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bp),%xmm2
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-96`($bp),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
+	.byte	0x67
+	movdqa	%xmm4,%xmm3
+___
+for($k=0;$k<$STRIDE/16-4;$k+=4) {
+$code.=<<___;
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
+	movdqa	%xmm0,`16*($k+0)+112`(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
+	movdqa	%xmm1,`16*($k+1)+112`(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
+	movdqa	%xmm2,`16*($k+2)+112`(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,`16*($k+3)+112`(%r10)
+	movdqa	%xmm4,%xmm3
+___
+}
+$code.=<<___;				# last iteration can be optimized
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,`16*($k+0)+112`(%r10)
+
+	paddd	%xmm2,%xmm3
+	.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,`16*($k+1)+112`(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,`16*($k+2)+112`(%r10)
+	pand	`16*($k+0)-128`($bp),%xmm0	# while it's still in register
+
+	pand	`16*($k+1)-128`($bp),%xmm1
+	pand	`16*($k+2)-128`($bp),%xmm2
+	movdqa	%xmm3,`16*($k+3)+112`(%r10)
+	pand	`16*($k+3)-128`($bp),%xmm3
 	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+___
+for($k=0;$k<$STRIDE/16-4;$k+=4) {
+$code.=<<___;
+	movdqa	`16*($k+0)-128`($bp),%xmm4
+	movdqa	`16*($k+1)-128`($bp),%xmm5
+	movdqa	`16*($k+2)-128`($bp),%xmm2
+	pand	`16*($k+0)+112`(%r10),%xmm4
+	movdqa	`16*($k+3)-128`($bp),%xmm3
+	pand	`16*($k+1)+112`(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	`16*($k+2)+112`(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	`16*($k+3)+112`(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+___
+}
+$code.=<<___;
+	por	%xmm1,%xmm0
+	pshufd	\$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
 	lea	$STRIDE($bp),$bp
-	por	%xmm3,%xmm0
-
 	movq	%xmm0,$m0		# m0=bp[0]
 
 	mov	($n0),$n0		# pull n0[0] value
@@ -146,29 +199,14 @@
 	xor	$i,$i			# i=0
 	xor	$j,$j			# j=0
 
-	movq	`0*$STRIDE/4-96`($bp),%xmm0
-	movq	`1*$STRIDE/4-96`($bp),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bp),%xmm2
-	pand	%xmm5,%xmm1
-
 	mov	$n0,$m1
 	mulq	$m0			# ap[0]*bp[0]
 	mov	%rax,$lo0
 	mov	($np),%rax
 
-	movq	`3*$STRIDE/4-96`($bp),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	$lo0,$m1		# "tp[0]"*n0
 	mov	%rdx,$hi0
 
-	por	%xmm2,%xmm0
-	lea	$STRIDE($bp),$bp
-	por	%xmm3,%xmm0
-
 	mulq	$m1			# np[0]*m1
 	add	%rax,$lo0		# discarded
 	mov	8($ap),%rax
@@ -199,16 +237,14 @@
 
 	mulq	$m1			# np[j]*m1
 	cmp	$num,$j
-	jne	.L1st
-
-	movq	%xmm0,$m0		# bp[1]
+	jne	.L1st			# note that upon exit $j==$num, so
+					# they can be used interchangeably
 
 	add	%rax,$hi1
-	mov	($ap),%rax		# ap[0]
 	adc	\$0,%rdx
 	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
 	adc	\$0,%rdx
-	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
+	mov	$hi1,-16(%rsp,$num,8)	# tp[num-1]
 	mov	%rdx,$hi1
 	mov	$lo0,$hi0
 
@@ -222,33 +258,48 @@
 	jmp	.Louter
 .align	16
 .Louter:
+	lea	24+128(%rsp,$num,8),%rdx	# where 256-byte mask is (+size optimization)
+	and	\$-16,%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+___
+for($k=0;$k<$STRIDE/16;$k+=4) {
+$code.=<<___;
+	movdqa	`16*($k+0)-128`($bp),%xmm0
+	movdqa	`16*($k+1)-128`($bp),%xmm1
+	movdqa	`16*($k+2)-128`($bp),%xmm2
+	movdqa	`16*($k+3)-128`($bp),%xmm3
+	pand	`16*($k+0)-128`(%rdx),%xmm0
+	pand	`16*($k+1)-128`(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	`16*($k+2)-128`(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	`16*($k+3)-128`(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+___
+}
+$code.=<<___;
+	por	%xmm5,%xmm4
+	pshufd	\$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	lea	$STRIDE($bp),$bp
+
+	mov	($ap),%rax		# ap[0]
+	movq	%xmm0,$m0		# m0=bp[i]
+
 	xor	$j,$j			# j=0
 	mov	$n0,$m1
 	mov	(%rsp),$lo0
 
-	movq	`0*$STRIDE/4-96`($bp),%xmm0
-	movq	`1*$STRIDE/4-96`($bp),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bp),%xmm2
-	pand	%xmm5,%xmm1
-
 	mulq	$m0			# ap[0]*bp[i]
 	add	%rax,$lo0		# ap[0]*bp[i]+tp[0]
 	mov	($np),%rax
 	adc	\$0,%rdx
 
-	movq	`3*$STRIDE/4-96`($bp),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	$lo0,$m1		# tp[0]*n0
 	mov	%rdx,$hi0
 
-	por	%xmm2,%xmm0
-	lea	$STRIDE($bp),$bp
-	por	%xmm3,%xmm0
-
 	mulq	$m1			# np[0]*m1
 	add	%rax,$lo0		# discarded
 	mov	8($ap),%rax
@@ -282,17 +333,14 @@
 
 	mulq	$m1			# np[j]*m1
 	cmp	$num,$j
-	jne	.Linner
-
-	movq	%xmm0,$m0		# bp[i+1]
-
+	jne	.Linner			# note that upon exit $j==$num, so
+					# they can be used interchangeably
 	add	%rax,$hi1
-	mov	($ap),%rax		# ap[0]
 	adc	\$0,%rdx
 	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
-	mov	(%rsp,$j,8),$lo0
+	mov	(%rsp,$num,8),$lo0
 	adc	\$0,%rdx
-	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
+	mov	$hi1,-16(%rsp,$num,8)	# tp[num-1]
 	mov	%rdx,$hi1
 
 	xor	%rdx,%rdx
@@ -338,12 +386,7 @@
 
 	mov	8(%rsp,$num,8),%rsi	# restore %rsp
 	mov	\$1,%rax
-___
-$code.=<<___ if ($win64);
-	movaps	-88(%rsi),%xmm6
-	movaps	-72(%rsi),%xmm7
-___
-$code.=<<___;
+
 	mov	-48(%rsi),%r15
 	mov	-40(%rsi),%r14
 	mov	-32(%rsi),%r13
@@ -365,8 +408,8 @@
 .Lmul4x_enter:
 ___
 $code.=<<___ if ($addx);
-	and	\$0x80100,%r11d
-	cmp	\$0x80100,%r11d
+	and	\$0x80108,%r11d
+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
 	je	.Lmulx4x_enter
 ___
 $code.=<<___;
@@ -378,39 +421,34 @@
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
+
 	.byte	0x67
-	mov	${num}d,%r10d
-	shl	\$3,${num}d
-	shl	\$3+2,%r10d		# 4*$num
+	shl	\$3,${num}d		# convert $num to bytes
+	lea	($num,$num,2),%r10	# 3*$num in bytes
 	neg	$num			# -$num
 
 	##############################################################
-	# ensure that stack frame doesn't alias with $aptr+4*$num
-	# modulo 4096, which covers ret[num], am[num] and n[2*num]
-	# (see bn_exp.c). this is done to allow memory disambiguation
-	# logic do its magic. [excessive frame is allocated in order
-	# to allow bn_from_mont8x to clear it.]
+	# Ensure that stack frame doesn't alias with $rptr+3*$num
+	# modulo 4096, which covers ret[num], am[num] and n[num]
+	# (see bn_exp.c). This is done to allow memory disambiguation
+	# logic do its magic. [Extra [num] is allocated in order
+	# to align with bn_power5's frame, which is cleansed after
+	# completing exponentiation. Extra 256 bytes is for power mask
+	# calculated from 7th argument, the index.]
 	#
-	lea	-64(%rsp,$num,2),%r11
-	sub	$ap,%r11
+	lea	-320(%rsp,$num,2),%r11
+	sub	$rp,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lmul4xsp_alt
-	sub	%r11,%rsp		# align with $ap
-	lea	-64(%rsp,$num,2),%rsp	# alloca(128+num*8)
+	sub	%r11,%rsp		# align with $rp
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*num*8+256)
 	jmp	.Lmul4xsp_done
 
 .align	32
 .Lmul4xsp_alt:
-	lea	4096-64(,$num,2),%r10
-	lea	-64(%rsp,$num,2),%rsp	# alloca(128+num*8)
+	lea	4096-320(,$num,2),%r10
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*num*8+256)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
@@ -426,12 +464,7 @@
 
 	mov	40(%rsp),%rsi		# restore %rsp
 	mov	\$1,%rax
-___
-$code.=<<___ if ($win64);
-	movaps	-88(%rsi),%xmm6
-	movaps	-72(%rsi),%xmm7
-___
-$code.=<<___;
+
 	mov	-48(%rsi),%r15
 	mov	-40(%rsi),%r14
 	mov	-32(%rsi),%r13
@@ -446,9 +479,10 @@
 .type	mul4x_internal,\@abi-omnipotent
 .align	32
 mul4x_internal:
-	shl	\$5,$num
-	mov	`($win64?56:8)`(%rax),%r10d	# load 7th argument
-	lea	256(%rdx,$num),%r13
+	shl	\$5,$num		# $num was in bytes
+	movd	`($win64?56:8)`(%rax),%xmm5	# load 7th argument, index
+	lea	.Linc(%rip),%rax
+	lea	128(%rdx,$num),%r13	# end of powers table (+size optimization)
 	shr	\$5,$num		# restore $num
 ___
 		$bp="%r12";
@@ -456,44 +490,92 @@
 		$N=$STRIDE/4;		# should match cache line size
 		$tp=$i;
 $code.=<<___;
-	mov	%r10,%r11
-	shr	\$`log($N/8)/log(2)`,%r10
-	and	\$`$N/8-1`,%r11
-	not	%r10
-	lea	.Lmagic_masks(%rip),%rax
-	and	\$`2**5/($N/8)-1`,%r10	# 5 is "window size"
-	lea	96(%rdx,%r11,8),$bp	# pointer within 1st cache line
-	movq	0(%rax,%r10,8),%xmm4	# set of masks denoting which
-	movq	8(%rax,%r10,8),%xmm5	# cache line contains element
-	add	\$7,%r11
-	movq	16(%rax,%r10,8),%xmm6	# denoted by 7th argument
-	movq	24(%rax,%r10,8),%xmm7
-	and	\$7,%r11
+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
+	lea	88-112(%rsp,$num),%r10	# place the mask after tp[num+1] (+ICache optimization)
+	lea	128(%rdx),$bp		# size optimization
 
-	movq	`0*$STRIDE/4-96`($bp),%xmm0
-	lea	$STRIDE($bp),$tp	# borrow $tp
-	movq	`1*$STRIDE/4-96`($bp),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bp),%xmm2
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-96`($bp),%xmm3
-	pand	%xmm6,%xmm2
+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
+	movdqa	%xmm1,%xmm4
+	.byte	0x67,0x67
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
 	.byte	0x67
-	por	%xmm1,%xmm0
-	movq	`0*$STRIDE/4-96`($tp),%xmm1
+	movdqa	%xmm4,%xmm3
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
+	movdqa	%xmm4,%xmm3
+___
+}
+$code.=<<___;				# last iteration can be optimized
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
+
+	paddd	%xmm2,%xmm3
 	.byte	0x67
-	pand	%xmm7,%xmm3
-	.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
+	pand	`16*($i+0)-128`($bp),%xmm0	# while it's still in register
+
+	pand	`16*($i+1)-128`($bp),%xmm1
+	pand	`16*($i+2)-128`($bp),%xmm2
+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
+	pand	`16*($i+3)-128`($bp),%xmm3
 	por	%xmm2,%xmm0
-	movq	`1*$STRIDE/4-96`($tp),%xmm2
-	.byte	0x67
-	pand	%xmm4,%xmm1
-	.byte	0x67
-	por	%xmm3,%xmm0
-	movq	`2*$STRIDE/4-96`($tp),%xmm3
-
+	por	%xmm3,%xmm1
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+	movdqa	`16*($i+0)-128`($bp),%xmm4
+	movdqa	`16*($i+1)-128`($bp),%xmm5
+	movdqa	`16*($i+2)-128`($bp),%xmm2
+	pand	`16*($i+0)+112`(%r10),%xmm4
+	movdqa	`16*($i+3)-128`($bp),%xmm3
+	pand	`16*($i+1)+112`(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	`16*($i+2)+112`(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	`16*($i+3)+112`(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+___
+}
+$code.=<<___;
+	por	%xmm1,%xmm0
+	pshufd	\$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	lea	$STRIDE($bp),$bp
 	movq	%xmm0,$m0		# m0=bp[0]
-	movq	`3*$STRIDE/4-96`($tp),%xmm0
+
 	mov	%r13,16+8(%rsp)		# save end of b[num]
 	mov	$rp, 56+8(%rsp)		# save $rp
 
@@ -507,26 +589,10 @@
 	mov	%rax,$A[0]
 	mov	($np),%rax
 
-	pand	%xmm5,%xmm2
-	pand	%xmm6,%xmm3
-	por	%xmm2,%xmm1
-
 	imulq	$A[0],$m1		# "tp[0]"*n0
-	##############################################################
-	# $tp is chosen so that writing to top-most element of the
-	# vector occurs just "above" references to powers table,
-	# "above" modulo cache-line size, which effectively precludes
-	# possibility of memory disambiguation logic failure when
-	# accessing the table.
-	# 
-	lea	64+8(%rsp,%r11,8),$tp
+	lea	64+8(%rsp),$tp
 	mov	%rdx,$A[1]
 
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
-	lea	2*$STRIDE($bp),$bp
-	por	%xmm1,%xmm0
-
 	mulq	$m1			# np[0]*m1
 	add	%rax,$A[0]		# discarded
 	mov	8($ap,$num),%rax
@@ -535,7 +601,7 @@
 
 	mulq	$m0
 	add	%rax,$A[1]
-	mov	16*1($np),%rax		# interleaved with 0, therefore 16*n
+	mov	8*1($np),%rax
 	adc	\$0,%rdx
 	mov	%rdx,$A[0]
 
@@ -545,7 +611,7 @@
 	adc	\$0,%rdx
 	add	$A[1],$N[1]
 	lea	4*8($num),$j		# j=4
-	lea	16*4($np),$np
+	lea	8*4($np),$np
 	adc	\$0,%rdx
 	mov	$N[1],($tp)
 	mov	%rdx,$N[0]
@@ -555,7 +621,7 @@
 .L1st4x:
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[0]
-	mov	-16*2($np),%rax
+	mov	-8*2($np),%rax
 	lea	32($tp),$tp
 	adc	\$0,%rdx
 	mov	%rdx,$A[1]
@@ -571,7 +637,7 @@
 
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[1]
-	mov	-16*1($np),%rax
+	mov	-8*1($np),%rax
 	adc	\$0,%rdx
 	mov	%rdx,$A[0]
 
@@ -586,7 +652,7 @@
 
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[0]
-	mov	16*0($np),%rax
+	mov	8*0($np),%rax
 	adc	\$0,%rdx
 	mov	%rdx,$A[1]
 
@@ -601,7 +667,7 @@
 
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[1]
-	mov	16*1($np),%rax
+	mov	8*1($np),%rax
 	adc	\$0,%rdx
 	mov	%rdx,$A[0]
 
@@ -610,7 +676,7 @@
 	mov	16($ap,$j),%rax
 	adc	\$0,%rdx
 	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-	lea	16*4($np),$np
+	lea	8*4($np),$np
 	adc	\$0,%rdx
 	mov	$N[1],($tp)		# tp[j-1]
 	mov	%rdx,$N[0]
@@ -620,7 +686,7 @@
 
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[0]
-	mov	-16*2($np),%rax
+	mov	-8*2($np),%rax
 	lea	32($tp),$tp
 	adc	\$0,%rdx
 	mov	%rdx,$A[1]
@@ -636,7 +702,7 @@
 
 	mulq	$m0			# ap[j]*bp[0]
 	add	%rax,$A[1]
-	mov	-16*1($np),%rax
+	mov	-8*1($np),%rax
 	adc	\$0,%rdx
 	mov	%rdx,$A[0]
 
@@ -649,8 +715,7 @@
 	mov	$N[1],-16($tp)		# tp[j-1]
 	mov	%rdx,$N[0]
 
-	movq	%xmm0,$m0		# bp[1]
-	lea	($np,$num,2),$np	# rewind $np
+	lea	($np,$num),$np		# rewind $np
 
 	xor	$N[1],$N[1]
 	add	$A[0],$N[0]
@@ -661,6 +726,33 @@
 
 .align	32
 .Louter4x:
+	lea	16+128($tp),%rdx	# where 256-byte mask is (+size optimization)
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+	movdqa	`16*($i+0)-128`($bp),%xmm0
+	movdqa	`16*($i+1)-128`($bp),%xmm1
+	movdqa	`16*($i+2)-128`($bp),%xmm2
+	movdqa	`16*($i+3)-128`($bp),%xmm3
+	pand	`16*($i+0)-128`(%rdx),%xmm0
+	pand	`16*($i+1)-128`(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	`16*($i+2)-128`(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	`16*($i+3)-128`(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+___
+}
+$code.=<<___;
+	por	%xmm5,%xmm4
+	pshufd	\$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	lea	$STRIDE($bp),$bp
+	movq	%xmm0,$m0		# m0=bp[i]
+
 	mov	($tp,$num),$A[0]
 	mov	$n0,$m1
 	mulq	$m0			# ap[0]*bp[i]
@@ -668,25 +760,11 @@
 	mov	($np),%rax
 	adc	\$0,%rdx
 
-	movq	`0*$STRIDE/4-96`($bp),%xmm0
-	movq	`1*$STRIDE/4-96`($bp),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bp),%xmm2
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-96`($bp),%xmm3
-
 	imulq	$A[0],$m1		# tp[0]*n0
-	.byte	0x67
 	mov	%rdx,$A[1]
 	mov	$N[1],($tp)		# store upmost overflow bit
 
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	por	%xmm2,%xmm0
 	lea	($tp,$num),$tp		# rewind $tp
-	lea	$STRIDE($bp),$bp
-	por	%xmm3,%xmm0
 
 	mulq	$m1			# np[0]*m1
 	add	%rax,$A[0]		# "$N[0]", discarded
@@ -696,7 +774,7 @@
 
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[1]
-	mov	16*1($np),%rax		# interleaved with 0, therefore 16*n
+	mov	8*1($np),%rax
 	adc	\$0,%rdx
 	add	8($tp),$A[1]		# +tp[1]
 	adc	\$0,%rdx
@@ -708,7 +786,7 @@
 	adc	\$0,%rdx
 	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[i]+tp[j]
 	lea	4*8($num),$j		# j=4
-	lea	16*4($np),$np
+	lea	8*4($np),$np
 	adc	\$0,%rdx
 	mov	%rdx,$N[0]
 	jmp	.Linner4x
@@ -717,7 +795,7 @@
 .Linner4x:
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[0]
-	mov	-16*2($np),%rax
+	mov	-8*2($np),%rax
 	adc	\$0,%rdx
 	add	16($tp),$A[0]		# ap[j]*bp[i]+tp[j]
 	lea	32($tp),$tp
@@ -735,7 +813,7 @@
 
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[1]
-	mov	-16*1($np),%rax
+	mov	-8*1($np),%rax
 	adc	\$0,%rdx
 	add	-8($tp),$A[1]
 	adc	\$0,%rdx
@@ -752,7 +830,7 @@
 
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[0]
-	mov	16*0($np),%rax
+	mov	8*0($np),%rax
 	adc	\$0,%rdx
 	add	($tp),$A[0]		# ap[j]*bp[i]+tp[j]
 	adc	\$0,%rdx
@@ -769,7 +847,7 @@
 
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[1]
-	mov	16*1($np),%rax
+	mov	8*1($np),%rax
 	adc	\$0,%rdx
 	add	8($tp),$A[1]
 	adc	\$0,%rdx
@@ -780,7 +858,7 @@
 	mov	16($ap,$j),%rax
 	adc	\$0,%rdx
 	add	$A[1],$N[1]
-	lea	16*4($np),$np
+	lea	8*4($np),$np
 	adc	\$0,%rdx
 	mov	$N[0],-8($tp)		# tp[j-1]
 	mov	%rdx,$N[0]
@@ -790,7 +868,7 @@
 
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[0]
-	mov	-16*2($np),%rax
+	mov	-8*2($np),%rax
 	adc	\$0,%rdx
 	add	16($tp),$A[0]		# ap[j]*bp[i]+tp[j]
 	lea	32($tp),$tp
@@ -809,7 +887,7 @@
 	mulq	$m0			# ap[j]*bp[i]
 	add	%rax,$A[1]
 	mov	$m1,%rax
-	mov	-16*1($np),$m1
+	mov	-8*1($np),$m1
 	adc	\$0,%rdx
 	add	-8($tp),$A[1]
 	adc	\$0,%rdx
@@ -824,9 +902,8 @@
 	mov	$N[0],-24($tp)		# tp[j-1]
 	mov	%rdx,$N[0]
 
-	movq	%xmm0,$m0		# bp[i+1]
 	mov	$N[1],-16($tp)		# tp[j-1]
-	lea	($np,$num,2),$np	# rewind $np
+	lea	($np,$num),$np		# rewind $np
 
 	xor	$N[1],$N[1]
 	add	$A[0],$N[0]
@@ -840,16 +917,23 @@
 ___
 if (1) {
 $code.=<<___;
+	xor	%rax,%rax
 	sub	$N[0],$m1		# compare top-most words
 	adc	$j,$j			# $j is zero
 	or	$j,$N[1]
-	xor	\$1,$N[1]
+	sub	$N[1],%rax		# %rax=-$N[1]
 	lea	($tp,$num),%rbx		# tptr in .sqr4x_sub
-	lea	($np,$N[1],8),%rbp	# nptr in .sqr4x_sub
+	mov	($np),%r12
+	lea	($np),%rbp		# nptr in .sqr4x_sub
 	mov	%r9,%rcx
-	sar	\$3+2,%rcx		# cf=0
+	sar	\$3+2,%rcx
 	mov	56+8(%rsp),%rdi		# rptr in .sqr4x_sub
-	jmp	.Lsqr4x_sub
+	dec	%r12			# so that after 'not' we get -n[0]
+	xor	%r10,%r10
+	mov	8*1(%rbp),%r13
+	mov	8*2(%rbp),%r14
+	mov	8*3(%rbp),%r15
+	jmp	.Lsqr4x_sub_entry
 ___
 } else {
 my @ri=("%rax",$bp,$m0,$m1);
@@ -916,8 +1000,8 @@
 ___
 $code.=<<___ if ($addx);
 	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-	and	\$0x80100,%r11d
-	cmp	\$0x80100,%r11d
+	and	\$0x80108,%r11d
+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
 	je	.Lpowerx5_enter
 ___
 $code.=<<___;
@@ -928,38 +1012,32 @@
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
-	mov	${num}d,%r10d
+
 	shl	\$3,${num}d		# convert $num to bytes
-	shl	\$3+2,%r10d		# 4*$num
+	lea	($num,$num,2),%r10d	# 3*$num
 	neg	$num
 	mov	($n0),$n0		# *n0
 
 	##############################################################
-	# ensure that stack frame doesn't alias with $aptr+4*$num
-	# modulo 4096, which covers ret[num], am[num] and n[2*num]
-	# (see bn_exp.c). this is done to allow memory disambiguation
-	# logic do its magic.
+	# Ensure that stack frame doesn't alias with $rptr+3*$num
+	# modulo 4096, which covers ret[num], am[num] and n[num]
+	# (see bn_exp.c). This is done to allow memory disambiguation
+	# logic do its magic. [Extra 256 bytes is for power mask
+	# calculated from 7th argument, the index.]
 	#
-	lea	-64(%rsp,$num,2),%r11
-	sub	$aptr,%r11
+	lea	-320(%rsp,$num,2),%r11
+	sub	$rptr,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lpwr_sp_alt
 	sub	%r11,%rsp		# align with $aptr
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*num*8+256)
 	jmp	.Lpwr_sp_done
 
 .align	32
 .Lpwr_sp_alt:
-	lea	4096-64(,$num,2),%r10	# 4096-frame-2*$num
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	4096-320(,$num,2),%r10
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*num*8+256)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
@@ -981,16 +1059,21 @@
 	mov	$n0,  32(%rsp)
 	mov	%rax, 40(%rsp)		# save original %rsp
 .Lpower5_body:
-	movq	$rptr,%xmm1		# save $rptr
+	movq	$rptr,%xmm1		# save $rptr, used in sqr8x
 	movq	$nptr,%xmm2		# save $nptr
-	movq	%r10, %xmm3		# -$num
+	movq	%r10, %xmm3		# -$num, used in sqr8x
 	movq	$bptr,%xmm4
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 	movq	%xmm2,$nptr
 	movq	%xmm4,$bptr
@@ -1551,9 +1634,9 @@
 
 $code.=<<___;
 	movq	%xmm2,$nptr
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xor	%rax,%rax
-	lea	($nptr,$num,2),%rcx	# end of n[]
+	lea	($nptr,$num),%rcx	# end of n[]
 	lea	48+8(%rsp,$num,2),%rdx	# end of t[] buffer
 	mov	%rcx,0+8(%rsp)
 	lea	48+8(%rsp,$num),$tptr	# end of initial t[] window
@@ -1579,21 +1662,21 @@
 	.byte	0x67
 	mov	$m0,%r8
 	imulq	32+8(%rsp),$m0		# n0*a[0]
-	mov	16*0($nptr),%rax	# n[0]
+	mov	8*0($nptr),%rax		# n[0]
 	mov	\$8,%ecx
 	jmp	.L8x_reduce
 
 .align	32
 .L8x_reduce:
 	mulq	$m0
-	 mov	16*1($nptr),%rax	# n[1]
+	 mov	8*1($nptr),%rax		# n[1]
 	neg	%r8
 	mov	%rdx,%r8
 	adc	\$0,%r8
 
 	mulq	$m0
 	add	%rax,%r9
-	 mov	16*2($nptr),%rax
+	 mov	8*2($nptr),%rax
 	adc	\$0,%rdx
 	add	%r9,%r8
 	 mov	$m0,48-8+8(%rsp,%rcx,8)	# put aside n0*a[i]
@@ -1602,7 +1685,7 @@
 
 	mulq	$m0
 	add	%rax,%r10
-	 mov	16*3($nptr),%rax
+	 mov	8*3($nptr),%rax
 	adc	\$0,%rdx
 	add	%r10,%r9
 	 mov	32+8(%rsp),$carry	# pull n0, borrow $carry
@@ -1611,7 +1694,7 @@
 
 	mulq	$m0
 	add	%rax,%r11
-	 mov	16*4($nptr),%rax
+	 mov	8*4($nptr),%rax
 	adc	\$0,%rdx
 	 imulq	%r8,$carry		# modulo-scheduled
 	add	%r11,%r10
@@ -1620,7 +1703,7 @@
 
 	mulq	$m0
 	add	%rax,%r12
-	 mov	16*5($nptr),%rax
+	 mov	8*5($nptr),%rax
 	adc	\$0,%rdx
 	add	%r12,%r11
 	mov	%rdx,%r12
@@ -1628,7 +1711,7 @@
 
 	mulq	$m0
 	add	%rax,%r13
-	 mov	16*6($nptr),%rax
+	 mov	8*6($nptr),%rax
 	adc	\$0,%rdx
 	add	%r13,%r12
 	mov	%rdx,%r13
@@ -1636,7 +1719,7 @@
 
 	mulq	$m0
 	add	%rax,%r14
-	 mov	16*7($nptr),%rax
+	 mov	8*7($nptr),%rax
 	adc	\$0,%rdx
 	add	%r14,%r13
 	mov	%rdx,%r14
@@ -1645,7 +1728,7 @@
 	mulq	$m0
 	 mov	$carry,$m0		# n0*a[i]
 	add	%rax,%r15
-	 mov	16*0($nptr),%rax	# n[0]
+	 mov	8*0($nptr),%rax		# n[0]
 	adc	\$0,%rdx
 	add	%r15,%r14
 	mov	%rdx,%r15
@@ -1654,7 +1737,7 @@
 	dec	%ecx
 	jnz	.L8x_reduce
 
-	lea	16*8($nptr),$nptr
+	lea	8*8($nptr),$nptr
 	xor	%rax,%rax
 	mov	8+8(%rsp),%rdx		# pull end of t[]
 	cmp	0+8(%rsp),$nptr		# end of n[]?
@@ -1673,21 +1756,21 @@
 
 	mov	48+56+8(%rsp),$m0	# pull n0*a[0]
 	mov	\$8,%ecx
-	mov	16*0($nptr),%rax
+	mov	8*0($nptr),%rax
 	jmp	.L8x_tail
 
 .align	32
 .L8x_tail:
 	mulq	$m0
 	add	%rax,%r8
-	 mov	16*1($nptr),%rax
+	 mov	8*1($nptr),%rax
 	 mov	%r8,($tptr)		# save result
 	mov	%rdx,%r8
 	adc	\$0,%r8
 
 	mulq	$m0
 	add	%rax,%r9
-	 mov	16*2($nptr),%rax
+	 mov	8*2($nptr),%rax
 	adc	\$0,%rdx
 	add	%r9,%r8
 	 lea	8($tptr),$tptr		# $tptr++
@@ -1696,7 +1779,7 @@
 
 	mulq	$m0
 	add	%rax,%r10
-	 mov	16*3($nptr),%rax
+	 mov	8*3($nptr),%rax
 	adc	\$0,%rdx
 	add	%r10,%r9
 	mov	%rdx,%r10
@@ -1704,7 +1787,7 @@
 
 	mulq	$m0
 	add	%rax,%r11
-	 mov	16*4($nptr),%rax
+	 mov	8*4($nptr),%rax
 	adc	\$0,%rdx
 	add	%r11,%r10
 	mov	%rdx,%r11
@@ -1712,7 +1795,7 @@
 
 	mulq	$m0
 	add	%rax,%r12
-	 mov	16*5($nptr),%rax
+	 mov	8*5($nptr),%rax
 	adc	\$0,%rdx
 	add	%r12,%r11
 	mov	%rdx,%r12
@@ -1720,7 +1803,7 @@
 
 	mulq	$m0
 	add	%rax,%r13
-	 mov	16*6($nptr),%rax
+	 mov	8*6($nptr),%rax
 	adc	\$0,%rdx
 	add	%r13,%r12
 	mov	%rdx,%r13
@@ -1728,7 +1811,7 @@
 
 	mulq	$m0
 	add	%rax,%r14
-	 mov	16*7($nptr),%rax
+	 mov	8*7($nptr),%rax
 	adc	\$0,%rdx
 	add	%r14,%r13
 	mov	%rdx,%r14
@@ -1739,14 +1822,14 @@
 	add	%rax,%r15
 	adc	\$0,%rdx
 	add	%r15,%r14
-	 mov	16*0($nptr),%rax	# pull n[0]
+	 mov	8*0($nptr),%rax		# pull n[0]
 	mov	%rdx,%r15
 	adc	\$0,%r15
 
 	dec	%ecx
 	jnz	.L8x_tail
 
-	lea	16*8($nptr),$nptr
+	lea	8*8($nptr),$nptr
 	mov	8+8(%rsp),%rdx		# pull end of t[]
 	cmp	0+8(%rsp),$nptr		# end of n[]?
 	jae	.L8x_tail_done		# break out of loop
@@ -1792,7 +1875,7 @@
 	adc	8*6($tptr),%r14
 	adc	8*7($tptr),%r15
 	adc	\$0,%rax		# top-most carry
-	 mov	-16($nptr),%rcx		# np[num-1]
+	 mov	-8($nptr),%rcx		# np[num-1]
 	 xor	$carry,$carry
 
 	movq	%xmm2,$nptr		# restore $nptr
@@ -1810,6 +1893,8 @@
 
 	cmp	%rdx,$tptr		# end of t[]?
 	jb	.L8x_reduction_loop
+	ret
+.size	bn_sqr8x_internal,.-bn_sqr8x_internal
 ___
 }
 ##############################################################
@@ -1818,48 +1903,62 @@
 {
 my ($tptr,$nptr)=("%rbx","%rbp");
 $code.=<<___;
-	#xor	%rsi,%rsi		# %rsi was $carry above
-	sub	%r15,%rcx		# compare top-most words
-	lea	(%rdi,$num),$tptr	# %rdi was $tptr above
-	adc	%rsi,%rsi
-	mov	$num,%rcx
-	or	%rsi,%rax
-	movq	%xmm1,$rptr		# restore $rptr
-	xor	\$1,%rax
-	movq	%xmm1,$aptr		# prepare for back-to-back call
-	lea	($nptr,%rax,8),$nptr
-	sar	\$3+2,%rcx		# cf=0
-	jmp	.Lsqr4x_sub
-
+.type	__bn_post4x_internal,\@abi-omnipotent
 .align	32
+__bn_post4x_internal:
+	mov	8*0($nptr),%r12
+	lea	(%rdi,$num),$tptr	# %rdi was $tptr above
+	mov	$num,%rcx
+	movq	%xmm1,$rptr		# restore $rptr
+	neg	%rax
+	movq	%xmm1,$aptr		# prepare for back-to-back call
+	sar	\$3+2,%rcx
+	dec	%r12			# so that after 'not' we get -n[0]
+	xor	%r10,%r10
+	mov	8*1($nptr),%r13
+	mov	8*2($nptr),%r14
+	mov	8*3($nptr),%r15
+	jmp	.Lsqr4x_sub_entry
+
+.align	16
 .Lsqr4x_sub:
-	.byte	0x66
-	mov	8*0($tptr),%r12
-	mov	8*1($tptr),%r13
-	sbb	16*0($nptr),%r12
-	mov	8*2($tptr),%r14
-	sbb	16*1($nptr),%r13
-	mov	8*3($tptr),%r15
-	lea	8*4($tptr),$tptr
-	sbb	16*2($nptr),%r14
+	mov	8*0($nptr),%r12
+	mov	8*1($nptr),%r13
+	mov	8*2($nptr),%r14
+	mov	8*3($nptr),%r15
+.Lsqr4x_sub_entry:
+	lea	8*4($nptr),$nptr
+	not	%r12
+	not	%r13
+	not	%r14
+	not	%r15
+	and	%rax,%r12
+	and	%rax,%r13
+	and	%rax,%r14
+	and	%rax,%r15
+
+	neg	%r10			# mov %r10,%cf
+	adc	8*0($tptr),%r12
+	adc	8*1($tptr),%r13
+	adc	8*2($tptr),%r14
+	adc	8*3($tptr),%r15
 	mov	%r12,8*0($rptr)
-	sbb	16*3($nptr),%r15
-	lea	16*4($nptr),$nptr
+	lea	8*4($tptr),$tptr
 	mov	%r13,8*1($rptr)
+	sbb	%r10,%r10		# mov %cf,%r10
 	mov	%r14,8*2($rptr)
 	mov	%r15,8*3($rptr)
 	lea	8*4($rptr),$rptr
 
 	inc	%rcx			# pass %cf
 	jnz	.Lsqr4x_sub
-___
-}
-$code.=<<___;
+
 	mov	$num,%r10		# prepare for back-to-back call
 	neg	$num			# restore $num	
 	ret
-.size	bn_sqr8x_internal,.-bn_sqr8x_internal
+.size	__bn_post4x_internal,.-__bn_post4x_internal
 ___
+}
 {
 $code.=<<___;
 .globl	bn_from_montgomery
@@ -1883,39 +1982,32 @@
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
-	.byte	0x67
-	mov	${num}d,%r10d
+
 	shl	\$3,${num}d		# convert $num to bytes
-	shl	\$3+2,%r10d		# 4*$num
+	lea	($num,$num,2),%r10	# 3*$num in bytes
 	neg	$num
 	mov	($n0),$n0		# *n0
 
 	##############################################################
-	# ensure that stack frame doesn't alias with $aptr+4*$num
-	# modulo 4096, which covers ret[num], am[num] and n[2*num]
-	# (see bn_exp.c). this is done to allow memory disambiguation
-	# logic do its magic.
+	# Ensure that stack frame doesn't alias with $rptr+3*$num
+	# modulo 4096, which covers ret[num], am[num] and n[num]
+	# (see bn_exp.c). The stack is allocated to aligned with
+	# bn_power5's frame, and as bn_from_montgomery happens to be
+	# last operation, we use the opportunity to cleanse it.
 	#
-	lea	-64(%rsp,$num,2),%r11
-	sub	$aptr,%r11
+	lea	-320(%rsp,$num,2),%r11
+	sub	$rptr,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lfrom_sp_alt
 	sub	%r11,%rsp		# align with $aptr
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	jmp	.Lfrom_sp_done
 
 .align	32
 .Lfrom_sp_alt:
-	lea	4096-64(,$num,2),%r10	# 4096-frame-2*$num
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	4096-320(,$num,2),%r10
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
@@ -1969,12 +2061,13 @@
 ___
 $code.=<<___ if ($addx);
 	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-	and	\$0x80100,%r11d
-	cmp	\$0x80100,%r11d
+	and	\$0x80108,%r11d
+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
 	jne	.Lfrom_mont_nox
 
 	lea	(%rax,$num),$rptr
-	call	sqrx8x_reduction
+	call	__bn_sqrx8x_reduction
+	call	__bn_postx4x_internal
 
 	pxor	%xmm0,%xmm0
 	lea	48(%rsp),%rax
@@ -1985,7 +2078,8 @@
 .Lfrom_mont_nox:
 ___
 $code.=<<___;
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	%xmm0,%xmm0
 	lea	48(%rsp),%rax
@@ -2025,7 +2119,6 @@
 .align	32
 bn_mulx4x_mont_gather5:
 .Lmulx4x_enter:
-	.byte	0x67
 	mov	%rsp,%rax
 	push	%rbx
 	push	%rbp
@@ -2033,40 +2126,33 @@
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
-	.byte	0x67
-	mov	${num}d,%r10d
+
 	shl	\$3,${num}d		# convert $num to bytes
-	shl	\$3+2,%r10d		# 4*$num
+	lea	($num,$num,2),%r10	# 3*$num in bytes
 	neg	$num			# -$num
 	mov	($n0),$n0		# *n0
 
 	##############################################################
-	# ensure that stack frame doesn't alias with $aptr+4*$num
-	# modulo 4096, which covers a[num], ret[num] and n[2*num]
-	# (see bn_exp.c). this is done to allow memory disambiguation
-	# logic do its magic. [excessive frame is allocated in order
-	# to allow bn_from_mont8x to clear it.]
+	# Ensure that stack frame doesn't alias with $rptr+3*$num
+	# modulo 4096, which covers ret[num], am[num] and n[num]
+	# (see bn_exp.c). This is done to allow memory disambiguation
+	# logic do its magic. [Extra [num] is allocated in order
+	# to align with bn_power5's frame, which is cleansed after
+	# completing exponentiation. Extra 256 bytes is for power mask
+	# calculated from 7th argument, the index.]
 	#
-	lea	-64(%rsp,$num,2),%r11
-	sub	$ap,%r11
+	lea	-320(%rsp,$num,2),%r11
+	sub	$rp,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lmulx4xsp_alt
 	sub	%r11,%rsp		# align with $aptr
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+$num)
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	jmp	.Lmulx4xsp_done
 
-.align	32
 .Lmulx4xsp_alt:
-	lea	4096-64(,$num,2),%r10	# 4096-frame-$num
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+$num)
+	lea	4096-320(,$num,2),%r10
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
@@ -2092,12 +2178,7 @@
 
 	mov	40(%rsp),%rsi		# restore %rsp
 	mov	\$1,%rax
-___
-$code.=<<___ if ($win64);
-	movaps	-88(%rsi),%xmm6
-	movaps	-72(%rsi),%xmm7
-___
-$code.=<<___;
+
 	mov	-48(%rsi),%r15
 	mov	-40(%rsi),%r14
 	mov	-32(%rsi),%r13
@@ -2112,14 +2193,16 @@
 .type	mulx4x_internal,\@abi-omnipotent
 .align	32
 mulx4x_internal:
-	.byte	0x4c,0x89,0x8c,0x24,0x08,0x00,0x00,0x00	# mov	$num,8(%rsp)		# save -$num
-	.byte	0x67
+	mov	$num,8(%rsp)		# save -$num (it was in bytes)
+	mov	$num,%r10
 	neg	$num			# restore $num
 	shl	\$5,$num
-	lea	256($bp,$num),%r13
+	neg	%r10			# restore $num
+	lea	128($bp,$num),%r13	# end of powers table (+size optimization)
 	shr	\$5+5,$num
-	mov	`($win64?56:8)`(%rax),%r10d	# load 7th argument
+	movd	`($win64?56:8)`(%rax),%xmm5	# load 7th argument
 	sub	\$1,$num
+	lea	.Linc(%rip),%rax
 	mov	%r13,16+8(%rsp)		# end of b[num]
 	mov	$num,24+8(%rsp)		# inner counter
 	mov	$rp, 56+8(%rsp)		# save $rp
@@ -2130,52 +2213,92 @@
 my $STRIDE=2**5*8;		# 5 is "window size"
 my $N=$STRIDE/4;		# should match cache line size
 $code.=<<___;
-	mov	%r10,%r11
-	shr	\$`log($N/8)/log(2)`,%r10
-	and	\$`$N/8-1`,%r11
-	not	%r10
-	lea	.Lmagic_masks(%rip),%rax
-	and	\$`2**5/($N/8)-1`,%r10	# 5 is "window size"
-	lea	96($bp,%r11,8),$bptr	# pointer within 1st cache line
-	movq	0(%rax,%r10,8),%xmm4	# set of masks denoting which
-	movq	8(%rax,%r10,8),%xmm5	# cache line contains element
-	add	\$7,%r11
-	movq	16(%rax,%r10,8),%xmm6	# denoted by 7th argument
-	movq	24(%rax,%r10,8),%xmm7
-	and	\$7,%r11
+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
+	lea	88-112(%rsp,%r10),%r10	# place the mask after tp[num+1] (+ICache optimizaton)
+	lea	128($bp),$bptr		# size optimization
 
-	movq	`0*$STRIDE/4-96`($bptr),%xmm0
-	lea	$STRIDE($bptr),$tptr	# borrow $tptr
-	movq	`1*$STRIDE/4-96`($bptr),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bptr),%xmm2
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-96`($bptr),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	movq	`0*$STRIDE/4-96`($tptr),%xmm1
-	pand	%xmm7,%xmm3
+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
+	movdqa	%xmm1,%xmm4
+	.byte	0x67
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+	.byte	0x67
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
+	movdqa	%xmm4,%xmm3
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
+	movdqa	%xmm4,%xmm3
+___
+}
+$code.=<<___;				# last iteration can be optimized
+	.byte	0x67
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
+
+	pand	`16*($i+0)-128`($bptr),%xmm0	# while it's still in register
+	pand	`16*($i+1)-128`($bptr),%xmm1
+	pand	`16*($i+2)-128`($bptr),%xmm2
+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
+	pand	`16*($i+3)-128`($bptr),%xmm3
 	por	%xmm2,%xmm0
-	movq	`1*$STRIDE/4-96`($tptr),%xmm2
-	por	%xmm3,%xmm0
-	.byte	0x67,0x67
-	pand	%xmm4,%xmm1
-	movq	`2*$STRIDE/4-96`($tptr),%xmm3
-
+	por	%xmm3,%xmm1
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+	movdqa	`16*($i+0)-128`($bptr),%xmm4
+	movdqa	`16*($i+1)-128`($bptr),%xmm5
+	movdqa	`16*($i+2)-128`($bptr),%xmm2
+	pand	`16*($i+0)+112`(%r10),%xmm4
+	movdqa	`16*($i+3)-128`($bptr),%xmm3
+	pand	`16*($i+1)+112`(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	`16*($i+2)+112`(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	`16*($i+3)+112`(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+___
+}
+$code.=<<___;
+	pxor	%xmm1,%xmm0
+	pshufd	\$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	lea	$STRIDE($bptr),$bptr
 	movq	%xmm0,%rdx		# bp[0]
-	movq	`3*$STRIDE/4-96`($tptr),%xmm0
-	lea	2*$STRIDE($bptr),$bptr	# next &b[i]
-	pand	%xmm5,%xmm2
-	.byte	0x67,0x67
-	pand	%xmm6,%xmm3
-	##############################################################
-	# $tptr is chosen so that writing to top-most element of the
-	# vector occurs just "above" references to powers table,
-	# "above" modulo cache-line size, which effectively precludes
-	# possibility of memory disambiguation logic failure when
-	# accessing the table.
-	# 
-	lea	64+8*4+8(%rsp,%r11,8),$tptr
+	lea	64+8*4+8(%rsp),$tptr
 
 	mov	%rdx,$bi
 	mulx	0*8($aptr),$mi,%rax	# a[0]*b[0]
@@ -2191,37 +2314,31 @@
 	xor	$zero,$zero		# cf=0, of=0
 	mov	$mi,%rdx
 
-	por	%xmm2,%xmm1
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
 	mov	$bptr,8+8(%rsp)		# off-load &b[i]
-	por	%xmm1,%xmm0
 
-	.byte	0x48,0x8d,0xb6,0x20,0x00,0x00,0x00	# lea	4*8($aptr),$aptr
+	lea	4*8($aptr),$aptr
 	adcx	%rax,%r13
 	adcx	$zero,%r14		# cf=0
 
-	mulx	0*16($nptr),%rax,%r10
+	mulx	0*8($nptr),%rax,%r10
 	adcx	%rax,%r15		# discarded
 	adox	%r11,%r10
-	mulx	1*16($nptr),%rax,%r11
+	mulx	1*8($nptr),%rax,%r11
 	adcx	%rax,%r10
 	adox	%r12,%r11
-	mulx	2*16($nptr),%rax,%r12
+	mulx	2*8($nptr),%rax,%r12
 	mov	24+8(%rsp),$bptr	# counter value
-	.byte	0x66
 	mov	%r10,-8*4($tptr)
 	adcx	%rax,%r11
 	adox	%r13,%r12
-	mulx	3*16($nptr),%rax,%r15
-	 .byte	0x67,0x67
+	mulx	3*8($nptr),%rax,%r15
 	 mov	$bi,%rdx
 	mov	%r11,-8*3($tptr)
 	adcx	%rax,%r12
 	adox	$zero,%r15		# of=0
-	.byte	0x48,0x8d,0x89,0x40,0x00,0x00,0x00	# lea	4*16($nptr),$nptr
+	lea	4*8($nptr),$nptr
 	mov	%r12,-8*2($tptr)
-	#jmp	.Lmulx4x_1st
+	jmp	.Lmulx4x_1st
 
 .align	32
 .Lmulx4x_1st:
@@ -2241,30 +2358,29 @@
 	lea	4*8($tptr),$tptr
 
 	adox	%r15,%r10
-	mulx	0*16($nptr),%rax,%r15
+	mulx	0*8($nptr),%rax,%r15
 	adcx	%rax,%r10
 	adox	%r15,%r11
-	mulx	1*16($nptr),%rax,%r15
+	mulx	1*8($nptr),%rax,%r15
 	adcx	%rax,%r11
 	adox	%r15,%r12
-	mulx	2*16($nptr),%rax,%r15
+	mulx	2*8($nptr),%rax,%r15
 	mov	%r10,-5*8($tptr)
 	adcx	%rax,%r12
 	mov	%r11,-4*8($tptr)
 	adox	%r15,%r13
-	mulx	3*16($nptr),%rax,%r15
+	mulx	3*8($nptr),%rax,%r15
 	 mov	$bi,%rdx
 	mov	%r12,-3*8($tptr)
 	adcx	%rax,%r13
 	adox	$zero,%r15
-	lea	4*16($nptr),$nptr
+	lea	4*8($nptr),$nptr
 	mov	%r13,-2*8($tptr)
 
 	dec	$bptr			# of=0, pass cf
 	jnz	.Lmulx4x_1st
 
 	mov	8(%rsp),$num		# load -num
-	movq	%xmm0,%rdx		# bp[1]
 	adc	$zero,%r15		# modulo-scheduled
 	lea	($aptr,$num),$aptr	# rewind $aptr
 	add	%r15,%r14
@@ -2275,6 +2391,34 @@
 
 .align	32
 .Lmulx4x_outer:
+	lea	16-256($tptr),%r10	# where 256-byte mask is (+density control)
+	pxor	%xmm4,%xmm4
+	.byte	0x67,0x67
+	pxor	%xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+	movdqa	`16*($i+0)-128`($bptr),%xmm0
+	movdqa	`16*($i+1)-128`($bptr),%xmm1
+	movdqa	`16*($i+2)-128`($bptr),%xmm2
+	pand	`16*($i+0)+256`(%r10),%xmm0
+	movdqa	`16*($i+3)-128`($bptr),%xmm3
+	pand	`16*($i+1)+256`(%r10),%xmm1
+	por	%xmm0,%xmm4
+	pand	`16*($i+2)+256`(%r10),%xmm2
+	por	%xmm1,%xmm5
+	pand	`16*($i+3)+256`(%r10),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+___
+}
+$code.=<<___;
+	por	%xmm5,%xmm4
+	pshufd	\$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	lea	$STRIDE($bptr),$bptr
+	movq	%xmm0,%rdx		# m0=bp[i]
+
 	mov	$zero,($tptr)		# save top-most carry
 	lea	4*8($tptr,$num),$tptr	# rewind $tptr
 	mulx	0*8($aptr),$mi,%r11	# a[0]*b[i]
@@ -2289,54 +2433,37 @@
 	mulx	3*8($aptr),%rdx,%r14
 	adox	-2*8($tptr),%r12
 	adcx	%rdx,%r13
-	lea	($nptr,$num,2),$nptr	# rewind $nptr
+	lea	($nptr,$num),$nptr	# rewind $nptr
 	lea	4*8($aptr),$aptr
 	adox	-1*8($tptr),%r13
 	adcx	$zero,%r14
 	adox	$zero,%r14
 
-	.byte	0x67
 	mov	$mi,%r15
 	imulq	32+8(%rsp),$mi		# "t[0]"*n0
 
-	movq	`0*$STRIDE/4-96`($bptr),%xmm0
-	.byte	0x67,0x67
 	mov	$mi,%rdx
-	movq	`1*$STRIDE/4-96`($bptr),%xmm1
-	.byte	0x67
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-96`($bptr),%xmm2
-	.byte	0x67
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-96`($bptr),%xmm3
-	add	\$$STRIDE,$bptr		# next &b[i]
-	.byte	0x67
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
 	xor	$zero,$zero		# cf=0, of=0
 	mov	$bptr,8+8(%rsp)		# off-load &b[i]
 
-	mulx	0*16($nptr),%rax,%r10
+	mulx	0*8($nptr),%rax,%r10
 	adcx	%rax,%r15		# discarded
 	adox	%r11,%r10
-	mulx	1*16($nptr),%rax,%r11
+	mulx	1*8($nptr),%rax,%r11
 	adcx	%rax,%r10
 	adox	%r12,%r11
-	mulx	2*16($nptr),%rax,%r12
+	mulx	2*8($nptr),%rax,%r12
 	adcx	%rax,%r11
 	adox	%r13,%r12
-	mulx	3*16($nptr),%rax,%r15
+	mulx	3*8($nptr),%rax,%r15
 	 mov	$bi,%rdx
-	 por	%xmm2,%xmm0
 	mov	24+8(%rsp),$bptr	# counter value
 	mov	%r10,-8*4($tptr)
-	 por	%xmm3,%xmm0
 	adcx	%rax,%r12
 	mov	%r11,-8*3($tptr)
 	adox	$zero,%r15		# of=0
 	mov	%r12,-8*2($tptr)
-	lea	4*16($nptr),$nptr
+	lea	4*8($nptr),$nptr
 	jmp	.Lmulx4x_inner
 
 .align	32
@@ -2361,20 +2488,20 @@
 	adcx	$zero,%r14		# cf=0
 
 	adox	%r15,%r10
-	mulx	0*16($nptr),%rax,%r15
+	mulx	0*8($nptr),%rax,%r15
 	adcx	%rax,%r10
 	adox	%r15,%r11
-	mulx	1*16($nptr),%rax,%r15
+	mulx	1*8($nptr),%rax,%r15
 	adcx	%rax,%r11
 	adox	%r15,%r12
-	mulx	2*16($nptr),%rax,%r15
+	mulx	2*8($nptr),%rax,%r15
 	mov	%r10,-5*8($tptr)
 	adcx	%rax,%r12
 	adox	%r15,%r13
 	mov	%r11,-4*8($tptr)
-	mulx	3*16($nptr),%rax,%r15
+	mulx	3*8($nptr),%rax,%r15
 	 mov	$bi,%rdx
-	lea	4*16($nptr),$nptr
+	lea	4*8($nptr),$nptr
 	mov	%r12,-3*8($tptr)
 	adcx	%rax,%r13
 	adox	$zero,%r15
@@ -2384,7 +2511,6 @@
 	jnz	.Lmulx4x_inner
 
 	mov	0+8(%rsp),$num		# load -num
-	movq	%xmm0,%rdx		# bp[i+1]
 	adc	$zero,%r15		# modulo-scheduled
 	sub	0*8($tptr),$bptr	# pull top-most carry to %cf
 	mov	8+8(%rsp),$bptr		# re-load &b[i]
@@ -2397,20 +2523,26 @@
 	cmp	%r10,$bptr
 	jb	.Lmulx4x_outer
 
-	mov	-16($nptr),%r10
+	mov	-8($nptr),%r10
+	mov	$zero,%r8
+	mov	($nptr,$num),%r12
+	lea	($nptr,$num),%rbp	# rewind $nptr
+	mov	$num,%rcx
+	lea	($tptr,$num),%rdi	# rewind $tptr
+	xor	%eax,%eax
 	xor	%r15,%r15
 	sub	%r14,%r10		# compare top-most words
 	adc	%r15,%r15
-	or	%r15,$zero
-	xor	\$1,$zero
-	lea	($tptr,$num),%rdi	# rewind $tptr
-	lea	($nptr,$num,2),$nptr	# rewind $nptr
-	.byte	0x67,0x67
-	sar	\$3+2,$num		# cf=0
-	lea	($nptr,$zero,8),%rbp
+	or	%r15,%r8
+	sar	\$3+2,%rcx
+	sub	%r8,%rax		# %rax=-%r8
 	mov	56+8(%rsp),%rdx		# restore rp
-	mov	$num,%rcx
-	jmp	.Lsqrx4x_sub		# common post-condition
+	dec	%r12			# so that after 'not' we get -n[0]
+	mov	8*1(%rbp),%r13
+	xor	%r8,%r8
+	mov	8*2(%rbp),%r14
+	mov	8*3(%rbp),%r15
+	jmp	.Lsqrx4x_sub_entry	# common post-condition
 .size	mulx4x_internal,.-mulx4x_internal
 ___
 }{
@@ -2434,7 +2566,6 @@
 .align	32
 bn_powerx5:
 .Lpowerx5_enter:
-	.byte	0x67
 	mov	%rsp,%rax
 	push	%rbx
 	push	%rbp
@@ -2442,39 +2573,32 @@
 	push	%r13
 	push	%r14
 	push	%r15
-___
-$code.=<<___ if ($win64);
-	lea	-0x28(%rsp),%rsp
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
-___
-$code.=<<___;
-	.byte	0x67
-	mov	${num}d,%r10d
+
 	shl	\$3,${num}d		# convert $num to bytes
-	shl	\$3+2,%r10d		# 4*$num
+	lea	($num,$num,2),%r10	# 3*$num in bytes
 	neg	$num
 	mov	($n0),$n0		# *n0
 
 	##############################################################
-	# ensure that stack frame doesn't alias with $aptr+4*$num
-	# modulo 4096, which covers ret[num], am[num] and n[2*num]
-	# (see bn_exp.c). this is done to allow memory disambiguation
-	# logic do its magic.
+	# Ensure that stack frame doesn't alias with $rptr+3*$num
+	# modulo 4096, which covers ret[num], am[num] and n[num]
+	# (see bn_exp.c). This is done to allow memory disambiguation
+	# logic do its magic. [Extra 256 bytes is for power mask
+	# calculated from 7th argument, the index.]
 	#
-	lea	-64(%rsp,$num,2),%r11
-	sub	$aptr,%r11
+	lea	-320(%rsp,$num,2),%r11
+	sub	$rptr,%r11
 	and	\$4095,%r11
 	cmp	%r11,%r10
 	jb	.Lpwrx_sp_alt
 	sub	%r11,%rsp		# align with $aptr
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	jmp	.Lpwrx_sp_done
 
 .align	32
 .Lpwrx_sp_alt:
-	lea	4096-64(,$num,2),%r10	# 4096-frame-2*$num
-	lea	-64(%rsp,$num,2),%rsp	# alloca(frame+2*$num)
+	lea	4096-320(,$num,2),%r10
+	lea	-320(%rsp,$num,2),%rsp	# alloca(frame+2*$num*8+256)
 	sub	%r10,%r11
 	mov	\$0,%r10
 	cmovc	%r10,%r11
@@ -2505,10 +2629,15 @@
 .Lpowerx5_body:
 
 	call	__bn_sqrx8x_internal
+	call	__bn_postx4x_internal
 	call	__bn_sqrx8x_internal
+	call	__bn_postx4x_internal
 	call	__bn_sqrx8x_internal
+	call	__bn_postx4x_internal
 	call	__bn_sqrx8x_internal
+	call	__bn_postx4x_internal
 	call	__bn_sqrx8x_internal
+	call	__bn_postx4x_internal
 
 	mov	%r10,$num		# -num
 	mov	$aptr,$rptr
@@ -2520,12 +2649,7 @@
 
 	mov	40(%rsp),%rsi		# restore %rsp
 	mov	\$1,%rax
-___
-$code.=<<___ if ($win64);
-	movaps	-88(%rsi),%xmm6
-	movaps	-72(%rsi),%xmm7
-___
-$code.=<<___;
+
 	mov	-48(%rsi),%r15
 	mov	-40(%rsi),%r14
 	mov	-32(%rsi),%r13
@@ -2959,11 +3083,11 @@
 
 $code.=<<___;
 	movq	%xmm2,$nptr
-sqrx8x_reduction:
+__bn_sqrx8x_reduction:
 	xor	%eax,%eax		# initial top-most carry bit
 	mov	32+8(%rsp),%rbx		# n0
 	mov	48+8(%rsp),%rdx		# "%r8", 8*0($tptr)
-	lea	-128($nptr,$num,2),%rcx	# end of n[]
+	lea	-8*8($nptr,$num),%rcx	# end of n[]
 	#lea	48+8(%rsp,$num,2),$tptr	# end of t[] buffer
 	mov	%rcx, 0+8(%rsp)		# save end of n[]
 	mov	$tptr,8+8(%rsp)		# save end of t[]
@@ -2992,23 +3116,23 @@
 .align	32
 .Lsqrx8x_reduce:
 	mov	%r8, %rbx
-	mulx	16*0($nptr),%rax,%r8	# n[0]
+	mulx	8*0($nptr),%rax,%r8	# n[0]
 	adcx	%rbx,%rax		# discarded
 	adox	%r9,%r8
 
-	mulx	16*1($nptr),%rbx,%r9	# n[1]
+	mulx	8*1($nptr),%rbx,%r9	# n[1]
 	adcx	%rbx,%r8
 	adox	%r10,%r9
 
-	mulx	16*2($nptr),%rbx,%r10
+	mulx	8*2($nptr),%rbx,%r10
 	adcx	%rbx,%r9
 	adox	%r11,%r10
 
-	mulx	16*3($nptr),%rbx,%r11
+	mulx	8*3($nptr),%rbx,%r11
 	adcx	%rbx,%r10
 	adox	%r12,%r11
 
-	.byte	0xc4,0x62,0xe3,0xf6,0xa5,0x40,0x00,0x00,0x00	# mulx	16*4($nptr),%rbx,%r12
+	.byte	0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	8*4($nptr),%rbx,%r12
 	 mov	%rdx,%rax
 	 mov	%r8,%rdx
 	adcx	%rbx,%r11
@@ -3018,15 +3142,15 @@
 	 mov	%rax,%rdx
 	 mov	%rax,64+48+8(%rsp,%rcx,8)	# put aside n0*a[i]
 
-	mulx	16*5($nptr),%rax,%r13
+	mulx	8*5($nptr),%rax,%r13
 	adcx	%rax,%r12
 	adox	%r14,%r13
 
-	mulx	16*6($nptr),%rax,%r14
+	mulx	8*6($nptr),%rax,%r14
 	adcx	%rax,%r13
 	adox	%r15,%r14
 
-	mulx	16*7($nptr),%rax,%r15
+	mulx	8*7($nptr),%rax,%r15
 	 mov	%rbx,%rdx
 	adcx	%rax,%r14
 	adox	$carry,%r15		# $carry is 0
@@ -3042,7 +3166,7 @@
 
 	mov	48+8(%rsp),%rdx		# pull n0*a[0]
 	add	8*0($tptr),%r8
-	lea	16*8($nptr),$nptr
+	lea	8*8($nptr),$nptr
 	mov	\$-8,%rcx
 	adcx	8*1($tptr),%r9
 	adcx	8*2($tptr),%r10
@@ -3061,35 +3185,35 @@
 .align	32
 .Lsqrx8x_tail:
 	mov	%r8,%rbx
-	mulx	16*0($nptr),%rax,%r8
+	mulx	8*0($nptr),%rax,%r8
 	adcx	%rax,%rbx
 	adox	%r9,%r8
 
-	mulx	16*1($nptr),%rax,%r9
+	mulx	8*1($nptr),%rax,%r9
 	adcx	%rax,%r8
 	adox	%r10,%r9
 
-	mulx	16*2($nptr),%rax,%r10
+	mulx	8*2($nptr),%rax,%r10
 	adcx	%rax,%r9
 	adox	%r11,%r10
 
-	mulx	16*3($nptr),%rax,%r11
+	mulx	8*3($nptr),%rax,%r11
 	adcx	%rax,%r10
 	adox	%r12,%r11
 
-	.byte	0xc4,0x62,0xfb,0xf6,0xa5,0x40,0x00,0x00,0x00	# mulx	16*4($nptr),%rax,%r12
+	.byte	0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	8*4($nptr),%rax,%r12
 	adcx	%rax,%r11
 	adox	%r13,%r12
 
-	mulx	16*5($nptr),%rax,%r13
+	mulx	8*5($nptr),%rax,%r13
 	adcx	%rax,%r12
 	adox	%r14,%r13
 
-	mulx	16*6($nptr),%rax,%r14
+	mulx	8*6($nptr),%rax,%r14
 	adcx	%rax,%r13
 	adox	%r15,%r14
 
-	mulx	16*7($nptr),%rax,%r15
+	mulx	8*7($nptr),%rax,%r15
 	 mov	72+48+8(%rsp,%rcx,8),%rdx	# pull n0*a[i]
 	adcx	%rax,%r14
 	adox	$carry,%r15
@@ -3105,7 +3229,7 @@
 
 	sub	16+8(%rsp),$carry	# mov 16(%rsp),%cf
 	 mov	48+8(%rsp),%rdx		# pull n0*a[0]
-	 lea	16*8($nptr),$nptr
+	 lea	8*8($nptr),$nptr
 	adc	8*0($tptr),%r8
 	adc	8*1($tptr),%r9
 	adc	8*2($tptr),%r10
@@ -3141,7 +3265,7 @@
 	adc	8*0($tptr),%r8
 	 movq	%xmm3,%rcx
 	adc	8*1($tptr),%r9
-	 mov	16*7($nptr),$carry
+	 mov	8*7($nptr),$carry
 	 movq	%xmm2,$nptr		# restore $nptr
 	adc	8*2($tptr),%r10
 	adc	8*3($tptr),%r11
@@ -3167,6 +3291,8 @@
 	lea	8*8($tptr,%rcx),$tptr	# start of current t[] window
 	cmp	8+8(%rsp),%r8		# end of t[]?
 	jb	.Lsqrx8x_reduction_loop
+	ret
+.size	bn_sqrx8x_internal,.-bn_sqrx8x_internal
 ___
 }
 ##############################################################
@@ -3174,52 +3300,59 @@
 #
 {
 my ($rptr,$nptr)=("%rdx","%rbp");
-my @ri=map("%r$_",(10..13));
-my @ni=map("%r$_",(14..15));
 $code.=<<___;
-	xor	%ebx,%ebx
-	sub	%r15,%rsi		# compare top-most words
-	adc	%rbx,%rbx
+.align	32
+__bn_postx4x_internal:
+	mov	8*0($nptr),%r12
 	mov	%rcx,%r10		# -$num
-	or	%rbx,%rax
 	mov	%rcx,%r9		# -$num
-	xor	\$1,%rax
-	sar	\$3+2,%rcx		# cf=0
+	neg	%rax
+	sar	\$3+2,%rcx
 	#lea	48+8(%rsp,%r9),$tptr
-	lea	($nptr,%rax,8),$nptr
 	movq	%xmm1,$rptr		# restore $rptr
 	movq	%xmm1,$aptr		# prepare for back-to-back call
-	jmp	.Lsqrx4x_sub
+	dec	%r12			# so that after 'not' we get -n[0]
+	mov	8*1($nptr),%r13
+	xor	%r8,%r8
+	mov	8*2($nptr),%r14
+	mov	8*3($nptr),%r15
+	jmp	.Lsqrx4x_sub_entry
 
-.align	32
+.align	16
 .Lsqrx4x_sub:
-	.byte	0x66
-	mov	8*0($tptr),%r12
-	mov	8*1($tptr),%r13
-	sbb	16*0($nptr),%r12
-	mov	8*2($tptr),%r14
-	sbb	16*1($nptr),%r13
-	mov	8*3($tptr),%r15
-	lea	8*4($tptr),$tptr
-	sbb	16*2($nptr),%r14
+	mov	8*0($nptr),%r12
+	mov	8*1($nptr),%r13
+	mov	8*2($nptr),%r14
+	mov	8*3($nptr),%r15
+.Lsqrx4x_sub_entry:
+	andn	%rax,%r12,%r12
+	lea	8*4($nptr),$nptr
+	andn	%rax,%r13,%r13
+	andn	%rax,%r14,%r14
+	andn	%rax,%r15,%r15
+
+	neg	%r8			# mov %r8,%cf
+	adc	8*0($tptr),%r12
+	adc	8*1($tptr),%r13
+	adc	8*2($tptr),%r14
+	adc	8*3($tptr),%r15
 	mov	%r12,8*0($rptr)
-	sbb	16*3($nptr),%r15
-	lea	16*4($nptr),$nptr
+	lea	8*4($tptr),$tptr
 	mov	%r13,8*1($rptr)
+	sbb	%r8,%r8			# mov %cf,%r8
 	mov	%r14,8*2($rptr)
 	mov	%r15,8*3($rptr)
 	lea	8*4($rptr),$rptr
 
 	inc	%rcx
 	jnz	.Lsqrx4x_sub
-___
-}
-$code.=<<___;
+
 	neg	%r9			# restore $num
 
 	ret
-.size	bn_sqrx8x_internal,.-bn_sqrx8x_internal
+.size	__bn_postx4x_internal,.-__bn_postx4x_internal
 ___
+}
 }}}
 {
 my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%edx","%r8", "%r9d") : # Win64 order
@@ -3249,56 +3382,91 @@
 
 .globl	bn_gather5
 .type	bn_gather5,\@abi-omnipotent
-.align	16
+.align	32
 bn_gather5:
-___
-$code.=<<___ if ($win64);
-.LSEH_begin_bn_gather5:
+.LSEH_begin_bn_gather5:			# Win64 thing, but harmless in other cases
 	# I can't trust assembler to use specific encoding:-(
-	.byte	0x48,0x83,0xec,0x28		#sub	\$0x28,%rsp
-	.byte	0x0f,0x29,0x34,0x24		#movaps	%xmm6,(%rsp)
-	.byte	0x0f,0x29,0x7c,0x24,0x10	#movdqa	%xmm7,0x10(%rsp)
+	.byte	0x4c,0x8d,0x14,0x24			#lea    (%rsp),%r10
+	.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00	#sub	$0x108,%rsp
+	lea	.Linc(%rip),%rax
+	and	\$-16,%rsp		# shouldn't be formally required
+
+	movd	$idx,%xmm5
+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
+	lea	128($tbl),%r11		# size optimization
+	lea	128(%rsp),%rax		# size optimization
+
+	pshufd	\$0,%xmm5,%xmm5		# broadcast $idx
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to $idx and save result to stack
+#
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
+___
+$code.=<<___	if ($i);
+	movdqa	%xmm3,`16*($i-1)-128`(%rax)
 ___
 $code.=<<___;
-	mov	$idx,%r11d
-	shr	\$`log($N/8)/log(2)`,$idx
-	and	\$`$N/8-1`,%r11
-	not	$idx
-	lea	.Lmagic_masks(%rip),%rax
-	and	\$`2**5/($N/8)-1`,$idx	# 5 is "window size"
-	lea	128($tbl,%r11,8),$tbl	# pointer within 1st cache line
-	movq	0(%rax,$idx,8),%xmm4	# set of masks denoting which
-	movq	8(%rax,$idx,8),%xmm5	# cache line contains element
-	movq	16(%rax,$idx,8),%xmm6	# denoted by 7th argument
-	movq	24(%rax,$idx,8),%xmm7
-	jmp	.Lgather
-.align	16
-.Lgather:
-	movq	`0*$STRIDE/4-128`($tbl),%xmm0
-	movq	`1*$STRIDE/4-128`($tbl),%xmm1
-	pand	%xmm4,%xmm0
-	movq	`2*$STRIDE/4-128`($tbl),%xmm2
-	pand	%xmm5,%xmm1
-	movq	`3*$STRIDE/4-128`($tbl),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	.byte	0x67,0x67
-	por	%xmm2,%xmm0
-	lea	$STRIDE($tbl),$tbl
-	por	%xmm3,%xmm0
+	movdqa	%xmm4,%xmm3
 
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
+	movdqa	%xmm0,`16*($i+0)-128`(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
+	movdqa	%xmm1,`16*($i+1)-128`(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
+	movdqa	%xmm2,`16*($i+2)-128`(%rax)
+	movdqa	%xmm4,%xmm2
+___
+}
+$code.=<<___;
+	movdqa	%xmm3,`16*($i-1)-128`(%rax)
+	jmp	.Lgather
+
+.align	32
+.Lgather:
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+	movdqa	`16*($i+0)-128`(%r11),%xmm0
+	movdqa	`16*($i+1)-128`(%r11),%xmm1
+	movdqa	`16*($i+2)-128`(%r11),%xmm2
+	pand	`16*($i+0)-128`(%rax),%xmm0
+	movdqa	`16*($i+3)-128`(%r11),%xmm3
+	pand	`16*($i+1)-128`(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	`16*($i+2)-128`(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	`16*($i+3)-128`(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+___
+}
+$code.=<<___;
+	por	%xmm5,%xmm4
+	lea	$STRIDE(%r11),%r11
+	pshufd	\$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
 	movq	%xmm0,($out)		# m0=bp[0]
 	lea	8($out),$out
 	sub	\$1,$num
 	jnz	.Lgather
-___
-$code.=<<___ if ($win64);
-	movaps	(%rsp),%xmm6
-	movaps	0x10(%rsp),%xmm7
-	lea	0x28(%rsp),%rsp
-___
-$code.=<<___;
+
+	lea	(%r10),%rsp
 	ret
 .LSEH_end_bn_gather5:
 .size	bn_gather5,.-bn_gather5
@@ -3306,9 +3474,9 @@
 }
 $code.=<<___;
 .align	64
-.Lmagic_masks:
-	.long	0,0, 0,0, 0,0, -1,-1
-	.long	0,0, 0,0, 0,0,  0,0
+.Linc:
+	.long	0,0, 1,1
+	.long	2,2, 2,2
 .asciz	"Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
 ___
 
@@ -3356,19 +3524,16 @@
 
 	lea	.Lmul_epilogue(%rip),%r10
 	cmp	%r10,%rbx
-	jb	.Lbody_40
+	ja	.Lbody_40
 
 	mov	192($context),%r10	# pull $num
 	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
+
 	jmp	.Lbody_proceed
 
 .Lbody_40:
 	mov	40(%rax),%rax		# pull saved stack pointer
 .Lbody_proceed:
-
-	movaps	-88(%rax),%xmm0
-	movaps	-72(%rax),%xmm1
-
 	mov	-8(%rax),%rbx
 	mov	-16(%rax),%rbp
 	mov	-24(%rax),%r12
@@ -3381,8 +3546,6 @@
 	mov	%r13,224($context)	# restore context->R13
 	mov	%r14,232($context)	# restore context->R14
 	mov	%r15,240($context)	# restore context->R15
-	movups	%xmm0,512($context)	# restore context->Xmm6
-	movups	%xmm1,528($context)	# restore context->Xmm7
 
 .Lcommon_seh_tail:
 	mov	8(%rax),%rdi
@@ -3493,10 +3656,9 @@
 $code.=<<___;
 .align	8
 .LSEH_info_bn_gather5:
-        .byte   0x01,0x0d,0x05,0x00
-        .byte   0x0d,0x78,0x01,0x00	#movaps	0x10(rsp),xmm7
-        .byte   0x08,0x68,0x00,0x00	#movaps	(rsp),xmm6
-        .byte   0x04,0x42,0x00,0x00	#sub	rsp,0x28
+	.byte	0x01,0x0b,0x03,0x0a
+	.byte	0x0b,0x01,0x21,0x00	# sub	rsp,0x108
+	.byte	0x04,0xa3,0x00,0x00	# lea	r10,(rsp)
 .align	8
 ___
 }
diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c
index 543c148..0ecaf82 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -266,6 +266,18 @@
   return 1;
 }
 
+int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) {
+  if (bn_wexpand(bn, num) == NULL) {
+    return 0;
+  }
+  memmove(bn->d, words, num * sizeof(BN_ULONG));
+  /* |bn_wexpand| verified that |num| isn't too large. */
+  bn->top = (int)num;
+  bn_correct_top(bn);
+  bn->neg = 0;
+  return 1;
+}
+
 int BN_is_negative(const BIGNUM *bn) {
   return bn->neg != 0;
 }
@@ -295,7 +307,7 @@
     return NULL;
   }
 
-  a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
+  a = OPENSSL_malloc(sizeof(BN_ULONG) * words);
   if (a == NULL) {
     OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
diff --git a/src/crypto/bn/bn_asn1.c b/src/crypto/bn/bn_asn1.c
index 9d70ba8..efb2335 100644
--- a/src/crypto/bn/bn_asn1.c
+++ b/src/crypto/bn/bn_asn1.c
@@ -18,7 +18,7 @@
 #include <openssl/err.h>
 
 
-int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
+int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) {
   CBS child;
   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
       CBS_len(&child) == 0) {
@@ -42,7 +42,7 @@
   return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
 }
 
-int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
+int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret) {
   CBS child;
   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
       CBS_len(&child) == 0) {
@@ -58,7 +58,7 @@
   return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
 }
 
-int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
+int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) {
   /* Negative numbers are unsupported. */
   if (BN_is_negative(bn)) {
     OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
@@ -66,28 +66,15 @@
   }
 
   CBB child;
-  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) ||
+      /* The number must be padded with a leading zero if the high bit would
+       * otherwise be set or if |bn| is zero. */
+      (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) ||
+      !BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) ||
+      !CBB_flush(cbb)) {
     OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
     return 0;
   }
 
-  /* The number must be padded with a leading zero if the high bit would
-   * otherwise be set (or |bn| is zero). */
-  if (BN_num_bits(bn) % 8 == 0 &&
-      !CBB_add_u8(&child, 0x00)) {
-    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
-    return 0;
-  }
-
-  uint8_t *out;
-  if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
-    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
-    return 0;
-  }
-  BN_bn2bin(bn, out);
-  if (!CBB_flush(cbb)) {
-    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
-    return 0;
-  }
   return 1;
 }
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index e7e04f1..fe8cfd0 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -1799,8 +1799,8 @@
     {"\x02\x00", 2},
 };
 
-// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
-// should interpret them.
+// kASN1BuggyTests contains incorrect encodings and the corresponding, expected
+// results of |BN_parse_asn1_unsigned_buggy| given that input.
 static const ASN1Test kASN1BuggyTests[] = {
     // Negative numbers.
     {"128", "\x02\x01\x80", 3},
@@ -1823,7 +1823,7 @@
     }
     CBS cbs;
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (!BN_cbs2unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+    if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
       fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
       return false;
     }
@@ -1838,7 +1838,7 @@
     size_t der_len;
     CBB_zero(&cbb);
     if (!CBB_init(&cbb, 0) ||
-        !BN_bn2cbb(&cbb, bn.get()) ||
+        !BN_marshal_asn1(&cbb, bn.get()) ||
         !CBB_finish(&cbb, &der, &der_len)) {
       CBB_cleanup(&cbb);
       return false;
@@ -1850,9 +1850,9 @@
       return false;
     }
 
-    // |BN_cbs2unsigned_buggy| parses all valid input.
+    // |BN_parse_asn1_unsigned_buggy| parses all valid input.
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (!BN_cbs2unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+    if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
       fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
       return false;
     }
@@ -1869,16 +1869,16 @@
     }
     CBS cbs;
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (BN_cbs2unsigned(&cbs, bn.get())) {
+    if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
       fprintf(stderr, "Parsed invalid input.\n");
       return false;
     }
     ERR_clear_error();
 
     // All tests in kASN1InvalidTests are also rejected by
-    // |BN_cbs2unsigned_buggy|.
+    // |BN_parse_asn1_unsigned_buggy|.
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
+    if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
       fprintf(stderr, "Parsed invalid input.\n");
       return false;
     }
@@ -1886,7 +1886,7 @@
   }
 
   for (const ASN1Test &test : kASN1BuggyTests) {
-    // These broken encodings are rejected by |BN_cbs2unsigned|.
+    // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
     ScopedBIGNUM bn(BN_new());
     if (!bn) {
       return false;
@@ -1894,20 +1894,20 @@
 
     CBS cbs;
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (BN_cbs2unsigned(&cbs, bn.get())) {
+    if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
       fprintf(stderr, "Parsed invalid input.\n");
       return false;
     }
     ERR_clear_error();
 
-    // However |BN_cbs2unsigned_buggy| accepts them.
+    // However |BN_parse_asn1_unsigned_buggy| accepts them.
     ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
     if (!bn2) {
       return false;
     }
 
     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
-    if (!BN_cbs2unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
+    if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
       fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
       return false;
     }
@@ -1926,7 +1926,7 @@
   CBB cbb;
   CBB_zero(&cbb);
   if (!CBB_init(&cbb, 0) ||
-      BN_bn2cbb(&cbb, bn.get())) {
+      BN_marshal_asn1(&cbb, bn.get())) {
     fprintf(stderr, "Serialized negative number.\n");
     CBB_cleanup(&cbb);
     return false;
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 1f7af64..9125bf8 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -208,7 +208,7 @@
   char *buf;
   char *p;
 
-  buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
+  buf = OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
   if (buf == NULL) {
     OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -385,9 +385,8 @@
    */
   i = BN_num_bits(a) * 3;
   num = i / 10 + i / 1000 + 1 + 1;
-  bn_data =
-      (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
-  buf = (char *)OPENSSL_malloc(num + 3);
+  bn_data = OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
+  buf = OPENSSL_malloc(num + 3);
   if ((buf == NULL) || (bn_data == NULL)) {
     OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     goto err;
@@ -578,12 +577,14 @@
     return NULL;
   }
 
+  int out_is_alloced = 0;
   if (out == NULL) {
     out = BN_new();
-  }
-  if (out == NULL) {
-    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
-    return NULL;
+    if (out == NULL) {
+      OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+      return NULL;
+    }
+    out_is_alloced = 1;
   }
 
   if (in_len == 0) {
@@ -593,6 +594,9 @@
 
   in += 4;
   if (BN_bin2bn(in, in_len, out) == NULL) {
+    if (out_is_alloced) {
+      BN_free(out);
+    }
     return NULL;
   }
   out->neg = ((*in) & 0x80) != 0;
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index f9e144a..6f67291 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -56,55 +56,126 @@
 
 #include <openssl/bn.h>
 
+#include <assert.h>
 #include <limits.h>
 #include <openssl/err.h>
 
 #include "internal.h"
 
 
-#define asm __asm__
+#if !defined(BN_ULLONG)
+/* bn_div_words divides a double-width |h|,|l| by |d| and returns the result,
+ * which must fit in a |BN_ULONG|. */
+static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
+  BN_ULONG dh, dl, q, ret = 0, th, tl, t;
+  int i, count = 2;
 
-#if !defined(OPENSSL_NO_ASM)
-# if defined(__GNUC__) && __GNUC__>=2
-#  if defined(OPENSSL_X86)
-   /*
-    * There were two reasons for implementing this template:
-    * - GNU C generates a call to a function (__udivdi3 to be exact)
-    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
-    *   understand why...);
-    * - divl doesn't only calculate quotient, but also leaves
-    *   remainder in %edx which we can definitely use here:-)
-    *
-    *					<appro@fy.chalmers.se>
-    */
-#undef div_asm
-#  define div_asm(n0,n1,d0)		\
-	({  asm volatile (			\
-		"divl	%4"			\
-		: "=a"(q), "=d"(rem)		\
-		: "a"(n1), "d"(n0), "g"(d0)	\
-		: "cc");			\
-	    q;					\
-	})
-#  define REMAINDER_IS_ALREADY_CALCULATED
-#  elif defined(OPENSSL_X86_64)
-   /*
-    * Same story here, but it's 128-bit by 64-bit division. Wow!
-    *					<appro@fy.chalmers.se>
-    */
-#  undef div_asm
-#  define div_asm(n0,n1,d0)		\
-	({  asm volatile (			\
-		"divq	%4"			\
-		: "=a"(q), "=d"(rem)		\
-		: "a"(n1), "d"(n0), "g"(d0)	\
-		: "cc");			\
-	    q;					\
-	})
-#  define REMAINDER_IS_ALREADY_CALCULATED
-#  endif /* __<cpu> */
-# endif /* __GNUC__ */
-#endif /* OPENSSL_NO_ASM */
+  if (d == 0) {
+    return BN_MASK2;
+  }
+
+  i = BN_num_bits_word(d);
+  assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+  i = BN_BITS2 - i;
+  if (h >= d) {
+    h -= d;
+  }
+
+  if (i) {
+    d <<= i;
+    h = (h << i) | (l >> (BN_BITS2 - i));
+    l <<= i;
+  }
+  dh = (d & BN_MASK2h) >> BN_BITS4;
+  dl = (d & BN_MASK2l);
+  for (;;) {
+    if ((h >> BN_BITS4) == dh) {
+      q = BN_MASK2l;
+    } else {
+      q = h / dh;
+    }
+
+    th = q * dh;
+    tl = dl * q;
+    for (;;) {
+      t = h - th;
+      if ((t & BN_MASK2h) ||
+          ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
+        break;
+      }
+      q--;
+      th -= dh;
+      tl -= dl;
+    }
+    t = (tl >> BN_BITS4);
+    tl = (tl << BN_BITS4) & BN_MASK2h;
+    th += t;
+
+    if (l < tl) {
+      th++;
+    }
+    l -= tl;
+    if (h < th) {
+      h += d;
+      q--;
+    }
+    h -= th;
+
+    if (--count == 0) {
+      break;
+    }
+
+    ret = q << BN_BITS4;
+    h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+    l = (l & BN_MASK2l) << BN_BITS4;
+  }
+
+  ret |= q;
+  return ret;
+}
+#endif /* !defined(BN_ULLONG) */
+
+static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out,
+                                    BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) {
+  /* GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when
+   * the |BN_ULLONG|-based C code is used.
+   *
+   * GCC bugs:
+   *   * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224
+   *   * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721
+   *   * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183
+   *   * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897
+   *   * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668
+   *
+   * Clang bugs:
+   *   * https://llvm.org/bugs/show_bug.cgi?id=6397
+   *   * https://llvm.org/bugs/show_bug.cgi?id=12418
+   *
+   * These issues aren't specific to x86 and x86_64, so it might be worthwhile
+   * to add more assembly language implementations. */
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__GNUC__)
+  __asm__ volatile (
+    "divl %4"
+    : "=a"(*quotient_out), "=d"(*rem_out)
+    : "a"(n1), "d"(n0), "g"(d0)
+    : "cc" );
+#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
+  __asm__ volatile (
+    "divq %4"
+    : "=a"(*quotient_out), "=d"(*rem_out)
+    : "a"(n1), "d"(n0), "g"(d0)
+    : "cc" );
+#else
+#if defined(BN_ULLONG)
+  BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1;
+  *quotient_out = (BN_ULONG)(n / d0);
+#else
+  *quotient_out = bn_div_words(n0, n1, d0);
+#endif
+  *rem_out = n1 - (*quotient_out * d0);
+#endif
+}
 
 /* BN_div computes  dv := num / divisor,  rounding towards
  * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
@@ -260,23 +331,10 @@
       q = BN_MASK2;
     } else {
       /* n0 < d0 */
+      bn_div_rem_words(&q, &rem, n0, n1, d0);
+
 #ifdef BN_ULLONG
-      BN_ULLONG t2;
-
-#if defined(BN_ULLONG) && !defined(div_asm)
-      q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
-#else
-      q = div_asm(n0, n1, d0);
-#endif
-
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
-      /* rem doesn't have to be BN_ULLONG. The least we know it's less that d0,
-       * isn't it? */
-      rem = (n1 - q * d0) & BN_MASK2;
-#endif
-
-      t2 = (BN_ULLONG)d1 * q;
-
+      BN_ULLONG t2 = (BN_ULLONG)d1 * q;
       for (;;) {
         if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
           break;
@@ -290,33 +348,7 @@
       }
 #else /* !BN_ULLONG */
       BN_ULONG t2l, t2h;
-
-#if defined(div_asm)
-      q = div_asm(n0, n1, d0);
-#else
-      q = bn_div_words(n0, n1, d0);
-#endif
-
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
-      rem = (n1 - q * d0) & BN_MASK2;
-#endif
-
-#if defined(BN_UMULT_LOHI)
       BN_UMULT_LOHI(t2l, t2h, d1, q);
-#elif defined(BN_UMULT_HIGH)
-      t2l = d1 * q;
-      t2h = BN_UMULT_HIGH(d1, q);
-#else
-      {
-        BN_ULONG ql, qh;
-        t2l = LBITS(d1);
-        t2h = HBITS(d1);
-        ql = LBITS(q);
-        qh = HBITS(q);
-        mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
-      }
-#endif
-
       for (;;) {
         if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
           break;
@@ -576,7 +608,7 @@
     return 0;
   }
 
-  /* normalize input (so bn_div_words doesn't complain) */
+  /* normalize input for |bn_div_rem_words|. */
   j = BN_BITS2 - BN_num_bits_word(w);
   w <<= j;
   if (!BN_lshift(a, a, j)) {
@@ -584,10 +616,10 @@
   }
 
   for (i = a->top - 1; i >= 0; i--) {
-    BN_ULONG l, d;
-
-    l = a->d[i];
-    d = bn_div_words(ret, l, w);
+    BN_ULONG l = a->d[i];
+    BN_ULONG d;
+    BN_ULONG unused_rem;
+    bn_div_rem_words(&d, &unused_rem, ret, l, w);
     ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
     a->d[i] = d;
   }
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index 72a8db4..bb7a2f4 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -209,6 +209,7 @@
   BN_init(&recp->N);
   BN_init(&recp->Nr);
   recp->num_bits = 0;
+  recp->shift = 0;
   recp->flags = 0;
 }
 
@@ -787,29 +788,65 @@
  * pattern as far as cache lines are concerned. The following functions are
  * used to transfer a BIGNUM from/to that table. */
 static int copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, int idx,
-                          int width) {
-  size_t i, j;
+                          int window) {
+  int i, j;
+  const int width = 1 << window;
+  BN_ULONG *table = (BN_ULONG *) buf;
 
   if (top > b->top) {
     top = b->top; /* this works because 'buf' is explicitly zeroed */
   }
-  for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
-    buf[j] = ((unsigned char *)b->d)[i];
+
+  for (i = 0, j = idx; i < top; i++, j += width)  {
+    table[j] = b->d[i];
   }
 
   return 1;
 }
 
 static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
-                            int width) {
-  size_t i, j;
+                            int window) {
+  int i, j;
+  const int width = 1 << window;
+  volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
 
   if (bn_wexpand(b, top) == NULL) {
     return 0;
   }
 
-  for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
-    ((unsigned char *)b->d)[i] = buf[j];
+  if (window <= 3) {
+    for (i = 0; i < top; i++, table += width) {
+      BN_ULONG acc = 0;
+
+      for (j = 0; j < width; j++) {
+        acc |= table[j] & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
+      }
+
+      b->d[i] = acc;
+    }
+  } else {
+    int xstride = 1 << (window - 2);
+    BN_ULONG y0, y1, y2, y3;
+
+    i = idx >> (window - 2); /* equivalent of idx / xstride */
+    idx &= xstride - 1;      /* equivalent of idx % xstride */
+
+    y0 = (BN_ULONG)0 - (constant_time_eq_int(i, 0) & 1);
+    y1 = (BN_ULONG)0 - (constant_time_eq_int(i, 1) & 1);
+    y2 = (BN_ULONG)0 - (constant_time_eq_int(i, 2) & 1);
+    y3 = (BN_ULONG)0 - (constant_time_eq_int(i, 3) & 1);
+
+    for (i = 0; i < top; i++, table += width) {
+      BN_ULONG acc = 0;
+
+      for (j = 0; j < xstride; j++) {
+        acc |= ((table[j + 0 * xstride] & y0) | (table[j + 1 * xstride] & y1) |
+                (table[j + 2 * xstride] & y2) | (table[j + 3 * xstride] & y3)) &
+               ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
+      }
+
+      b->d[i] = acc;
+    }
   }
 
   b->top = top;
@@ -891,8 +928,6 @@
     return BN_one(rr);
   }
 
-  BN_CTX_start(ctx);
-
   /* Allocate a montgomery context if it was not supplied by the caller. */
   if (mont == NULL) {
     new_mont = BN_MONT_CTX_new();
@@ -935,9 +970,8 @@
 #if defined(OPENSSL_BN_ASM_MONT5)
   if (window >= 5) {
     window = 5; /* ~5% improvement for RSA2048 sign, and even for RSA4096 */
-    if ((top & 7) == 0) {
-      powerbufLen += 2 * top * sizeof(m->d[0]);
-    }
+    /* reserve space for mont->N.d[] copy */
+    powerbufLen += top * sizeof(mont->N.d[0]);
   }
 #endif
 
@@ -954,7 +988,7 @@
   } else
 #endif
   {
-    if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
+    if ((powerbufFree = OPENSSL_malloc(
             powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) {
       goto err;
     }
@@ -1008,7 +1042,8 @@
   /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
    * 512-bit RSA is hardly relevant, we omit it to spare size... */
   if (window == 5 && top > 1) {
-    const BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
+    const BN_ULONG *n0 = mont->n0;
+    BN_ULONG *np;
 
     /* BN_to_montgomery can contaminate words above .top
      * [in BN_DEBUG[_DEBUG] build]... */
@@ -1019,14 +1054,9 @@
       tmp.d[i] = 0;
     }
 
-    if (top & 7) {
-      np2 = np;
-    } else {
-      BN_ULONG *np_double = am.d + top;
-      for (i = 0; i < top; i++) {
-        np_double[2 * i] = np[i];
-      }
-      np2 = np_double;
+    /* copy mont->N.d[] to improve cache locality */
+    for (np = am.d + top, i = 0; i < top; i++) {
+      np[i] = mont->N.d[i];
     }
 
     bn_scatter5(tmp.d, top, powerbuf, 0);
@@ -1041,7 +1071,7 @@
     }
     for (i = 3; i < 8; i += 2) {
       int j;
-      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
       bn_scatter5(tmp.d, top, powerbuf, i);
       for (j = 2 * i; j < 32; j *= 2) {
         bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
@@ -1049,13 +1079,13 @@
       }
     }
     for (; i < 16; i += 2) {
-      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
       bn_scatter5(tmp.d, top, powerbuf, i);
       bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
       bn_scatter5(tmp.d, top, powerbuf, 2 * i);
     }
     for (; i < 32; i += 2) {
-      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+      bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
       bn_scatter5(tmp.d, top, powerbuf, i);
     }
 
@@ -1103,7 +1133,7 @@
         wvalue >>= (bits - 4) & 7;
         wvalue &= 0x1f;
         bits -= 5;
-        bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
+        bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
       }
       while (bits >= 0) {
         /* Read five bits from |bits-4| through |bits|, inclusive. */
@@ -1112,11 +1142,11 @@
         wvalue >>= first_bit & 7;
         wvalue &= 0x1f;
         bits -= 5;
-        bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
+        bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
       }
     }
 
-    ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np2, n0, top);
+    ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
     tmp.top = top;
     bn_correct_top(&tmp);
     if (ret) {
@@ -1128,8 +1158,8 @@
   } else
 #endif
   {
-    if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers) ||
-        !copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
+    if (!copy_to_prebuf(&tmp, top, powerbuf, 0, window) ||
+        !copy_to_prebuf(&am, top, powerbuf, 1, window)) {
       goto err;
     }
 
@@ -1140,13 +1170,13 @@
      */
     if (window > 1) {
       if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx) ||
-          !copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
+          !copy_to_prebuf(&tmp, top, powerbuf, 2, window)) {
         goto err;
       }
       for (i = 3; i < numPowers; i++) {
         /* Calculate a^i = a^(i-1) * a */
         if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx) ||
-            !copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
+            !copy_to_prebuf(&tmp, top, powerbuf, i, window)) {
           goto err;
         }
       }
@@ -1156,7 +1186,7 @@
     for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) {
       wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
     }
-    if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers)) {
+    if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, window)) {
       goto err;
     }
 
@@ -1175,7 +1205,7 @@
       }
 
       /* Fetch the appropriate pre-computed value from the pre-buf */
-      if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
+      if (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) {
         goto err;
       }
 
@@ -1198,7 +1228,6 @@
     OPENSSL_cleanse(powerbuf, powerbufLen);
     OPENSSL_free(powerbufFree);
   }
-  BN_CTX_end(ctx);
   return (ret);
 }
 
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index 7303ca5..f552d99 100644
--- a/src/crypto/bn/generic.c
+++ b/src/crypto/bn/generic.c
@@ -61,13 +61,10 @@
 #include "internal.h"
 
 
-/* Generic implementations of most operations are needed for:
- * - Configurations without inline assembly.
- * - Architectures other than x86 or x86_64.
- * - Windows x84_64; x86_64-gcc.c does not build on MSVC. */
+/* This file has two other implementations: x86 assembly language in
+ * asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. */
 #if defined(OPENSSL_NO_ASM) || \
-    (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
-    (defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
+    !(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
 
 #ifdef BN_ULLONG
 #define mul_add(r, a, w, c)             \
@@ -94,7 +91,8 @@
     (r1) = Hw(t);             \
   }
 
-#elif defined(BN_UMULT_LOHI)
+#else
+
 #define mul_add(r, a, w, c)             \
   {                                     \
     BN_ULONG high, low, ret, tmp = (a); \
@@ -124,102 +122,8 @@
     BN_UMULT_LOHI(r0, r1, tmp, tmp); \
   }
 
-#else
-
-/*************************************************************
- * No long long type
- */
-
-#define LBITS(a) ((a) & BN_MASK2l)
-#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
-#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
-
-#define LLBITS(a) ((a) & BN_MASKl)
-#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
-#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
-
-#define mul64(l, h, bl, bh)       \
-  {                               \
-    BN_ULONG m, m1, lt, ht;       \
-                                  \
-    lt = l;                       \
-    ht = h;                       \
-    m = (bh) * (lt);              \
-    lt = (bl) * (lt);             \
-    m1 = (bl) * (ht);             \
-    ht = (bh) * (ht);             \
-    m = (m + m1) & BN_MASK2;      \
-    if (m < m1)                   \
-      ht += L2HBITS((BN_ULONG)1); \
-    ht += HBITS(m);               \
-    m1 = L2HBITS(m);              \
-    lt = (lt + m1) & BN_MASK2;    \
-    if (lt < m1)                  \
-      ht++;                       \
-    (l) = lt;                     \
-    (h) = ht;                     \
-  }
-
-#define sqr64(lo, ho, in)                    \
-  {                                          \
-    BN_ULONG l, h, m;                        \
-                                             \
-    h = (in);                                \
-    l = LBITS(h);                            \
-    h = HBITS(h);                            \
-    m = (l) * (h);                           \
-    l *= l;                                  \
-    h *= h;                                  \
-    h += (m & BN_MASK2h1) >> (BN_BITS4 - 1); \
-    m = (m & BN_MASK2l) << (BN_BITS4 + 1);   \
-    l = (l + m) & BN_MASK2;                  \
-    if (l < m)                               \
-      h++;                                   \
-    (lo) = l;                                \
-    (ho) = h;                                \
-  }
-
-#define mul_add(r, a, bl, bh, c) \
-  {                              \
-    BN_ULONG l, h;               \
-                                 \
-    h = (a);                     \
-    l = LBITS(h);                \
-    h = HBITS(h);                \
-    mul64(l, h, (bl), (bh));     \
-                                 \
-    /* non-multiply part */      \
-    l = (l + (c)) & BN_MASK2;    \
-    if (l < (c))                 \
-      h++;                       \
-    (c) = (r);                   \
-    l = (l + (c)) & BN_MASK2;    \
-    if (l < (c))                 \
-      h++;                       \
-    (c) = h & BN_MASK2;          \
-    (r) = l;                     \
-  }
-
-#define mul(r, a, bl, bh, c)  \
-  {                           \
-    BN_ULONG l, h;            \
-                              \
-    h = (a);                  \
-    l = LBITS(h);             \
-    h = HBITS(h);             \
-    mul64(l, h, (bl), (bh));  \
-                              \
-    /* non-multiply part */   \
-    l += (c);                 \
-    if ((l & BN_MASK2) < (c)) \
-      h++;                    \
-    (c) = h & BN_MASK2;       \
-    (r) = l & BN_MASK2;       \
-  }
 #endif /* !BN_ULLONG */
 
-#if defined(BN_ULLONG) || defined(BN_UMULT_HIGH)
-
 BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
                           BN_ULONG w) {
   BN_ULONG c1 = 0;
@@ -298,174 +202,6 @@
   }
 }
 
-#else /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
-
-BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
-                          BN_ULONG w) {
-  BN_ULONG c = 0;
-  BN_ULONG bl, bh;
-
-  assert(num >= 0);
-  if (num <= 0) {
-    return (BN_ULONG)0;
-  }
-
-  bl = LBITS(w);
-  bh = HBITS(w);
-
-  while (num & ~3) {
-    mul_add(rp[0], ap[0], bl, bh, c);
-    mul_add(rp[1], ap[1], bl, bh, c);
-    mul_add(rp[2], ap[2], bl, bh, c);
-    mul_add(rp[3], ap[3], bl, bh, c);
-    ap += 4;
-    rp += 4;
-    num -= 4;
-  }
-  while (num) {
-    mul_add(rp[0], ap[0], bl, bh, c);
-    ap++;
-    rp++;
-    num--;
-  }
-  return c;
-}
-
-BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
-  BN_ULONG carry = 0;
-  BN_ULONG bl, bh;
-
-  assert(num >= 0);
-  if (num <= 0) {
-    return (BN_ULONG)0;
-  }
-
-  bl = LBITS(w);
-  bh = HBITS(w);
-
-  while (num & ~3) {
-    mul(rp[0], ap[0], bl, bh, carry);
-    mul(rp[1], ap[1], bl, bh, carry);
-    mul(rp[2], ap[2], bl, bh, carry);
-    mul(rp[3], ap[3], bl, bh, carry);
-    ap += 4;
-    rp += 4;
-    num -= 4;
-  }
-  while (num) {
-    mul(rp[0], ap[0], bl, bh, carry);
-    ap++;
-    rp++;
-    num--;
-  }
-  return carry;
-}
-
-void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
-  assert(n >= 0);
-  if (n <= 0) {
-    return;
-  }
-
-  while (n & ~3) {
-    sqr64(r[0], r[1], a[0]);
-    sqr64(r[2], r[3], a[1]);
-    sqr64(r[4], r[5], a[2]);
-    sqr64(r[6], r[7], a[3]);
-    a += 4;
-    r += 8;
-    n -= 4;
-  }
-  while (n) {
-    sqr64(r[0], r[1], a[0]);
-    a++;
-    r += 2;
-    n--;
-  }
-}
-
-#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
-
-#if defined(BN_ULLONG)
-
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
-  return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
-}
-
-#else
-
-/* Divide h,l by d and return the result. */
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
-  BN_ULONG dh, dl, q, ret = 0, th, tl, t;
-  int i, count = 2;
-
-  if (d == 0) {
-    return BN_MASK2;
-  }
-
-  i = BN_num_bits_word(d);
-  assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
-
-  i = BN_BITS2 - i;
-  if (h >= d) {
-    h -= d;
-  }
-
-  if (i) {
-    d <<= i;
-    h = (h << i) | (l >> (BN_BITS2 - i));
-    l <<= i;
-  }
-  dh = (d & BN_MASK2h) >> BN_BITS4;
-  dl = (d & BN_MASK2l);
-  for (;;) {
-    if ((h >> BN_BITS4) == dh) {
-      q = BN_MASK2l;
-    } else {
-      q = h / dh;
-    }
-
-    th = q * dh;
-    tl = dl * q;
-    for (;;) {
-      t = h - th;
-      if ((t & BN_MASK2h) ||
-          ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
-        break;
-      }
-      q--;
-      th -= dh;
-      tl -= dl;
-    }
-    t = (tl >> BN_BITS4);
-    tl = (tl << BN_BITS4) & BN_MASK2h;
-    th += t;
-
-    if (l < tl) {
-      th++;
-    }
-    l -= tl;
-    if (h < th) {
-      h += d;
-      q--;
-    }
-    h -= th;
-
-    if (--count == 0) {
-      break;
-    }
-
-    ret = q << BN_BITS4;
-    h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
-    l = (l & BN_MASK2l) << BN_BITS4;
-  }
-
-  ret |= q;
-  return ret;
-}
-
-#endif /* !defined(BN_ULLONG) */
-
 #ifdef BN_ULLONG
 BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
                       int n) {
@@ -673,7 +409,7 @@
 
 #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
 
-#elif defined(BN_UMULT_LOHI)
+#else
 
 /* Keep in mind that additions to hi can not overflow, because the high word of
  * a multiplication result cannot be all-ones. */
@@ -716,58 +452,6 @@
 
 #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
 
-#else /* !BN_ULLONG */
-
-/* Keep in mind that additions to hi can not overflow, because
- * the high word of a multiplication result cannot be all-ones. */
-
-#define mul_add_c(a, b, c0, c1, c2)        \
-  do {                                     \
-    BN_ULONG lo = LBITS(a), hi = HBITS(a); \
-    BN_ULONG bl = LBITS(b), bh = HBITS(b); \
-    mul64(lo, hi, bl, bh);                 \
-    c0 = (c0 + lo) & BN_MASK2;             \
-    if (c0 < lo)                           \
-      hi++;                                \
-    c1 = (c1 + hi) & BN_MASK2;             \
-    if (c1 < hi)                           \
-      c2++;                                \
-  } while (0)
-
-#define mul_add_c2(a, b, c0, c1, c2)       \
-  do {                                     \
-    BN_ULONG tt;                           \
-    BN_ULONG lo = LBITS(a), hi = HBITS(a); \
-    BN_ULONG bl = LBITS(b), bh = HBITS(b); \
-    mul64(lo, hi, bl, bh);                 \
-    tt = hi;                               \
-    c0 = (c0 + lo) & BN_MASK2;             \
-    if (c0 < lo)                           \
-      tt++;                                \
-    c1 = (c1 + tt) & BN_MASK2;             \
-    if (c1 < tt)                           \
-      c2++;                                \
-    c0 = (c0 + lo) & BN_MASK2;             \
-    if (c0 < lo)                           \
-      hi++;                                \
-    c1 = (c1 + hi) & BN_MASK2;             \
-    if (c1 < hi)                           \
-      c2++;                                \
-  } while (0)
-
-#define sqr_add_c(a, i, c0, c1, c2) \
-  do {                              \
-    BN_ULONG lo, hi;                \
-    sqr64(lo, hi, (a)[i]);          \
-    c0 = (c0 + lo) & BN_MASK2;      \
-    if (c0 < lo)                    \
-      hi++;                         \
-    c1 = (c1 + hi) & BN_MASK2;      \
-    if (c1 < hi)                    \
-      c2++;                         \
-  } while (0)
-
-#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
 #endif /* !BN_ULLONG */
 
 void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 72ef4e9..0a2982c 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -125,13 +125,15 @@
 
 #include <openssl/base.h>
 
-#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
+#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
 #pragma warning(push, 3)
 #include <intrin.h>
 #pragma warning(pop)
 #pragma intrinsic(__umulh, _umul128)
 #endif
 
+#include "../internal.h"
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
@@ -144,7 +146,7 @@
 
 #if !defined(_MSC_VER)
 /* MSVC doesn't support two-word integers on 64-bit. */
-#define BN_ULLONG	__uint128_t
+#define BN_ULLONG	uint128_t
 #endif
 
 #define BN_BITS2	64
@@ -179,14 +181,6 @@
 #endif
 
 
-/* Pentium pro 16,16,16,32,64 */
-/* Alpha       16,16,16,16.64 */
-#define BN_MULL_SIZE_NORMAL (16)              /* 32 */
-#define BN_MUL_RECURSIVE_SIZE_NORMAL (16)     /* 32 less than */
-#define BN_SQR_RECURSIVE_SIZE_NORMAL (16)     /* 32 */
-#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
-#define BN_MONT_CTX_SET_SIZE_WORD (64)        /* 32 */
-
 #define STATIC_BIGNUM(x)                                \
   {                                                     \
     (BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG),        \
@@ -198,10 +192,14 @@
 #define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
 #endif
 
+
+/* bn_set_words sets |bn| to the value encoded in the |num| words in |words|,
+ * least significant word first. */
+int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num);
+
 BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
 BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
 BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
 
@@ -223,67 +221,12 @@
 int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                 const BN_ULONG *np, const BN_ULONG *n0, int num);
 
-#if !defined(BN_ULLONG)
+#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
+#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
+#endif
 
-#define LBITS(a) ((a) & BN_MASK2l)
-#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
-#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
-
-#define LLBITS(a) ((a) & BN_MASKl)
-#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
-#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
-
-#define mul64(l, h, bl, bh)       \
-  {                               \
-    BN_ULONG m, m1, lt, ht;       \
-                                  \
-    lt = l;                       \
-    ht = h;                       \
-    m = (bh) * (lt);              \
-    lt = (bl) * (lt);             \
-    m1 = (bl) * (ht);             \
-    ht = (bh) * (ht);             \
-    m = (m + m1) & BN_MASK2;      \
-    if (m < m1)                   \
-      ht += L2HBITS((BN_ULONG)1); \
-    ht += HBITS(m);               \
-    m1 = L2HBITS(m);              \
-    lt = (lt + m1) & BN_MASK2;    \
-    if (lt < m1)                  \
-      ht++;                       \
-    (l) = lt;                     \
-    (h) = ht;                     \
-  }
-
-#endif  /* !defined(BN_ULLONG) */
-
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
-# if defined(__GNUC__) && __GNUC__ >= 2
-#  define BN_UMULT_HIGH(a,b)	({	\
-	register BN_ULONG ret,discard;	\
-	__asm__ ("mulq	%3"		\
-	     : "=a"(discard),"=d"(ret)	\
-	     : "a"(a), "g"(b)		\
-	     : "cc");			\
-	ret;			})
-#  define BN_UMULT_LOHI(low,high,a,b)	\
-	__asm__ ("mulq	%3"		\
-		: "=a"(low),"=d"(high)	\
-		: "a"(a),"g"(b)		\
-		: "cc");
-# elif defined(_MSC_VER) && _MSC_VER >= 1400
-#  define BN_UMULT_HIGH(a, b) __umulh((a), (b))
-#  define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
-# endif
-#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
-# if defined(__GNUC__) && __GNUC__>=2
-#  define BN_UMULT_HIGH(a,b)	({	\
-	register BN_ULONG ret;		\
-	__asm__ ("umulh	%0,%1,%2"	\
-	     : "=r"(ret)		\
-	     : "r"(a), "r"(b));		\
-	ret;			})
-# endif
+#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI)
+#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform."
 #endif
 
 
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index 18da0da..f56998e 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -289,14 +289,14 @@
   return ret;
 }
 
-BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
-                                    const BIGNUM *mod, BN_CTX *bn_ctx) {
+int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
+                           const BIGNUM *mod, BN_CTX *bn_ctx) {
   CRYPTO_MUTEX_lock_read(lock);
   BN_MONT_CTX *ctx = *pmont;
   CRYPTO_MUTEX_unlock(lock);
 
   if (ctx) {
-    return ctx;
+    return 1;
   }
 
   CRYPTO_MUTEX_lock_write(lock);
@@ -318,7 +318,7 @@
 
 out:
   CRYPTO_MUTEX_unlock(lock);
-  return ctx;
+  return ctx != NULL;
 }
 
 int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
@@ -326,14 +326,12 @@
   return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx);
 }
 
-#if 0
 static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
                                    const BN_MONT_CTX *mont) {
-  const BIGNUM *n;
   BN_ULONG *ap, *np, *rp, n0, v, carry;
   int nl, max, i;
 
-  n = &mont->N;
+  const BIGNUM *n = &mont->N;
   nl = n->top;
   if (nl == 0) {
     ret->top = 0;
@@ -376,13 +374,13 @@
 
   {
     BN_ULONG *nrp;
-    size_t m;
+    uintptr_t m;
 
     v = bn_sub_words(rp, ap, np, nl) - carry;
     /* if subtraction result is real, then trick unconditional memcpy below to
      * perform in-place "refresh" instead of actual copy. */
-    m = (0 - (size_t)v);
-    nrp = (BN_ULONG *)(((intptr_t)rp & ~m) | ((intptr_t)ap & m));
+    m = (0u - (uintptr_t)v);
+    nrp = (BN_ULONG *)(((uintptr_t)rp & ~m) | ((uintptr_t)ap & m));
 
     for (i = 0, nl -= 4; i < nl; i += 4) {
       BN_ULONG t1, t2, t3, t4;
@@ -411,104 +409,25 @@
 
   return 1;
 }
-#endif
 
-#define PTR_SIZE_INT size_t
-
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, const BN_MONT_CTX *mont)
-	{
-	BIGNUM *n;
-	BN_ULONG *ap,*np,*rp,n0,v,carry;
-	int nl,max,i;
-
-	n= (BIGNUM*) &(mont->N);
-	nl=n->top;
-	if (nl == 0) { ret->top=0; return(1); }
-
-	max=(2*nl); /* carry is stored separately */
-	if (bn_wexpand(r,max) == NULL) return(0);
-
-	r->neg^=n->neg;
-	np=n->d;
-	rp=r->d;
-
-	/* clear the top words of T */
-#if 1
-	for (i=r->top; i<max; i++) /* memset? XXX */
-		rp[i]=0;
-#else
-	memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
-#endif
-
-	r->top=max;
-	n0=mont->n0[0];
-
-	for (carry=0, i=0; i<nl; i++, rp++)
-		{
-		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
-		v = (v+carry+rp[nl])&BN_MASK2;
-		carry |= (v != rp[nl]);
-		carry &= (v <= rp[nl]);
-		rp[nl]=v;
-		}
-
-	if (bn_wexpand(ret,nl) == NULL) return(0);
-	ret->top=nl;
-	ret->neg=r->neg;
-
-	rp=ret->d;
-	ap=&(r->d[nl]);
-
-	{
-	BN_ULONG *nrp;
-	size_t m;
-
-	v=bn_sub_words(rp,ap,np,nl)-carry;
-	/* if subtraction result is real, then
-	 * trick unconditional memcpy below to perform in-place
-	 * "refresh" instead of actual copy. */
-	m=(0-(size_t)v);
-	nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
-
-	for (i=0,nl-=4; i<nl; i+=4)
-		{
-		BN_ULONG t1,t2,t3,t4;
-		
-		t1=nrp[i+0];
-		t2=nrp[i+1];
-		t3=nrp[i+2];	ap[i+0]=0;
-		t4=nrp[i+3];	ap[i+1]=0;
-		rp[i+0]=t1;	ap[i+2]=0;
-		rp[i+1]=t2;	ap[i+3]=0;
-		rp[i+2]=t3;
-		rp[i+3]=t4;
-		}
-	for (nl+=4; i<nl; i++)
-		rp[i]=nrp[i], ap[i]=0;
-	}
-	bn_correct_top(r);
-	bn_correct_top(ret);
-
-	return(1);
-	}
-
-int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont,
                        BN_CTX *ctx) {
-  int retn = 0;
+  int ret = 0;
   BIGNUM *t;
 
   BN_CTX_start(ctx);
   t = BN_CTX_get(ctx);
-  if (t == NULL) {
-    return 0;
+  if (t == NULL ||
+      !BN_copy(t, a)) {
+    goto err;
   }
 
-  if (BN_copy(t, a)) {
-    retn = BN_from_montgomery_word(ret, t, mont);
-  }
+  ret = BN_from_montgomery_word(r, t, mont);
+
+err:
   BN_CTX_end(ctx);
 
-  return retn;
+  return ret;
 }
 
 int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
diff --git a/src/crypto/bn/mul.c b/src/crypto/bn/mul.c
index 029a59e..06e53ee 100644
--- a/src/crypto/bn/mul.c
+++ b/src/crypto/bn/mul.c
@@ -62,7 +62,12 @@
 #include "internal.h"
 
 
-void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) {
+#define BN_MUL_RECURSIVE_SIZE_NORMAL 16
+#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL
+
+
+static void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
+                          int nb) {
   BN_ULONG *rr;
 
   if (na < nb) {
@@ -107,31 +112,6 @@
   }
 }
 
-void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
-  bn_mul_words(r, a, n, b[0]);
-
-  for (;;) {
-    if (--n <= 0) {
-      return;
-    }
-    bn_mul_add_words(&(r[1]), a, n, b[1]);
-    if (--n <= 0) {
-      return;
-    }
-    bn_mul_add_words(&(r[2]), a, n, b[2]);
-    if (--n <= 0) {
-      return;
-    }
-    bn_mul_add_words(&(r[3]), a, n, b[3]);
-    if (--n <= 0) {
-      return;
-    }
-    bn_mul_add_words(&(r[4]), a, n, b[4]);
-    r += 4;
-    b += 4;
-  }
-}
-
 #if !defined(OPENSSL_X86) || defined(OPENSSL_NO_ASM)
 /* Here follows specialised variants of bn_add_words() and bn_sub_words(). They
  * have the property performing operations on arrays of different sizes. The
@@ -618,7 +598,8 @@
     }
   }
 
-  if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+  static const int kMulNormalSize = 16;
+  if (al >= kMulNormalSize && bl >= kMulNormalSize) {
     if (i >= -1 && i <= 1) {
       /* Find out the power of two lower or equal
          to the longest of the two numbers */
diff --git a/src/crypto/bn/rsaz_exp.c b/src/crypto/bn/rsaz_exp.c
index c802752..30f08e5 100644
--- a/src/crypto/bn/rsaz_exp.c
+++ b/src/crypto/bn/rsaz_exp.c
@@ -48,6 +48,9 @@
 
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 /*
  * See crypto/bn/asm/rsaz-avx2.pl for further details.
  */
@@ -58,42 +61,30 @@
 void rsaz_1024_gather5_avx2(void *val,const void *tbl,int i);
 void rsaz_1024_red2norm_avx2(void *norm,const void *red);
 
-#if defined(__GNUC__)
-# define ALIGN64	__attribute__((aligned(64)))
-#elif defined(_MSC_VER)
-# define ALIGN64	__declspec(align(64))
-#elif defined(__SUNPRO_C)
-# define ALIGN64
-# pragma align 64(one,two80)
-#else
-# define ALIGN64	/* not fatal, might hurt performance a little */
-#endif
-
-ALIGN64 static const BN_ULONG one[40] =
+alignas(64) static const BN_ULONG one[40] =
 	{1,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-ALIGN64 static const BN_ULONG two80[40] =
+alignas(64) static const BN_ULONG two80[40] =
 	{0,0,1<<22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
 void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
 	const BN_ULONG base_norm[16], const BN_ULONG exponent[16],
 	const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0)
 {
-	unsigned char	 storage[320*3+32*9*16+64];	/* 5.5KB */
-	unsigned char	*p_str = storage + (64-((size_t)storage%64));
+	alignas(64) uint8_t storage[(320 * 3) + (32 * 9 * 16)]; /* 5.5KB */
 	unsigned char	*a_inv, *m, *result,
-			*table_s = p_str+320*3,
+			*table_s = storage + (320 * 3),
 			*R2      = table_s;	/* borrow */
 	int index;
 	int wvalue;
 
-	if ((((size_t)p_str&4095)+320)>>12) {
-		result = p_str;
-		a_inv = p_str + 320;
-		m = p_str + 320*2;	/* should not cross page */
+	if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) {
+		result = storage;
+		a_inv = storage + 320;
+		m = storage + (320 * 2); /* should not cross page */
 	} else {
-		m = p_str;		/* should not cross page */
-		result = p_str + 320;
-		a_inv = p_str + 320*2;
+		m = storage;		/* should not cross page */
+		result = storage + 320;
+		a_inv = storage + (320 * 2);
 	}
 
 	rsaz_1024_norm2red_avx2(m, m_norm);
@@ -224,8 +215,9 @@
 	rsaz_1024_scatter5_avx2(table_s,result,31);
 #endif
 
+	const uint8_t *p_str = (const uint8_t *)exponent;
+
 	/* load first window */
-	p_str = (unsigned char*)exponent;
 	wvalue = p_str[127] >> 3;
 	rsaz_1024_gather5_avx2(result,table_s,wvalue);
 
@@ -235,7 +227,7 @@
 
 		rsaz_1024_sqr_avx2(result, result, m, k0, 5);
 
-		wvalue = *((unsigned short*)&p_str[index/8]);
+		wvalue = *((const unsigned short*)&p_str[index / 8]);
 		wvalue = (wvalue>> (index%8)) & 31;
 		index-=5;
 
@@ -274,11 +266,10 @@
 	const BN_ULONG base[8], const BN_ULONG exponent[8],
 	const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
 {
-	unsigned char	 storage[16*8*8+64*2+64];	/* 1.2KB */
-	unsigned char	*table = storage + (64-((size_t)storage%64));
+	alignas(64) uint8_t storage[(16*8*8) + (64 * 2)]; /* 1.2KB */
+	unsigned char	*table = storage;
 	BN_ULONG	*a_inv = (BN_ULONG *)(table+16*8*8),
 			*temp  = (BN_ULONG *)(table+16*8*8+8*8);
-	unsigned char	*p_str = (unsigned char*)exponent;
 	int index;
 	unsigned int wvalue;
 
@@ -300,6 +291,8 @@
 	for (index=3; index<16; index++)
 		rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
 
+	const uint8_t *p_str = (const uint8_t *)exponent;
+
 	/* load first window */
 	wvalue = p_str[63];
 
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index 33d3c21..362e702 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -5,6 +5,7 @@
 
   OBJECT
 
+  asn1_compat.c
   ber.c
   cbs.c
   cbb.c
diff --git a/src/crypto/bytestring/asn1_compat.c b/src/crypto/bytestring/asn1_compat.c
new file mode 100644
index 0000000..b17d2d1
--- /dev/null
+++ b/src/crypto/bytestring/asn1_compat.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+
+#include <openssl/bytestring.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+int CBB_finish_i2d(CBB *cbb, uint8_t **outp) {
+  assert(cbb->base->can_resize);
+
+  uint8_t *der;
+  size_t der_len;
+  if (!CBB_finish(cbb, &der, &der_len)) {
+    CBB_cleanup(cbb);
+    return -1;
+  }
+  if (der_len > INT_MAX) {
+    OPENSSL_free(der);
+    return -1;
+  }
+  if (outp != NULL) {
+    if (*outp == NULL) {
+      *outp = der;
+      der = NULL;
+    } else {
+      memcpy(*outp, der, der_len);
+      *outp += der_len;
+    }
+  }
+  OPENSSL_free(der);
+  return (int)der_len;
+}
diff --git a/src/crypto/bytestring/ber.c b/src/crypto/bytestring/ber.c
index 9e8daaa..04fcac6 100644
--- a/src/crypto/bytestring/ber.c
+++ b/src/crypto/bytestring/ber.c
@@ -14,6 +14,7 @@
 
 #include <openssl/bytestring.h>
 
+#include <assert.h>
 #include <string.h>
 
 #include "internal.h"
@@ -24,11 +25,37 @@
  * input could otherwise cause the stack to overflow. */
 static const unsigned kMaxDepth = 2048;
 
+/* is_string_type returns one if |tag| is a string type and zero otherwise. It
+ * ignores the constructed bit. */
+static int is_string_type(unsigned tag) {
+  if ((tag & 0xc0) != 0) {
+    return 0;
+  }
+  switch (tag & 0x1f) {
+    case CBS_ASN1_BITSTRING:
+    case CBS_ASN1_OCTETSTRING:
+    case CBS_ASN1_UTF8STRING:
+    case CBS_ASN1_NUMERICSTRING:
+    case CBS_ASN1_PRINTABLESTRING:
+    case CBS_ASN1_T16STRING:
+    case CBS_ASN1_VIDEOTEXSTRING:
+    case CBS_ASN1_IA5STRING:
+    case CBS_ASN1_GRAPHICSTRING:
+    case CBS_ASN1_VISIBLESTRING:
+    case CBS_ASN1_GENERALSTRING:
+    case CBS_ASN1_UNIVERSALSTRING:
+    case CBS_ASN1_BMPSTRING:
+      return 1;
+    default:
+      return 0;
+  }
+}
+
 /* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
- * depending on whether an indefinite length element was found. The value of
- * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
- * and zero on error. */
-static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
+ * depending on whether an indefinite length element or constructed string was
+ * found. The value of |orig_in| is not changed. It returns one on success (i.e.
+ * |*ber_found| was set) and zero on error. */
+static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) {
   CBS in;
 
   if (depth > kMaxDepth) {
@@ -49,10 +76,16 @@
     if (CBS_len(&contents) == header_len &&
         header_len > 0 &&
         CBS_data(&contents)[header_len-1] == 0x80) {
+      /* Found an indefinite-length element. */
       *ber_found = 1;
       return 1;
     }
     if (tag & CBS_ASN1_CONSTRUCTED) {
+      if (is_string_type(tag)) {
+        /* Constructed strings are only legal in BER and require conversion. */
+        *ber_found = 1;
+        return 1;
+      }
       if (!CBS_skip(&contents, header_len) ||
           !cbs_find_ber(&contents, ber_found, depth + 1)) {
         return 0;
@@ -63,16 +96,6 @@
   return 1;
 }
 
-/* is_primitive_type returns true if |tag| likely a primitive type. Normally
- * one can just test the "constructed" bit in the tag but, in BER, even
- * primitive tags can have the constructed bit if they have indefinite
- * length. */
-static char is_primitive_type(unsigned tag) {
-  return (tag & 0xc0) == 0 &&
-         (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
-         (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
-}
-
 /* is_eoc returns true if |header_len| and |contents|, as returned by
  * |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. */
 static char is_eoc(size_t header_len, CBS *contents) {
@@ -81,111 +104,86 @@
 }
 
 /* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
- * |squash_header| is set then the top-level of elements from |in| will not
- * have their headers written. This is used when concatenating the fragments of
- * an indefinite length, primitive value. If |looking_for_eoc| is set then any
- * EOC elements found will cause the function to return after consuming it.
- * It returns one on success and zero on error. */
-static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
+ * |string_tag| is non-zero, then all elements must match |string_tag| up to the
+ * constructed bit and primitive element bodies are written to |out| without
+ * element headers. This is used when concatenating the fragments of a
+ * constructed string. If |looking_for_eoc| is set then any EOC elements found
+ * will cause the function to return after consuming it. It returns one on
+ * success and zero on error. */
+static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
                            char looking_for_eoc, unsigned depth) {
+  assert(!(string_tag & CBS_ASN1_CONSTRUCTED));
+
   if (depth > kMaxDepth) {
     return 0;
   }
 
   while (CBS_len(in) > 0) {
     CBS contents;
-    unsigned tag;
+    unsigned tag, child_string_tag = string_tag;
     size_t header_len;
     CBB *out_contents, out_contents_storage;
 
     if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) {
       return 0;
     }
-    out_contents = out;
 
-    if (CBS_len(&contents) == header_len) {
-      if (is_eoc(header_len, &contents)) {
-        return looking_for_eoc;
-      }
-
-      if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
-        /* This is an indefinite length element. If it's a SEQUENCE or SET then
-         * we just need to write the out the contents as normal, but with a
-         * concrete length prefix.
-         *
-         * If it's a something else then the contents will be a series of BER
-         * elements of the same type which need to be concatenated. */
-        const char context_specific = (tag & 0xc0) == 0x80;
-        char squash_child_headers = is_primitive_type(tag);
-
-        /* This is a hack, but it sufficies to handle NSS's output. If we find
-         * an indefinite length, context-specific tag with a definite, primitive
-         * tag inside it, then we assume that the context-specific tag is
-         * implicit and the tags within are fragments of a primitive type that
-         * need to be concatenated. */
-        if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
-          CBS in_copy, inner_contents;
-          unsigned inner_tag;
-          size_t inner_header_len;
-
-          CBS_init(&in_copy, CBS_data(in), CBS_len(in));
-          if (!CBS_get_any_ber_asn1_element(&in_copy, &inner_contents,
-                                            &inner_tag, &inner_header_len)) {
-            return 0;
-          }
-          if (CBS_len(&inner_contents) > inner_header_len &&
-              is_primitive_type(inner_tag)) {
-            squash_child_headers = 1;
-          }
-        }
-
-        if (!squash_header) {
-          unsigned out_tag = tag;
-          if (squash_child_headers) {
-            out_tag &= ~CBS_ASN1_CONSTRUCTED;
-          }
-          if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
-            return 0;
-          }
-          out_contents = &out_contents_storage;
-        }
-
-        if (!cbs_convert_ber(in, out_contents,
-                             squash_child_headers,
-                             1 /* looking for eoc */, depth + 1)) {
-          return 0;
-        }
-        if (out_contents != out && !CBB_flush(out)) {
-          return 0;
-        }
-        continue;
-      }
+    if (is_eoc(header_len, &contents)) {
+      return looking_for_eoc;
     }
 
-    if (!squash_header) {
-      if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
+    if (string_tag != 0) {
+      /* This is part of a constructed string. All elements must match
+       * |string_tag| up to the constructed bit and get appended to |out|
+       * without a child element. */
+      if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) {
+        return 0;
+      }
+      out_contents = out;
+    } else {
+      unsigned out_tag = tag;
+      if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) {
+        /* If a constructed string, clear the constructed bit and inform
+         * children to concatenate bodies. */
+        out_tag &= ~CBS_ASN1_CONSTRUCTED;
+        child_string_tag = out_tag;
+      }
+      if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
         return 0;
       }
       out_contents = &out_contents_storage;
     }
 
+    if (CBS_len(&contents) == header_len && header_len > 0 &&
+        CBS_data(&contents)[header_len - 1] == 0x80) {
+      /* This is an indefinite length element. */
+      if (!cbs_convert_ber(in, out_contents, child_string_tag,
+                           1 /* looking for eoc */, depth + 1) ||
+          !CBB_flush(out)) {
+        return 0;
+      }
+      continue;
+    }
+
     if (!CBS_skip(&contents, header_len)) {
       return 0;
     }
 
     if (tag & CBS_ASN1_CONSTRUCTED) {
-      if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
+      /* Recurse into children. */
+      if (!cbs_convert_ber(&contents, out_contents, child_string_tag,
                            0 /* not looking for eoc */, depth + 1)) {
         return 0;
       }
     } else {
+      /* Copy primitive contents as-is. */
       if (!CBB_add_bytes(out_contents, CBS_data(&contents),
                          CBS_len(&contents))) {
         return 0;
       }
     }
 
-    if (out_contents != out && !CBB_flush(out)) {
+    if (!CBB_flush(out)) {
       return 0;
     }
   }
@@ -209,13 +207,57 @@
     return 1;
   }
 
-  if (!CBB_init(&cbb, CBS_len(in))) {
-    return 0;
-  }
-  if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
+  if (!CBB_init(&cbb, CBS_len(in)) ||
+      !cbs_convert_ber(in, &cbb, 0, 0, 0) ||
+      !CBB_finish(&cbb, out, out_len)) {
     CBB_cleanup(&cbb);
     return 0;
   }
 
-  return CBB_finish(&cbb, out, out_len);
+  return 1;
+}
+
+int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage,
+                                 unsigned outer_tag, unsigned inner_tag) {
+  assert(!(outer_tag & CBS_ASN1_CONSTRUCTED));
+  assert(!(inner_tag & CBS_ASN1_CONSTRUCTED));
+  assert(is_string_type(inner_tag));
+
+  if (CBS_peek_asn1_tag(in, outer_tag)) {
+    /* Normal implicitly-tagged string. */
+    *out_storage = NULL;
+    return CBS_get_asn1(in, out, outer_tag);
+  }
+
+  /* Otherwise, try to parse an implicitly-tagged constructed string.
+   * |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep
+   * of nesting. */
+  CBB result;
+  CBS child;
+  if (!CBB_init(&result, CBS_len(in)) ||
+      !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) {
+    goto err;
+  }
+
+  while (CBS_len(&child) > 0) {
+    CBS chunk;
+    if (!CBS_get_asn1(&child, &chunk, inner_tag) ||
+        !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) {
+      goto err;
+    }
+  }
+
+  uint8_t *data;
+  size_t len;
+  if (!CBB_finish(&result, &data, &len)) {
+    goto err;
+  }
+
+  CBS_init(out, data, len);
+  *out_storage = data;
+  return 1;
+
+err:
+  CBB_cleanup(&result);
+  return 0;
 }
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 188c63d..84ecffc 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -579,7 +579,7 @@
   static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
   static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
 
-  // kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
+  // kOctetStringBER contains an indefinite length OCTET STRING with two parts.
   // These parts need to be concatenated in DER form.
   static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0,    1,
                                             0x04, 0x02, 2,    3,    0x00, 0x00};
@@ -609,6 +609,16 @@
       0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
   };
 
+  // kConstructedStringBER contains a deeply-nested constructed OCTET STRING.
+  // The BER conversion collapses this to one level deep, but not completely.
+  static const uint8_t kConstructedStringBER[] = {
+      0xa0, 0x10, 0x24, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01,
+      0x01, 0x24, 0x06, 0x04, 0x01, 0x02, 0x04, 0x01, 0x03,
+  };
+  static const uint8_t kConstructedStringDER[] = {
+      0xa0, 0x08, 0x04, 0x02, 0x00, 0x01, 0x04, 0x02, 0x02, 0x03,
+  };
+
   return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
                       kSimpleBER, sizeof(kSimpleBER)) &&
          DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
@@ -617,7 +627,59 @@
                       sizeof(kOctetStringDER), kOctetStringBER,
                       sizeof(kOctetStringBER)) &&
          DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
-                      sizeof(kNSSBER));
+                      sizeof(kNSSBER)) &&
+         DoBerConvert("kConstructedStringBER", kConstructedStringDER,
+                      sizeof(kConstructedStringDER), kConstructedStringBER,
+                      sizeof(kConstructedStringBER));
+}
+
+struct ImplicitStringTest {
+  const char *in;
+  size_t in_len;
+  bool ok;
+  const char *out;
+  size_t out_len;
+};
+
+static const ImplicitStringTest kImplicitStringTests[] = {
+    // A properly-encoded string.
+    {"\x80\x03\x61\x61\x61", 5, true, "aaa", 3},
+    // An implicit-tagged string.
+    {"\xa0\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, true, "aaa", 3},
+    // |CBS_get_asn1_implicit_string| only accepts one level deep of nesting.
+    {"\xa0\x0b\x24\x06\x04\x01\x61\x04\x01\x61\x04\x01\x61", 13, false, nullptr,
+     0},
+    // The outer tag must match.
+    {"\x81\x03\x61\x61\x61", 5, false, nullptr, 0},
+    {"\xa1\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, false, nullptr, 0},
+    // The inner tag must match.
+    {"\xa1\x09\x0c\x01\x61\x0c\x01\x61\x0c\x01\x61", 11, false, nullptr, 0},
+};
+
+static bool TestImplicitString() {
+  for (const auto &test : kImplicitStringTests) {
+    uint8_t *storage = nullptr;
+    CBS in, out;
+    CBS_init(&in, reinterpret_cast<const uint8_t *>(test.in), test.in_len);
+    int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
+                                          CBS_ASN1_CONTEXT_SPECIFIC | 0,
+                                          CBS_ASN1_OCTETSTRING);
+    ScopedOpenSSLBytes scoper(storage);
+
+    if (static_cast<bool>(ok) != test.ok) {
+      fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
+              ok ? "succeeded" : "failed");
+      return false;
+    }
+
+    if (ok && (CBS_len(&out) != test.out_len ||
+               memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
+      fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
+      return false;
+    }
+  }
+
+  return true;
 }
 
 struct ASN1Uint64Test {
@@ -747,6 +809,7 @@
       !TestCBBDiscardChild() ||
       !TestCBBASN1() ||
       !TestBerConvert() ||
+      !TestImplicitString() ||
       !TestASN1Uint64() ||
       !TestGetOptionalASN1Bool() ||
       !TestZero() ||
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index 5e0c538..ed54b49 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -181,8 +181,14 @@
     return 0;
   }
 
+  /* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
+   * number no greater than 30.
+   *
+   * If the number portion is 31 (0x1f, the largest value that fits in the
+   * allotted bits), then the tag is more than one byte long and the
+   * continuation bytes contain the tag number. This parser only supports tag
+   * numbers less than 31 (and thus single-byte tags). */
   if ((tag & 0x1f) == 0x1f) {
-    /* Long form tags are not supported. */
     return 0;
   }
 
@@ -191,6 +197,8 @@
   }
 
   size_t len;
+  /* The format for the length encoding is specified in ITU-T X.690 section
+   * 8.1.3. */
   if ((length_byte & 0x80) == 0) {
     /* Short form length. */
     len = ((size_t) length_byte) + 2;
@@ -198,7 +206,9 @@
       *out_header_len = 2;
     }
   } else {
-    /* Long form length. */
+    /* The high bit indicate that this is the long form, while the next 7 bits
+     * encode the number of subsequent octets used to encode the length (ITU-T
+     * X.690 clause 8.1.3.5.b). */
     const size_t num_bytes = length_byte & 0x7f;
     uint32_t len32;
 
@@ -210,12 +220,18 @@
       return CBS_get_bytes(cbs, out, 2);
     }
 
+    /* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
+     * used as the first byte of the length. If this parser encounters that
+     * value, num_bytes will be parsed as 127, which will fail the check below.
+     */
     if (num_bytes == 0 || num_bytes > 4) {
       return 0;
     }
     if (!cbs_get_u(&header, &len32, num_bytes)) {
       return 0;
     }
+    /* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+     * with the minimum number of octets. */
     if (len32 < 128) {
       /* Length should have used short-form encoding. */
       return 0;
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index b4ea7e5..2fed413 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -22,22 +22,51 @@
 #endif
 
 
-/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
- * indefinite-length elements then it attempts to convert the BER data to DER
- * and sets |*out| and |*out_length| to describe a malloced buffer containing
- * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
+/* CBS_asn1_ber_to_der reads a BER element from |in|. If it finds
+ * indefinite-length elements or constructed strings then it converts the BER
+ * data to DER and sets |*out| and |*out_length| to describe a malloced buffer
+ * containing the DER data. Additionally, |*in| will be advanced over the BER
+ * element.
  *
- * If it doesn't find any indefinite-length elements then it sets |*out| to
- * NULL and |*in| is unmodified.
+ * If it doesn't find any indefinite-length elements or constructed strings then
+ * it sets |*out| to NULL and |*in| is unmodified.
  *
- * A sufficiently complex ASN.1 structure will break this function because it's
- * not possible to generically convert BER to DER without knowledge of the
- * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
- * from NSS.
+ * This function should successfully process any valid BER input, however it
+ * will not convert all of BER's deviations from DER. BER is ambiguous between
+ * implicitly-tagged SEQUENCEs of strings and implicitly-tagged constructed
+ * strings. Implicitly-tagged strings must be parsed with
+ * |CBS_get_ber_implicitly_tagged_string| instead of |CBS_get_asn1|. The caller
+ * must also account for BER variations in the contents of a primitive.
  *
  * 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_asn1_implicit_string parses a BER string of primitive type
+ * |inner_tag| implicitly-tagged with |outer_tag|. It sets |out| to the
+ * contents. If concatenation was needed, it sets |*out_storage| to a buffer
+ * which the caller must release with |OPENSSL_free|. Otherwise, it sets
+ * |*out_storage| to NULL.
+ *
+ * This function does not parse all of BER. It requires the string be
+ * definite-length. Constructed strings are allowed, but all children of the
+ * outermost element must be primitive. The caller should use
+ * |CBS_asn1_ber_to_der| before running this function.
+ *
+ * It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out,
+                                                uint8_t **out_storage,
+                                                unsigned outer_tag,
+                                                unsigned inner_tag);
+
+/* CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized
+ * with |CBB_init|. If |outp| is not NULL then the result is written to |*outp|
+ * and |*outp| is advanced just past the output. It returns the number of bytes
+ * in the result, whether written or not, or a negative value on error. On
+ * error, it calls |CBB_cleanup| on |cbb|.
+ *
+ * This function may be used to help implement legacy i2d ASN.1 functions. */
+int CBB_finish_i2d(CBB *cbb, uint8_t **outp);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/chacha/CMakeLists.txt b/src/crypto/chacha/CMakeLists.txt
index 266e869..39d1def 100644
--- a/src/crypto/chacha/CMakeLists.txt
+++ b/src/crypto/chacha/CMakeLists.txt
@@ -4,7 +4,31 @@
   set(
     CHACHA_ARCH_SOURCES
 
-    chacha_vec_arm.S
+    chacha-armv4.${ASM_EXT}
+  )
+endif()
+
+if (${ARCH} STREQUAL "aarch64")
+  set(
+    CHACHA_ARCH_SOURCES
+
+    chacha-armv8.${ASM_EXT}
+  )
+endif()
+
+if (${ARCH} STREQUAL "x86")
+  set(
+    CHACHA_ARCH_SOURCES
+
+    chacha-x86.${ASM_EXT}
+  )
+endif()
+
+if (${ARCH} STREQUAL "x86_64")
+  set(
+    CHACHA_ARCH_SOURCES
+
+    chacha-x86_64.${ASM_EXT}
   )
 endif()
 
@@ -13,8 +37,22 @@
 
   OBJECT
 
-  chacha_generic.c
-  chacha_vec.c
+  chacha.c
 
   ${CHACHA_ARCH_SOURCES}
 )
+
+add_executable(
+  chacha_test
+
+  chacha_test.cc
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(chacha_test crypto)
+add_dependencies(all_tests chacha_test)
+
+perlasm(chacha-armv4.${ASM_EXT} asm/chacha-armv4.pl)
+perlasm(chacha-armv8.${ASM_EXT} asm/chacha-armv8.pl)
+perlasm(chacha-x86.${ASM_EXT} asm/chacha-x86.pl)
+perlasm(chacha-x86_64.${ASM_EXT} asm/chacha-x86_64.pl)
\ No newline at end of file
diff --git a/src/crypto/chacha/asm/chacha-armv4.pl b/src/crypto/chacha/asm/chacha-armv4.pl
new file mode 100755
index 0000000..b190445
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-armv4.pl
@@ -0,0 +1,1151 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# December 2014
+# 
+# ChaCha20 for ARMv4.
+#
+# Performance in cycles per byte out of large buffer.
+#
+#			IALU/gcc-4.4    1xNEON      3xNEON+1xIALU
+#
+# Cortex-A5		19.3(*)/+95%    21.8        14.1
+# Cortex-A8		10.5(*)/+160%   13.9        6.35
+# Cortex-A9		12.9(**)/+110%  14.3        6.50
+# Cortex-A15		11.0/+40%       16.0        5.00
+# Snapdragon S4		11.5/+125%      13.6        4.90
+#
+# (*)	most "favourable" result for aligned data on little-endian
+#	processor, result for misaligned data is 10-15% lower;
+# (**)	this result is a trade-off: it can be improved by 20%,
+#	but then Snapdragon S4 and Cortex-A8 results get
+#	20-25% worse;
+
+$flavour = shift;
+if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
+else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
+
+if ($flavour && $flavour ne "void") {
+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+    die "can't locate arm-xlate.pl";
+
+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+    open STDOUT,">$output";
+}
+
+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+  my $arg = pop;
+    $arg = "#$arg" if ($arg*1 eq $arg);
+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
+}
+
+my @x=map("r$_",(0..7,"x","x","x","x",12,"x",14,"x"));
+my @t=map("r$_",(8..11));
+
+sub ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my $odd = $d0&1;
+my ($xc,$xc_) = (@t[0..1]);
+my ($xd,$xd_) = $odd ? (@t[2],@x[$d1]) : (@x[$d0],@t[2]);
+my @ret;
+
+	# Consider order in which variables are addressed by their
+	# index:
+	#
+	#       a   b   c   d
+	#
+	#       0   4   8  12 < even round
+	#       1   5   9  13
+	#       2   6  10  14
+	#       3   7  11  15
+	#       0   5  10  15 < odd round
+	#       1   6  11  12
+	#       2   7   8  13
+	#       3   4   9  14
+	#
+	# 'a', 'b' are permanently allocated in registers, @x[0..7],
+	# while 'c's and pair of 'd's are maintained in memory. If
+	# you observe 'c' column, you'll notice that pair of 'c's is
+	# invariant between rounds. This means that we have to reload
+	# them once per round, in the middle. This is why you'll see
+	# bunch of 'c' stores and loads in the middle, but none in
+	# the beginning or end. If you observe 'd' column, you'll
+	# notice that 15 and 13 are reused in next pair of rounds.
+	# This is why these two are chosen for offloading to memory,
+	# to make loads count more.
+							push @ret,(
+	"&add	(@x[$a0],@x[$a0],@x[$b0])",
+	"&mov	($xd,$xd,'ror#16')",
+	 "&add	(@x[$a1],@x[$a1],@x[$b1])",
+	 "&mov	($xd_,$xd_,'ror#16')",
+	"&eor	($xd,$xd,@x[$a0],'ror#16')",
+	 "&eor	($xd_,$xd_,@x[$a1],'ror#16')",
+
+	"&add	($xc,$xc,$xd)",
+	"&mov	(@x[$b0],@x[$b0],'ror#20')",
+	 "&add	($xc_,$xc_,$xd_)",
+	 "&mov	(@x[$b1],@x[$b1],'ror#20')",
+	"&eor	(@x[$b0],@x[$b0],$xc,'ror#20')",
+	 "&eor	(@x[$b1],@x[$b1],$xc_,'ror#20')",
+
+	"&add	(@x[$a0],@x[$a0],@x[$b0])",
+	"&mov	($xd,$xd,'ror#24')",
+	 "&add	(@x[$a1],@x[$a1],@x[$b1])",
+	 "&mov	($xd_,$xd_,'ror#24')",
+	"&eor	($xd,$xd,@x[$a0],'ror#24')",
+	 "&eor	($xd_,$xd_,@x[$a1],'ror#24')",
+
+	"&add	($xc,$xc,$xd)",
+	"&mov	(@x[$b0],@x[$b0],'ror#25')"		);
+							push @ret,(
+	"&str	($xd,'[sp,#4*(16+$d0)]')",
+	"&ldr	($xd,'[sp,#4*(16+$d2)]')"		) if ($odd);
+							push @ret,(
+	 "&add	($xc_,$xc_,$xd_)",
+	 "&mov	(@x[$b1],@x[$b1],'ror#25')"		);
+							push @ret,(
+	 "&str	($xd_,'[sp,#4*(16+$d1)]')",
+	 "&ldr	($xd_,'[sp,#4*(16+$d3)]')"		) if (!$odd);
+							push @ret,(
+	"&eor	(@x[$b0],@x[$b0],$xc,'ror#25')",
+	 "&eor	(@x[$b1],@x[$b1],$xc_,'ror#25')"	);
+
+	$xd=@x[$d2]					if (!$odd);
+	$xd_=@x[$d3]					if ($odd);
+							push @ret,(
+	"&str	($xc,'[sp,#4*(16+$c0)]')",
+	"&ldr	($xc,'[sp,#4*(16+$c2)]')",
+	"&add	(@x[$a2],@x[$a2],@x[$b2])",
+	"&mov	($xd,$xd,'ror#16')",
+	 "&str	($xc_,'[sp,#4*(16+$c1)]')",
+	 "&ldr	($xc_,'[sp,#4*(16+$c3)]')",
+	 "&add	(@x[$a3],@x[$a3],@x[$b3])",
+	 "&mov	($xd_,$xd_,'ror#16')",
+	"&eor	($xd,$xd,@x[$a2],'ror#16')",
+	 "&eor	($xd_,$xd_,@x[$a3],'ror#16')",
+
+	"&add	($xc,$xc,$xd)",
+	"&mov	(@x[$b2],@x[$b2],'ror#20')",
+	 "&add	($xc_,$xc_,$xd_)",
+	 "&mov	(@x[$b3],@x[$b3],'ror#20')",
+	"&eor	(@x[$b2],@x[$b2],$xc,'ror#20')",
+	 "&eor	(@x[$b3],@x[$b3],$xc_,'ror#20')",
+
+	"&add	(@x[$a2],@x[$a2],@x[$b2])",
+	"&mov	($xd,$xd,'ror#24')",
+	 "&add	(@x[$a3],@x[$a3],@x[$b3])",
+	 "&mov	($xd_,$xd_,'ror#24')",
+	"&eor	($xd,$xd,@x[$a2],'ror#24')",
+	 "&eor	($xd_,$xd_,@x[$a3],'ror#24')",
+
+	"&add	($xc,$xc,$xd)",
+	"&mov	(@x[$b2],@x[$b2],'ror#25')",
+	 "&add	($xc_,$xc_,$xd_)",
+	 "&mov	(@x[$b3],@x[$b3],'ror#25')",
+	"&eor	(@x[$b2],@x[$b2],$xc,'ror#25')",
+	 "&eor	(@x[$b3],@x[$b3],$xc_,'ror#25')"	);
+
+	@ret;
+}
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax	unified
+.thumb
+#else
+.code	32
+#endif
+
+#if defined(__thumb2__) || defined(__clang__)
+#define ldrhsb	ldrbhs
+#endif
+
+.align	5
+.Lsigma:
+.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
+.Lone:
+.long	1,0,0,0
+#if __ARM_MAX_ARCH__>=7
+.LOPENSSL_armcap:
+.word   OPENSSL_armcap_P-.LChaCha20_ctr32
+#else
+.word	-1
+#endif
+
+.globl	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+.LChaCha20_ctr32:
+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb	sp!,{r0-r2,r4-r11,lr}
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
+	sub	r14,pc,#16		@ ChaCha20_ctr32
+#else
+	adr	r14,.LChaCha20_ctr32
+#endif
+	cmp	r2,#0			@ len==0?
+#ifdef	__thumb2__
+	itt	eq
+#endif
+	addeq	sp,sp,#4*3
+	beq	.Lno_data
+#if __ARM_MAX_ARCH__>=7
+	cmp	r2,#192			@ test len
+	bls	.Lshort
+	ldr	r4,[r14,#-32]
+	ldr	r4,[r14,r4]
+# ifdef	__APPLE__
+	ldr	r4,[r4]
+# endif
+	tst	r4,#ARMV7_NEON
+	bne	.LChaCha20_neon
+.Lshort:
+#endif
+	ldmia	r12,{r4-r7}		@ load counter and nonce
+	sub	sp,sp,#4*(16)		@ off-load area
+	sub	r14,r14,#64		@ .Lsigma
+	stmdb	sp!,{r4-r7}		@ copy counter and nonce
+	ldmia	r3,{r4-r11}		@ load key
+	ldmia	r14,{r0-r3}		@ load sigma
+	stmdb	sp!,{r4-r11}		@ copy key
+	stmdb	sp!,{r0-r3}		@ copy sigma
+	str	r10,[sp,#4*(16+10)]	@ off-load "@x[10]"
+	str	r11,[sp,#4*(16+11)]	@ off-load "@x[11]"
+	b	.Loop_outer_enter
+
+.align	4
+.Loop_outer:
+	ldmia	sp,{r0-r9}		@ load key material
+	str	@t[3],[sp,#4*(32+2)]	@ save len
+	str	r12,  [sp,#4*(32+1)]	@ save inp
+	str	r14,  [sp,#4*(32+0)]	@ save out
+.Loop_outer_enter:
+	ldr	@t[3], [sp,#4*(15)]
+	ldr	@x[12],[sp,#4*(12)]	@ modulo-scheduled load
+	ldr	@t[2], [sp,#4*(13)]
+	ldr	@x[14],[sp,#4*(14)]
+	str	@t[3], [sp,#4*(16+15)]
+	mov	@t[3],#10
+	b	.Loop
+
+.align	4
+.Loop:
+	subs	@t[3],@t[3],#1
+___
+	foreach (&ROUND(0, 4, 8,12)) { eval; }
+	foreach (&ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+	bne	.Loop
+
+	ldr	@t[3],[sp,#4*(32+2)]	@ load len
+
+	str	@t[0], [sp,#4*(16+8)]	@ modulo-scheduled store
+	str	@t[1], [sp,#4*(16+9)]
+	str	@x[12],[sp,#4*(16+12)]
+	str	@t[2], [sp,#4*(16+13)]
+	str	@x[14],[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ @x[0-7] and second half at sp+4*(16+8)
+
+	cmp	@t[3],#64		@ done yet?
+#ifdef	__thumb2__
+	itete	lo
+#endif
+	addlo	r12,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r12,[sp,#4*(32+1)]	@ ... load inp
+	addlo	r14,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r14,[sp,#4*(32+0)]	@ ... load out
+
+	ldr	@t[0],[sp,#4*(0)]	@ load key material
+	ldr	@t[1],[sp,#4*(1)]
+
+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
+# if __ARM_ARCH__<7
+	orr	@t[2],r12,r14
+	tst	@t[2],#3		@ are input and output aligned?
+	ldr	@t[2],[sp,#4*(2)]
+	bne	.Lunaligned
+	cmp	@t[3],#64		@ restore flags
+# else
+	ldr	@t[2],[sp,#4*(2)]
+# endif
+	ldr	@t[3],[sp,#4*(3)]
+
+	add	@x[0],@x[0],@t[0]	@ accumulate key material
+	add	@x[1],@x[1],@t[1]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[0],[r12],#16		@ load input
+	ldrhs	@t[1],[r12,#-12]
+
+	add	@x[2],@x[2],@t[2]
+	add	@x[3],@x[3],@t[3]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[2],[r12,#-8]
+	ldrhs	@t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	@x[0],@x[0]
+	rev	@x[1],@x[1]
+	rev	@x[2],@x[2]
+	rev	@x[3],@x[3]
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[0],@x[0],@t[0]	@ xor with input
+	eorhs	@x[1],@x[1],@t[1]
+	 add	@t[0],sp,#4*(4)
+	str	@x[0],[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[2],@x[2],@t[2]
+	eorhs	@x[3],@x[3],@t[3]
+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
+	str	@x[1],[r14,#-12]
+	str	@x[2],[r14,#-8]
+	str	@x[3],[r14,#-4]
+
+	add	@x[4],@x[4],@t[0]	@ accumulate key material
+	add	@x[5],@x[5],@t[1]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[0],[r12],#16		@ load input
+	ldrhs	@t[1],[r12,#-12]
+	add	@x[6],@x[6],@t[2]
+	add	@x[7],@x[7],@t[3]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[2],[r12,#-8]
+	ldrhs	@t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	@x[4],@x[4]
+	rev	@x[5],@x[5]
+	rev	@x[6],@x[6]
+	rev	@x[7],@x[7]
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[4],@x[4],@t[0]
+	eorhs	@x[5],@x[5],@t[1]
+	 add	@t[0],sp,#4*(8)
+	str	@x[4],[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[6],@x[6],@t[2]
+	eorhs	@x[7],@x[7],@t[3]
+	str	@x[5],[r14,#-12]
+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
+	str	@x[6],[r14,#-8]
+	 add	@x[0],sp,#4*(16+8)
+	str	@x[7],[r14,#-4]
+
+	ldmia	@x[0],{@x[0]-@x[7]}	@ load second half
+
+	add	@x[0],@x[0],@t[0]	@ accumulate key material
+	add	@x[1],@x[1],@t[1]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[0],[r12],#16		@ load input
+	ldrhs	@t[1],[r12,#-12]
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	 strhi	@t[2],[sp,#4*(16+10)]	@ copy "@x[10]" while at it
+	 strhi	@t[3],[sp,#4*(16+11)]	@ copy "@x[11]" while at it
+	add	@x[2],@x[2],@t[2]
+	add	@x[3],@x[3],@t[3]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[2],[r12,#-8]
+	ldrhs	@t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	@x[0],@x[0]
+	rev	@x[1],@x[1]
+	rev	@x[2],@x[2]
+	rev	@x[3],@x[3]
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[0],@x[0],@t[0]
+	eorhs	@x[1],@x[1],@t[1]
+	 add	@t[0],sp,#4*(12)
+	str	@x[0],[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[2],@x[2],@t[2]
+	eorhs	@x[3],@x[3],@t[3]
+	str	@x[1],[r14,#-12]
+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
+	str	@x[2],[r14,#-8]
+	str	@x[3],[r14,#-4]
+
+	add	@x[4],@x[4],@t[0]	@ accumulate key material
+	add	@x[5],@x[5],@t[1]
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	 addhi	@t[0],@t[0],#1		@ next counter value
+	 strhi	@t[0],[sp,#4*(12)]	@ save next counter value
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[0],[r12],#16		@ load input
+	ldrhs	@t[1],[r12,#-12]
+	add	@x[6],@x[6],@t[2]
+	add	@x[7],@x[7],@t[3]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	@t[2],[r12,#-8]
+	ldrhs	@t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	@x[4],@x[4]
+	rev	@x[5],@x[5]
+	rev	@x[6],@x[6]
+	rev	@x[7],@x[7]
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[4],@x[4],@t[0]
+	eorhs	@x[5],@x[5],@t[1]
+# ifdef	__thumb2__
+	 it	ne
+# endif
+	 ldrne	@t[0],[sp,#4*(32+2)]	@ re-load len
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	@x[6],@x[6],@t[2]
+	eorhs	@x[7],@x[7],@t[3]
+	str	@x[4],[r14],#16		@ store output
+	str	@x[5],[r14,#-12]
+# ifdef	__thumb2__
+	it	hs
+# endif
+	 subhs	@t[3],@t[0],#64		@ len-=64
+	str	@x[6],[r14,#-8]
+	str	@x[7],[r14,#-4]
+	bhi	.Loop_outer
+
+	beq	.Ldone
+# if __ARM_ARCH__<7
+	b	.Ltail
+
+.align	4
+.Lunaligned:				@ unaligned endian-neutral path
+	cmp	@t[3],#64		@ restore flags
+# endif
+#endif
+#if __ARM_ARCH__<7
+	ldr	@t[3],[sp,#4*(3)]
+___
+for ($i=0;$i<16;$i+=4) {
+my $j=$i&0x7;
+
+$code.=<<___	if ($i==4);
+	add	@x[0],sp,#4*(16+8)
+___
+$code.=<<___	if ($i==8);
+	ldmia	@x[0],{@x[0]-@x[7]}		@ load second half
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	strhi	@t[2],[sp,#4*(16+10)]		@ copy "@x[10]"
+	strhi	@t[3],[sp,#4*(16+11)]		@ copy "@x[11]"
+___
+$code.=<<___;
+	add	@x[$j+0],@x[$j+0],@t[0]		@ accumulate key material
+___
+$code.=<<___	if ($i==12);
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	addhi	@t[0],@t[0],#1			@ next counter value
+	strhi	@t[0],[sp,#4*(12)]		@ save next counter value
+___
+$code.=<<___;
+	add	@x[$j+1],@x[$j+1],@t[1]
+	add	@x[$j+2],@x[$j+2],@t[2]
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	@t[0],@t[0],@t[0]		@ zero or ...
+	ldrhsb	@t[0],[r12],#16			@ ... load input
+	eorlo	@t[1],@t[1],@t[1]
+	ldrhsb	@t[1],[r12,#-12]
+
+	add	@x[$j+3],@x[$j+3],@t[3]
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	@t[2],@t[2],@t[2]
+	ldrhsb	@t[2],[r12,#-8]
+	eorlo	@t[3],@t[3],@t[3]
+	ldrhsb	@t[3],[r12,#-4]
+
+	eor	@x[$j+0],@t[0],@x[$j+0]		@ xor with input (or zero)
+	eor	@x[$j+1],@t[1],@x[$j+1]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[0],[r12,#-15]		@ load more input
+	ldrhsb	@t[1],[r12,#-11]
+	eor	@x[$j+2],@t[2],@x[$j+2]
+	 strb	@x[$j+0],[r14],#16		@ store output
+	eor	@x[$j+3],@t[3],@x[$j+3]
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[2],[r12,#-7]
+	ldrhsb	@t[3],[r12,#-3]
+	 strb	@x[$j+1],[r14,#-12]
+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
+	 strb	@x[$j+2],[r14,#-8]
+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[0],[r12,#-14]		@ load more input
+	ldrhsb	@t[1],[r12,#-10]
+	 strb	@x[$j+3],[r14,#-4]
+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
+	 strb	@x[$j+0],[r14,#-15]
+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[2],[r12,#-6]
+	ldrhsb	@t[3],[r12,#-2]
+	 strb	@x[$j+1],[r14,#-11]
+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
+	 strb	@x[$j+2],[r14,#-7]
+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[0],[r12,#-13]		@ load more input
+	ldrhsb	@t[1],[r12,#-9]
+	 strb	@x[$j+3],[r14,#-3]
+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
+	 strb	@x[$j+0],[r14,#-14]
+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	@t[2],[r12,#-5]
+	ldrhsb	@t[3],[r12,#-1]
+	 strb	@x[$j+1],[r14,#-10]
+	 strb	@x[$j+2],[r14,#-6]
+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
+	 strb	@x[$j+3],[r14,#-2]
+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
+	 strb	@x[$j+0],[r14,#-13]
+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
+	 strb	@x[$j+1],[r14,#-9]
+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
+	 strb	@x[$j+2],[r14,#-5]
+	 strb	@x[$j+3],[r14,#-1]
+___
+$code.=<<___	if ($i<12);
+	add	@t[0],sp,#4*(4+$i)
+	ldmia	@t[0],{@t[0]-@t[3]}		@ load key material
+___
+}
+$code.=<<___;
+# ifdef	__thumb2__
+	it	ne
+# endif
+	ldrne	@t[0],[sp,#4*(32+2)]		@ re-load len
+# ifdef	__thumb2__
+	it	hs
+# endif
+	subhs	@t[3],@t[0],#64			@ len-=64
+	bhi	.Loop_outer
+
+	beq	.Ldone
+#endif
+
+.Ltail:
+	ldr	r12,[sp,#4*(32+1)]	@ load inp
+	add	@t[1],sp,#4*(0)
+	ldr	r14,[sp,#4*(32+0)]	@ load out
+
+.Loop_tail:
+	ldrb	@t[2],[@t[1]],#1	@ read buffer on stack
+	ldrb	@t[3],[r12],#1		@ read input
+	subs	@t[0],@t[0],#1
+	eor	@t[3],@t[3],@t[2]
+	strb	@t[3],[r14],#1		@ store output
+	bne	.Loop_tail
+
+.Ldone:
+	add	sp,sp,#4*(32+3)
+.Lno_data:
+	ldmia	sp!,{r4-r11,pc}
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+{{{
+my ($a0,$b0,$c0,$d0,$a1,$b1,$c1,$d1,$a2,$b2,$c2,$d2,$t0,$t1,$t2,$t3) =
+    map("q$_",(0..15));
+
+sub NEONROUND {
+my $odd = pop;
+my ($a,$b,$c,$d,$t)=@_;
+
+	(
+	"&vadd_i32	($a,$a,$b)",
+	"&veor		($d,$d,$a)",
+	"&vrev32_16	($d,$d)",	# vrot ($d,16)
+
+	"&vadd_i32	($c,$c,$d)",
+	"&veor		($t,$b,$c)",
+	"&vshr_u32	($b,$t,20)",
+	"&vsli_32	($b,$t,12)",
+
+	"&vadd_i32	($a,$a,$b)",
+	"&veor		($t,$d,$a)",
+	"&vshr_u32	($d,$t,24)",
+	"&vsli_32	($d,$t,8)",
+
+	"&vadd_i32	($c,$c,$d)",
+	"&veor		($t,$b,$c)",
+	"&vshr_u32	($b,$t,25)",
+	"&vsli_32	($b,$t,7)",
+
+	"&vext_8	($c,$c,$c,8)",
+	"&vext_8	($b,$b,$b,$odd?12:4)",
+	"&vext_8	($d,$d,$d,$odd?4:12)"
+	);
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7
+.arch	armv7-a
+.fpu	neon
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	ldr		r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb		sp!,{r0-r2,r4-r11,lr}
+.LChaCha20_neon:
+	adr		r14,.Lsigma
+	vstmdb		sp!,{d8-d15}		@ ABI spec says so
+	stmdb		sp!,{r0-r3}
+
+	vld1.32		{$b0-$c0},[r3]		@ load key
+	ldmia		r3,{r4-r11}		@ load key
+
+	sub		sp,sp,#4*(16+16)
+	vld1.32		{$d0},[r12]		@ load counter and nonce
+	add		r12,sp,#4*8
+	ldmia		r14,{r0-r3}		@ load sigma
+	vld1.32		{$a0},[r14]!		@ load sigma
+	vld1.32		{$t0},[r14]		@ one
+	vst1.32		{$c0-$d0},[r12]		@ copy 1/2key|counter|nonce
+	vst1.32		{$a0-$b0},[sp]		@ copy sigma|1/2key
+
+	str		r10,[sp,#4*(16+10)]	@ off-load "@x[10]"
+	str		r11,[sp,#4*(16+11)]	@ off-load "@x[11]"
+	vshl.i32	$t1#lo,$t0#lo,#1	@ two
+	vstr		$t0#lo,[sp,#4*(16+0)]
+	vshl.i32	$t2#lo,$t0#lo,#2	@ four
+	vstr		$t1#lo,[sp,#4*(16+2)]
+	vmov		$a1,$a0
+	vstr		$t2#lo,[sp,#4*(16+4)]
+	vmov		$a2,$a0
+	vmov		$b1,$b0
+	vmov		$b2,$b0
+	b		.Loop_neon_enter
+
+.align	4
+.Loop_neon_outer:
+	ldmia		sp,{r0-r9}		@ load key material
+	cmp		@t[3],#64*2		@ if len<=64*2
+	bls		.Lbreak_neon		@ switch to integer-only
+	vmov		$a1,$a0
+	str		@t[3],[sp,#4*(32+2)]	@ save len
+	vmov		$a2,$a0
+	str		r12,  [sp,#4*(32+1)]	@ save inp
+	vmov		$b1,$b0
+	str		r14,  [sp,#4*(32+0)]	@ save out
+	vmov		$b2,$b0
+.Loop_neon_enter:
+	ldr		@t[3], [sp,#4*(15)]
+	vadd.i32	$d1,$d0,$t0		@ counter+1
+	ldr		@x[12],[sp,#4*(12)]	@ modulo-scheduled load
+	vmov		$c1,$c0
+	ldr		@t[2], [sp,#4*(13)]
+	vmov		$c2,$c0
+	ldr		@x[14],[sp,#4*(14)]
+	vadd.i32	$d2,$d1,$t0		@ counter+2
+	str		@t[3], [sp,#4*(16+15)]
+	mov		@t[3],#10
+	add		@x[12],@x[12],#3	@ counter+3 
+	b		.Loop_neon
+
+.align	4
+.Loop_neon:
+	subs		@t[3],@t[3],#1
+___
+	my @thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,0);
+	my @thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,0);
+	my @thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,0);
+	my @thread3=&ROUND(0,4,8,12);
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread3));
+		eval(shift(@thread1));	eval(shift(@thread3));
+		eval(shift(@thread2));	eval(shift(@thread3));
+	}
+
+	@thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,1);
+	@thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,1);
+	@thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,1);
+	@thread3=&ROUND(0,5,10,15);
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread3));
+		eval(shift(@thread1));	eval(shift(@thread3));
+		eval(shift(@thread2));	eval(shift(@thread3));
+	}
+$code.=<<___;
+	bne		.Loop_neon
+
+	add		@t[3],sp,#32
+	vld1.32		{$t0-$t1},[sp]		@ load key material
+	vld1.32		{$t2-$t3},[@t[3]]
+
+	ldr		@t[3],[sp,#4*(32+2)]	@ load len
+
+	str		@t[0], [sp,#4*(16+8)]	@ modulo-scheduled store
+	str		@t[1], [sp,#4*(16+9)]
+	str		@x[12],[sp,#4*(16+12)]
+	str		@t[2], [sp,#4*(16+13)]
+	str		@x[14],[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ @x[0-7] and second half at sp+4*(16+8)
+
+	ldr		r12,[sp,#4*(32+1)]	@ load inp
+	ldr		r14,[sp,#4*(32+0)]	@ load out
+
+	vadd.i32	$a0,$a0,$t0		@ accumulate key material
+	vadd.i32	$a1,$a1,$t0
+	vadd.i32	$a2,$a2,$t0
+	vldr		$t0#lo,[sp,#4*(16+0)]	@ one
+
+	vadd.i32	$b0,$b0,$t1
+	vadd.i32	$b1,$b1,$t1
+	vadd.i32	$b2,$b2,$t1
+	vldr		$t1#lo,[sp,#4*(16+2)]	@ two
+
+	vadd.i32	$c0,$c0,$t2
+	vadd.i32	$c1,$c1,$t2
+	vadd.i32	$c2,$c2,$t2
+	vadd.i32	$d1#lo,$d1#lo,$t0#lo	@ counter+1
+	vadd.i32	$d2#lo,$d2#lo,$t1#lo	@ counter+2
+
+	vadd.i32	$d0,$d0,$t3
+	vadd.i32	$d1,$d1,$t3
+	vadd.i32	$d2,$d2,$t3
+
+	cmp		@t[3],#64*4
+	blo		.Ltail_neon
+
+	vld1.8		{$t0-$t1},[r12]!	@ load input
+	 mov		@t[3],sp
+	vld1.8		{$t2-$t3},[r12]!
+	veor		$a0,$a0,$t0		@ xor with input
+	veor		$b0,$b0,$t1
+	vld1.8		{$t0-$t1},[r12]!
+	veor		$c0,$c0,$t2
+	veor		$d0,$d0,$t3
+	vld1.8		{$t2-$t3},[r12]!
+
+	veor		$a1,$a1,$t0
+	 vst1.8		{$a0-$b0},[r14]!	@ store output
+	veor		$b1,$b1,$t1
+	vld1.8		{$t0-$t1},[r12]!
+	veor		$c1,$c1,$t2
+	 vst1.8		{$c0-$d0},[r14]!
+	veor		$d1,$d1,$t3
+	vld1.8		{$t2-$t3},[r12]!
+
+	veor		$a2,$a2,$t0
+	 vld1.32	{$a0-$b0},[@t[3]]!	@ load for next iteration
+	 veor		$t0#hi,$t0#hi,$t0#hi
+	 vldr		$t0#lo,[sp,#4*(16+4)]	@ four
+	veor		$b2,$b2,$t1
+	 vld1.32	{$c0-$d0},[@t[3]]
+	veor		$c2,$c2,$t2
+	 vst1.8		{$a1-$b1},[r14]!
+	veor		$d2,$d2,$t3
+	 vst1.8		{$c1-$d1},[r14]!
+
+	vadd.i32	$d0#lo,$d0#lo,$t0#lo	@ next counter value
+	vldr		$t0#lo,[sp,#4*(16+0)]	@ one
+
+	ldmia		sp,{@t[0]-@t[3]}	@ load key material
+	add		@x[0],@x[0],@t[0]	@ accumulate key material
+	ldr		@t[0],[r12],#16		@ load input
+	 vst1.8		{$a2-$b2},[r14]!
+	add		@x[1],@x[1],@t[1]
+	ldr		@t[1],[r12,#-12]
+	 vst1.8		{$c2-$d2},[r14]!
+	add		@x[2],@x[2],@t[2]
+	ldr		@t[2],[r12,#-8]
+	add		@x[3],@x[3],@t[3]
+	ldr		@t[3],[r12,#-4]
+# ifdef	__ARMEB__
+	rev		@x[0],@x[0]
+	rev		@x[1],@x[1]
+	rev		@x[2],@x[2]
+	rev		@x[3],@x[3]
+# endif
+	eor		@x[0],@x[0],@t[0]	@ xor with input
+	 add		@t[0],sp,#4*(4)
+	eor		@x[1],@x[1],@t[1]
+	str		@x[0],[r14],#16		@ store output
+	eor		@x[2],@x[2],@t[2]
+	str		@x[1],[r14,#-12]
+	eor		@x[3],@x[3],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+	str		@x[2],[r14,#-8]
+	str		@x[3],[r14,#-4]
+
+	add		@x[4],@x[4],@t[0]	@ accumulate key material
+	ldr		@t[0],[r12],#16		@ load input
+	add		@x[5],@x[5],@t[1]
+	ldr		@t[1],[r12,#-12]
+	add		@x[6],@x[6],@t[2]
+	ldr		@t[2],[r12,#-8]
+	add		@x[7],@x[7],@t[3]
+	ldr		@t[3],[r12,#-4]
+# ifdef	__ARMEB__
+	rev		@x[4],@x[4]
+	rev		@x[5],@x[5]
+	rev		@x[6],@x[6]
+	rev		@x[7],@x[7]
+# endif
+	eor		@x[4],@x[4],@t[0]
+	 add		@t[0],sp,#4*(8)
+	eor		@x[5],@x[5],@t[1]
+	str		@x[4],[r14],#16		@ store output
+	eor		@x[6],@x[6],@t[2]
+	str		@x[5],[r14,#-12]
+	eor		@x[7],@x[7],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+	str		@x[6],[r14,#-8]
+	 add		@x[0],sp,#4*(16+8)
+	str		@x[7],[r14,#-4]
+
+	ldmia		@x[0],{@x[0]-@x[7]}	@ load second half
+
+	add		@x[0],@x[0],@t[0]	@ accumulate key material
+	ldr		@t[0],[r12],#16		@ load input
+	add		@x[1],@x[1],@t[1]
+	ldr		@t[1],[r12,#-12]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	 strhi		@t[2],[sp,#4*(16+10)]	@ copy "@x[10]" while at it
+	add		@x[2],@x[2],@t[2]
+	ldr		@t[2],[r12,#-8]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	 strhi		@t[3],[sp,#4*(16+11)]	@ copy "@x[11]" while at it
+	add		@x[3],@x[3],@t[3]
+	ldr		@t[3],[r12,#-4]
+# ifdef	__ARMEB__
+	rev		@x[0],@x[0]
+	rev		@x[1],@x[1]
+	rev		@x[2],@x[2]
+	rev		@x[3],@x[3]
+# endif
+	eor		@x[0],@x[0],@t[0]
+	 add		@t[0],sp,#4*(12)
+	eor		@x[1],@x[1],@t[1]
+	str		@x[0],[r14],#16		@ store output
+	eor		@x[2],@x[2],@t[2]
+	str		@x[1],[r14,#-12]
+	eor		@x[3],@x[3],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+	str		@x[2],[r14,#-8]
+	str		@x[3],[r14,#-4]
+
+	add		@x[4],@x[4],@t[0]	@ accumulate key material
+	 add		@t[0],@t[0],#4		@ next counter value
+	add		@x[5],@x[5],@t[1]
+	 str		@t[0],[sp,#4*(12)]	@ save next counter value
+	ldr		@t[0],[r12],#16		@ load input
+	add		@x[6],@x[6],@t[2]
+	 add		@x[4],@x[4],#3		@ counter+3
+	ldr		@t[1],[r12,#-12]
+	add		@x[7],@x[7],@t[3]
+	ldr		@t[2],[r12,#-8]
+	ldr		@t[3],[r12,#-4]
+# ifdef	__ARMEB__
+	rev		@x[4],@x[4]
+	rev		@x[5],@x[5]
+	rev		@x[6],@x[6]
+	rev		@x[7],@x[7]
+# endif
+	eor		@x[4],@x[4],@t[0]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	 ldrhi		@t[0],[sp,#4*(32+2)]	@ re-load len
+	eor		@x[5],@x[5],@t[1]
+	eor		@x[6],@x[6],@t[2]
+	str		@x[4],[r14],#16		@ store output
+	eor		@x[7],@x[7],@t[3]
+	str		@x[5],[r14,#-12]
+	 sub		@t[3],@t[0],#64*4	@ len-=64*4
+	str		@x[6],[r14,#-8]
+	str		@x[7],[r14,#-4]
+	bhi		.Loop_neon_outer
+
+	b		.Ldone_neon
+
+.align	4
+.Lbreak_neon:
+	@ harmonize NEON and integer-only stack frames: load data
+	@ from NEON frame, but save to integer-only one; distance
+	@ between the two is 4*(32+4+16-32)=4*(20).
+
+	str		@t[3], [sp,#4*(20+32+2)]	@ save len
+	 add		@t[3],sp,#4*(32+4)
+	str		r12,   [sp,#4*(20+32+1)]	@ save inp
+	str		r14,   [sp,#4*(20+32+0)]	@ save out
+
+	ldr		@x[12],[sp,#4*(16+10)]
+	ldr		@x[14],[sp,#4*(16+11)]
+	 vldmia		@t[3],{d8-d15}			@ fulfill ABI requirement
+	str		@x[12],[sp,#4*(20+16+10)]	@ copy "@x[10]"
+	str		@x[14],[sp,#4*(20+16+11)]	@ copy "@x[11]"
+
+	ldr		@t[3], [sp,#4*(15)]
+	ldr		@x[12],[sp,#4*(12)]		@ modulo-scheduled load
+	ldr		@t[2], [sp,#4*(13)]
+	ldr		@x[14],[sp,#4*(14)]
+	str		@t[3], [sp,#4*(20+16+15)]
+	add		@t[3],sp,#4*(20)
+	vst1.32		{$a0-$b0},[@t[3]]!		@ copy key
+	add		sp,sp,#4*(20)			@ switch frame
+	vst1.32		{$c0-$d0},[@t[3]]
+	mov		@t[3],#10
+	b		.Loop				@ go integer-only
+
+.align	4
+.Ltail_neon:
+	cmp		@t[3],#64*3
+	bhs		.L192_or_more_neon
+	cmp		@t[3],#64*2
+	bhs		.L128_or_more_neon
+	cmp		@t[3],#64*1
+	bhs		.L64_or_more_neon
+
+	add		@t[0],sp,#4*(8)
+	vst1.8		{$a0-$b0},[sp]
+	add		@t[2],sp,#4*(0)
+	vst1.8		{$c0-$d0},[@t[0]]
+	b		.Loop_tail_neon
+
+.align	4
+.L64_or_more_neon:
+	vld1.8		{$t0-$t1},[r12]!
+	vld1.8		{$t2-$t3},[r12]!
+	veor		$a0,$a0,$t0
+	veor		$b0,$b0,$t1
+	veor		$c0,$c0,$t2
+	veor		$d0,$d0,$t3
+	vst1.8		{$a0-$b0},[r14]!
+	vst1.8		{$c0-$d0},[r14]!
+
+	beq		.Ldone_neon
+
+	add		@t[0],sp,#4*(8)
+	vst1.8		{$a1-$b1},[sp]
+	add		@t[2],sp,#4*(0)
+	vst1.8		{$c1-$d1},[@t[0]]
+	sub		@t[3],@t[3],#64*1	@ len-=64*1
+	b		.Loop_tail_neon
+
+.align	4
+.L128_or_more_neon:
+	vld1.8		{$t0-$t1},[r12]!
+	vld1.8		{$t2-$t3},[r12]!
+	veor		$a0,$a0,$t0
+	veor		$b0,$b0,$t1
+	vld1.8		{$t0-$t1},[r12]!
+	veor		$c0,$c0,$t2
+	veor		$d0,$d0,$t3
+	vld1.8		{$t2-$t3},[r12]!
+
+	veor		$a1,$a1,$t0
+	veor		$b1,$b1,$t1
+	 vst1.8		{$a0-$b0},[r14]!
+	veor		$c1,$c1,$t2
+	 vst1.8		{$c0-$d0},[r14]!
+	veor		$d1,$d1,$t3
+	vst1.8		{$a1-$b1},[r14]!
+	vst1.8		{$c1-$d1},[r14]!
+
+	beq		.Ldone_neon
+
+	add		@t[0],sp,#4*(8)
+	vst1.8		{$a2-$b2},[sp]
+	add		@t[2],sp,#4*(0)
+	vst1.8		{$c2-$d2},[@t[0]]
+	sub		@t[3],@t[3],#64*2	@ len-=64*2
+	b		.Loop_tail_neon
+
+.align	4
+.L192_or_more_neon:
+	vld1.8		{$t0-$t1},[r12]!
+	vld1.8		{$t2-$t3},[r12]!
+	veor		$a0,$a0,$t0
+	veor		$b0,$b0,$t1
+	vld1.8		{$t0-$t1},[r12]!
+	veor		$c0,$c0,$t2
+	veor		$d0,$d0,$t3
+	vld1.8		{$t2-$t3},[r12]!
+
+	veor		$a1,$a1,$t0
+	veor		$b1,$b1,$t1
+	vld1.8		{$t0-$t1},[r12]!
+	veor		$c1,$c1,$t2
+	 vst1.8		{$a0-$b0},[r14]!
+	veor		$d1,$d1,$t3
+	vld1.8		{$t2-$t3},[r12]!
+
+	veor		$a2,$a2,$t0
+	 vst1.8		{$c0-$d0},[r14]!
+	veor		$b2,$b2,$t1
+	 vst1.8		{$a1-$b1},[r14]!
+	veor		$c2,$c2,$t2
+	 vst1.8		{$c1-$d1},[r14]!
+	veor		$d2,$d2,$t3
+	vst1.8		{$a2-$b2},[r14]!
+	vst1.8		{$c2-$d2},[r14]!
+
+	beq		.Ldone_neon
+
+	ldmia		sp,{@t[0]-@t[3]}	@ load key material
+	add		@x[0],@x[0],@t[0]	@ accumulate key material
+	 add		@t[0],sp,#4*(4)
+	add		@x[1],@x[1],@t[1]
+	add		@x[2],@x[2],@t[2]
+	add		@x[3],@x[3],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+
+	add		@x[4],@x[4],@t[0]	@ accumulate key material
+	 add		@t[0],sp,#4*(8)
+	add		@x[5],@x[5],@t[1]
+	add		@x[6],@x[6],@t[2]
+	add		@x[7],@x[7],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+# ifdef	__ARMEB__
+	rev		@x[0],@x[0]
+	rev		@x[1],@x[1]
+	rev		@x[2],@x[2]
+	rev		@x[3],@x[3]
+	rev		@x[4],@x[4]
+	rev		@x[5],@x[5]
+	rev		@x[6],@x[6]
+	rev		@x[7],@x[7]
+# endif
+	stmia		sp,{@x[0]-@x[7]}
+	 add		@x[0],sp,#4*(16+8)
+
+	ldmia		@x[0],{@x[0]-@x[7]}	@ load second half
+
+	add		@x[0],@x[0],@t[0]	@ accumulate key material
+	 add		@t[0],sp,#4*(12)
+	add		@x[1],@x[1],@t[1]
+	add		@x[2],@x[2],@t[2]
+	add		@x[3],@x[3],@t[3]
+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
+
+	add		@x[4],@x[4],@t[0]	@ accumulate key material
+	 add		@t[0],sp,#4*(8)
+	add		@x[5],@x[5],@t[1]
+	 add		@x[4],@x[4],#3		@ counter+3
+	add		@x[6],@x[6],@t[2]
+	add		@x[7],@x[7],@t[3]
+	 ldr		@t[3],[sp,#4*(32+2)]	@ re-load len
+# ifdef	__ARMEB__
+	rev		@x[0],@x[0]
+	rev		@x[1],@x[1]
+	rev		@x[2],@x[2]
+	rev		@x[3],@x[3]
+	rev		@x[4],@x[4]
+	rev		@x[5],@x[5]
+	rev		@x[6],@x[6]
+	rev		@x[7],@x[7]
+# endif
+	stmia		@t[0],{@x[0]-@x[7]}
+	 add		@t[2],sp,#4*(0)
+	 sub		@t[3],@t[3],#64*3	@ len-=64*3
+
+.Loop_tail_neon:
+	ldrb		@t[0],[@t[2]],#1	@ read buffer on stack
+	ldrb		@t[1],[r12],#1		@ read input
+	subs		@t[3],@t[3],#1
+	eor		@t[0],@t[0],@t[1]
+	strb		@t[0],[r14],#1		@ store ouput
+	bne		.Loop_tail_neon
+
+.Ldone_neon:
+	add		sp,sp,#4*(32+4)
+	vldmia		sp,{d8-d15}
+	add		sp,sp,#4*(16+3)
+	ldmia		sp!,{r4-r11,pc}
+.size	ChaCha20_neon,.-ChaCha20_neon
+.comm	OPENSSL_armcap_P,4,4
+#endif
+___
+}}}
+
+foreach (split("\n",$code)) {
+	s/\`([^\`]*)\`/eval $1/geo;
+
+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
+
+	print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/chacha/asm/chacha-armv8.pl b/src/crypto/chacha/asm/chacha-armv8.pl
new file mode 100755
index 0000000..215d965
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-armv8.pl
@@ -0,0 +1,1127 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# June 2015
+# 
+# ChaCha20 for ARMv8.
+#
+# Performance in cycles per byte out of large buffer.
+#
+#			IALU/gcc-4.9    3xNEON+1xIALU	6xNEON+2xIALU
+#
+# Apple A7		5.50/+49%       3.33            1.70
+# Cortex-A53		8.40/+80%       4.72		4.72(*)
+# Cortex-A57		8.06/+43%       4.90            4.43(**)
+# Denver		4.50/+82%       2.63		2.67(*)
+# X-Gene		9.50/+46%       8.82		8.89(*)
+#
+# (*)	it's expected that doubling interleave factor doesn't help
+#	all processors, only those with higher NEON latency and
+#	higher instruction issue rate;
+# (**)	expected improvement was actually higher;
+
+$flavour=shift;
+$output=shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+  my $arg = pop;
+    $arg = "#$arg" if ($arg*1 eq $arg);
+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
+}
+
+my ($out,$inp,$len,$key,$ctr) = map("x$_",(0..4));
+
+my @x=map("x$_",(5..17,19..21));
+my @d=map("x$_",(22..28,30));
+
+sub ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+
+    (
+	"&add_32	(@x[$a0],@x[$a0],@x[$b0])",
+	 "&add_32	(@x[$a1],@x[$a1],@x[$b1])",
+	  "&add_32	(@x[$a2],@x[$a2],@x[$b2])",
+	   "&add_32	(@x[$a3],@x[$a3],@x[$b3])",
+	"&eor_32	(@x[$d0],@x[$d0],@x[$a0])",
+	 "&eor_32	(@x[$d1],@x[$d1],@x[$a1])",
+	  "&eor_32	(@x[$d2],@x[$d2],@x[$a2])",
+	   "&eor_32	(@x[$d3],@x[$d3],@x[$a3])",
+	"&ror_32	(@x[$d0],@x[$d0],16)",
+	 "&ror_32	(@x[$d1],@x[$d1],16)",
+	  "&ror_32	(@x[$d2],@x[$d2],16)",
+	   "&ror_32	(@x[$d3],@x[$d3],16)",
+
+	"&add_32	(@x[$c0],@x[$c0],@x[$d0])",
+	 "&add_32	(@x[$c1],@x[$c1],@x[$d1])",
+	  "&add_32	(@x[$c2],@x[$c2],@x[$d2])",
+	   "&add_32	(@x[$c3],@x[$c3],@x[$d3])",
+	"&eor_32	(@x[$b0],@x[$b0],@x[$c0])",
+	 "&eor_32	(@x[$b1],@x[$b1],@x[$c1])",
+	  "&eor_32	(@x[$b2],@x[$b2],@x[$c2])",
+	   "&eor_32	(@x[$b3],@x[$b3],@x[$c3])",
+	"&ror_32	(@x[$b0],@x[$b0],20)",
+	 "&ror_32	(@x[$b1],@x[$b1],20)",
+	  "&ror_32	(@x[$b2],@x[$b2],20)",
+	   "&ror_32	(@x[$b3],@x[$b3],20)",
+
+	"&add_32	(@x[$a0],@x[$a0],@x[$b0])",
+	 "&add_32	(@x[$a1],@x[$a1],@x[$b1])",
+	  "&add_32	(@x[$a2],@x[$a2],@x[$b2])",
+	   "&add_32	(@x[$a3],@x[$a3],@x[$b3])",
+	"&eor_32	(@x[$d0],@x[$d0],@x[$a0])",
+	 "&eor_32	(@x[$d1],@x[$d1],@x[$a1])",
+	  "&eor_32	(@x[$d2],@x[$d2],@x[$a2])",
+	   "&eor_32	(@x[$d3],@x[$d3],@x[$a3])",
+	"&ror_32	(@x[$d0],@x[$d0],24)",
+	 "&ror_32	(@x[$d1],@x[$d1],24)",
+	  "&ror_32	(@x[$d2],@x[$d2],24)",
+	   "&ror_32	(@x[$d3],@x[$d3],24)",
+
+	"&add_32	(@x[$c0],@x[$c0],@x[$d0])",
+	 "&add_32	(@x[$c1],@x[$c1],@x[$d1])",
+	  "&add_32	(@x[$c2],@x[$c2],@x[$d2])",
+	   "&add_32	(@x[$c3],@x[$c3],@x[$d3])",
+	"&eor_32	(@x[$b0],@x[$b0],@x[$c0])",
+	 "&eor_32	(@x[$b1],@x[$b1],@x[$c1])",
+	  "&eor_32	(@x[$b2],@x[$b2],@x[$c2])",
+	   "&eor_32	(@x[$b3],@x[$b3],@x[$c3])",
+	"&ror_32	(@x[$b0],@x[$b0],25)",
+	 "&ror_32	(@x[$b1],@x[$b1],25)",
+	  "&ror_32	(@x[$b2],@x[$b2],25)",
+	   "&ror_32	(@x[$b3],@x[$b3],25)"
+    );
+}
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+
+.extern	OPENSSL_armcap_P
+
+.align	5
+.Lsigma:
+.quad	0x3320646e61707865,0x6b20657479622d32		// endian-neutral
+.Lone:
+.long	1,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef	__ILP32__
+.long	OPENSSL_armcap_P-.
+#else
+.quad	OPENSSL_armcap_P-.
+#endif
+.asciz	"ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+
+.globl	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+	cbz	$len,.Labort
+	adr	@x[0],.LOPENSSL_armcap_P
+	cmp	$len,#192
+	b.lo	.Lshort
+#ifdef	__ILP32__
+	ldrsw	@x[1],[@x[0]]
+#else
+	ldr	@x[1],[@x[0]]
+#endif
+	ldr	w17,[@x[1],@x[0]]
+	tst	w17,#ARMV7_NEON
+	b.ne	ChaCha20_neon
+
+.Lshort:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	@x[0],.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	sub	sp,sp,#64
+
+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
+	ldp	@d[2],@d[3],[$key]		// load key
+	ldp	@d[4],@d[5],[$key,#16]
+	ldp	@d[6],@d[7],[$ctr]		// load counter
+#ifdef	__ARMEB__
+	ror	@d[2],@d[2],#32
+	ror	@d[3],@d[3],#32
+	ror	@d[4],@d[4],#32
+	ror	@d[5],@d[5],#32
+	ror	@d[6],@d[6],#32
+	ror	@d[7],@d[7],#32
+#endif
+
+.Loop_outer:
+	mov.32	@x[0],@d[0]			// unpack key block
+	lsr	@x[1],@d[0],#32
+	mov.32	@x[2],@d[1]
+	lsr	@x[3],@d[1],#32
+	mov.32	@x[4],@d[2]
+	lsr	@x[5],@d[2],#32
+	mov.32	@x[6],@d[3]
+	lsr	@x[7],@d[3],#32
+	mov.32	@x[8],@d[4]
+	lsr	@x[9],@d[4],#32
+	mov.32	@x[10],@d[5]
+	lsr	@x[11],@d[5],#32
+	mov.32	@x[12],@d[6]
+	lsr	@x[13],@d[6],#32
+	mov.32	@x[14],@d[7]
+	lsr	@x[15],@d[7],#32
+
+	mov	$ctr,#10
+	subs	$len,$len,#64
+.Loop:
+	sub	$ctr,$ctr,#1	
+___
+	foreach (&ROUND(0, 4, 8,12)) { eval; }
+	foreach (&ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+	cbnz	$ctr,.Loop
+
+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
+	add	@x[1],@x[1],@d[0],lsr#32
+	add.32	@x[2],@x[2],@d[1]
+	add	@x[3],@x[3],@d[1],lsr#32
+	add.32	@x[4],@x[4],@d[2]
+	add	@x[5],@x[5],@d[2],lsr#32
+	add.32	@x[6],@x[6],@d[3]
+	add	@x[7],@x[7],@d[3],lsr#32
+	add.32	@x[8],@x[8],@d[4]
+	add	@x[9],@x[9],@d[4],lsr#32
+	add.32	@x[10],@x[10],@d[5]
+	add	@x[11],@x[11],@d[5],lsr#32
+	add.32	@x[12],@x[12],@d[6]
+	add	@x[13],@x[13],@d[6],lsr#32
+	add.32	@x[14],@x[14],@d[7]
+	add	@x[15],@x[15],@d[7],lsr#32
+
+	b.lo	.Ltail
+
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	add	@x[2],@x[2],@x[3],lsl#32
+	ldp	@x[1],@x[3],[$inp,#0]		// load input
+	add	@x[4],@x[4],@x[5],lsl#32
+	add	@x[6],@x[6],@x[7],lsl#32
+	ldp	@x[5],@x[7],[$inp,#16]
+	add	@x[8],@x[8],@x[9],lsl#32
+	add	@x[10],@x[10],@x[11],lsl#32
+	ldp	@x[9],@x[11],[$inp,#32]
+	add	@x[12],@x[12],@x[13],lsl#32
+	add	@x[14],@x[14],@x[15],lsl#32
+	ldp	@x[13],@x[15],[$inp,#48]
+	add	$inp,$inp,#64
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	eor	@x[0],@x[0],@x[1]
+	eor	@x[2],@x[2],@x[3]
+	eor	@x[4],@x[4],@x[5]
+	eor	@x[6],@x[6],@x[7]
+	eor	@x[8],@x[8],@x[9]
+	eor	@x[10],@x[10],@x[11]
+	eor	@x[12],@x[12],@x[13]
+	eor	@x[14],@x[14],@x[15]
+
+	stp	@x[0],@x[2],[$out,#0]		// store output
+	 add	@d[6],@d[6],#1			// increment counter
+	stp	@x[4],@x[6],[$out,#16]
+	stp	@x[8],@x[10],[$out,#32]
+	stp	@x[12],@x[14],[$out,#48]
+	add	$out,$out,#64
+
+	b.hi	.Loop_outer
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+.Labort:
+	ret
+
+.align	4
+.Ltail:
+	add	$len,$len,#64
+.Less_than_64:
+	sub	$out,$out,#1
+	add	$inp,$inp,$len
+	add	$out,$out,$len
+	add	$ctr,sp,$len
+	neg	$len,$len
+
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	add	@x[2],@x[2],@x[3],lsl#32
+	add	@x[4],@x[4],@x[5],lsl#32
+	add	@x[6],@x[6],@x[7],lsl#32
+	add	@x[8],@x[8],@x[9],lsl#32
+	add	@x[10],@x[10],@x[11],lsl#32
+	add	@x[12],@x[12],@x[13],lsl#32
+	add	@x[14],@x[14],@x[15],lsl#32
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	stp	@x[0],@x[2],[sp,#0]
+	stp	@x[4],@x[6],[sp,#16]
+	stp	@x[8],@x[10],[sp,#32]
+	stp	@x[12],@x[14],[sp,#48]
+
+.Loop_tail:
+	ldrb	w10,[$inp,$len]
+	ldrb	w11,[$ctr,$len]
+	add	$len,$len,#1
+	eor	w10,w10,w11
+	strb	w10,[$out,$len]
+	cbnz	$len,.Loop_tail
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+{{{
+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2,$T3) =
+    map("v$_.4s",(0..7,16..23));
+my (@K)=map("v$_.4s",(24..30));
+my $ONE="v31.4s";
+
+sub NEONROUND {
+my $odd = pop;
+my ($a,$b,$c,$d,$t)=@_;
+
+	(
+	"&add		('$a','$a','$b')",
+	"&eor		('$d','$d','$a')",
+	"&rev32_16	('$d','$d')",		# vrot ($d,16)
+
+	"&add		('$c','$c','$d')",
+	"&eor		('$t','$b','$c')",
+	"&ushr		('$b','$t',20)",
+	"&sli		('$b','$t',12)",
+
+	"&add		('$a','$a','$b')",
+	"&eor		('$t','$d','$a')",
+	"&ushr		('$d','$t',24)",
+	"&sli		('$d','$t',8)",
+
+	"&add		('$c','$c','$d')",
+	"&eor		('$t','$b','$c')",
+	"&ushr		('$b','$t',25)",
+	"&sli		('$b','$t',7)",
+
+	"&ext		('$c','$c','$c',8)",
+	"&ext		('$d','$d','$d',$odd?4:12)",
+	"&ext		('$b','$b','$b',$odd?12:4)"
+	);
+}
+
+$code.=<<___;
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	@x[0],.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	cmp	$len,#512
+	b.hs	.L512_or_more_neon
+
+	sub	sp,sp,#64
+
+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
+	ld1	{@K[0]},[@x[0]],#16
+	ldp	@d[2],@d[3],[$key]		// load key
+	ldp	@d[4],@d[5],[$key,#16]
+	ld1	{@K[1],@K[2]},[$key]
+	ldp	@d[6],@d[7],[$ctr]		// load counter
+	ld1	{@K[3]},[$ctr]
+	ld1	{$ONE},[@x[0]]
+#ifdef	__ARMEB__
+	rev64	@K[0],@K[0]
+	ror	@d[2],@d[2],#32
+	ror	@d[3],@d[3],#32
+	ror	@d[4],@d[4],#32
+	ror	@d[5],@d[5],#32
+	ror	@d[6],@d[6],#32
+	ror	@d[7],@d[7],#32
+#endif
+	add	@K[3],@K[3],$ONE		// += 1
+	add	@K[4],@K[3],$ONE
+	add	@K[5],@K[4],$ONE
+	shl	$ONE,$ONE,#2			// 1 -> 4
+
+.Loop_outer_neon:
+	mov.32	@x[0],@d[0]			// unpack key block
+	lsr	@x[1],@d[0],#32
+	 mov	$A0,@K[0]
+	mov.32	@x[2],@d[1]
+	lsr	@x[3],@d[1],#32
+	 mov	$A1,@K[0]
+	mov.32	@x[4],@d[2]
+	lsr	@x[5],@d[2],#32
+	 mov	$A2,@K[0]
+	mov.32	@x[6],@d[3]
+	 mov	$B0,@K[1]
+	lsr	@x[7],@d[3],#32
+	 mov	$B1,@K[1]
+	mov.32	@x[8],@d[4]
+	 mov	$B2,@K[1]
+	lsr	@x[9],@d[4],#32
+	 mov	$D0,@K[3]
+	mov.32	@x[10],@d[5]
+	 mov	$D1,@K[4]
+	lsr	@x[11],@d[5],#32
+	 mov	$D2,@K[5]
+	mov.32	@x[12],@d[6]
+	 mov	$C0,@K[2]
+	lsr	@x[13],@d[6],#32
+	 mov	$C1,@K[2]
+	mov.32	@x[14],@d[7]
+	 mov	$C2,@K[2]
+	lsr	@x[15],@d[7],#32
+
+	mov	$ctr,#10
+	subs	$len,$len,#256
+.Loop_neon:
+	sub	$ctr,$ctr,#1
+___
+	my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+	my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+	my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+	my @thread3=&ROUND(0,4,8,12);
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread3));
+		eval(shift(@thread1));	eval(shift(@thread3));
+		eval(shift(@thread2));	eval(shift(@thread3));
+	}
+
+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+	@thread3=&ROUND(0,5,10,15);
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread3));
+		eval(shift(@thread1));	eval(shift(@thread3));
+		eval(shift(@thread2));	eval(shift(@thread3));
+	}
+$code.=<<___;
+	cbnz	$ctr,.Loop_neon
+
+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
+	 add	$A0,$A0,@K[0]
+	add	@x[1],@x[1],@d[0],lsr#32
+	 add	$A1,$A1,@K[0]
+	add.32	@x[2],@x[2],@d[1]
+	 add	$A2,$A2,@K[0]
+	add	@x[3],@x[3],@d[1],lsr#32
+	 add	$C0,$C0,@K[2]
+	add.32	@x[4],@x[4],@d[2]
+	 add	$C1,$C1,@K[2]
+	add	@x[5],@x[5],@d[2],lsr#32
+	 add	$C2,$C2,@K[2]
+	add.32	@x[6],@x[6],@d[3]
+	 add	$D0,$D0,@K[3]
+	add	@x[7],@x[7],@d[3],lsr#32
+	add.32	@x[8],@x[8],@d[4]
+	 add	$D1,$D1,@K[4]
+	add	@x[9],@x[9],@d[4],lsr#32
+	add.32	@x[10],@x[10],@d[5]
+	 add	$D2,$D2,@K[5]
+	add	@x[11],@x[11],@d[5],lsr#32
+	add.32	@x[12],@x[12],@d[6]
+	 add	$B0,$B0,@K[1]
+	add	@x[13],@x[13],@d[6],lsr#32
+	add.32	@x[14],@x[14],@d[7]
+	 add	$B1,$B1,@K[1]
+	add	@x[15],@x[15],@d[7],lsr#32
+	 add	$B2,$B2,@K[1]
+
+	b.lo	.Ltail_neon
+
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	add	@x[2],@x[2],@x[3],lsl#32
+	ldp	@x[1],@x[3],[$inp,#0]		// load input
+	add	@x[4],@x[4],@x[5],lsl#32
+	add	@x[6],@x[6],@x[7],lsl#32
+	ldp	@x[5],@x[7],[$inp,#16]
+	add	@x[8],@x[8],@x[9],lsl#32
+	add	@x[10],@x[10],@x[11],lsl#32
+	ldp	@x[9],@x[11],[$inp,#32]
+	add	@x[12],@x[12],@x[13],lsl#32
+	add	@x[14],@x[14],@x[15],lsl#32
+	ldp	@x[13],@x[15],[$inp,#48]
+	add	$inp,$inp,#64
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	ld1.8	{$T0-$T3},[$inp],#64
+	eor	@x[0],@x[0],@x[1]
+	eor	@x[2],@x[2],@x[3]
+	eor	@x[4],@x[4],@x[5]
+	eor	@x[6],@x[6],@x[7]
+	eor	@x[8],@x[8],@x[9]
+	 eor	$A0,$A0,$T0
+	eor	@x[10],@x[10],@x[11]
+	 eor	$B0,$B0,$T1
+	eor	@x[12],@x[12],@x[13]
+	 eor	$C0,$C0,$T2
+	eor	@x[14],@x[14],@x[15]
+	 eor	$D0,$D0,$T3
+	 ld1.8	{$T0-$T3},[$inp],#64
+
+	stp	@x[0],@x[2],[$out,#0]		// store output
+	 add	@d[6],@d[6],#4			// increment counter
+	stp	@x[4],@x[6],[$out,#16]
+	 add	@K[3],@K[3],$ONE		// += 4
+	stp	@x[8],@x[10],[$out,#32]
+	 add	@K[4],@K[4],$ONE
+	stp	@x[12],@x[14],[$out,#48]
+	 add	@K[5],@K[5],$ONE
+	add	$out,$out,#64
+
+	st1.8	{$A0-$D0},[$out],#64
+	ld1.8	{$A0-$D0},[$inp],#64
+
+	eor	$A1,$A1,$T0
+	eor	$B1,$B1,$T1
+	eor	$C1,$C1,$T2
+	eor	$D1,$D1,$T3
+	st1.8	{$A1-$D1},[$out],#64
+
+	eor	$A2,$A2,$A0
+	eor	$B2,$B2,$B0
+	eor	$C2,$C2,$C0
+	eor	$D2,$D2,$D0
+	st1.8	{$A2-$D2},[$out],#64
+
+	b.hi	.Loop_outer_neon
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+
+.Ltail_neon:
+	add	$len,$len,#256
+	cmp	$len,#64
+	b.lo	.Less_than_64
+
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	add	@x[2],@x[2],@x[3],lsl#32
+	ldp	@x[1],@x[3],[$inp,#0]		// load input
+	add	@x[4],@x[4],@x[5],lsl#32
+	add	@x[6],@x[6],@x[7],lsl#32
+	ldp	@x[5],@x[7],[$inp,#16]
+	add	@x[8],@x[8],@x[9],lsl#32
+	add	@x[10],@x[10],@x[11],lsl#32
+	ldp	@x[9],@x[11],[$inp,#32]
+	add	@x[12],@x[12],@x[13],lsl#32
+	add	@x[14],@x[14],@x[15],lsl#32
+	ldp	@x[13],@x[15],[$inp,#48]
+	add	$inp,$inp,#64
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	eor	@x[0],@x[0],@x[1]
+	eor	@x[2],@x[2],@x[3]
+	eor	@x[4],@x[4],@x[5]
+	eor	@x[6],@x[6],@x[7]
+	eor	@x[8],@x[8],@x[9]
+	eor	@x[10],@x[10],@x[11]
+	eor	@x[12],@x[12],@x[13]
+	eor	@x[14],@x[14],@x[15]
+
+	stp	@x[0],@x[2],[$out,#0]		// store output
+	 add	@d[6],@d[6],#4			// increment counter
+	stp	@x[4],@x[6],[$out,#16]
+	stp	@x[8],@x[10],[$out,#32]
+	stp	@x[12],@x[14],[$out,#48]
+	add	$out,$out,#64
+	b.eq	.Ldone_neon
+	sub	$len,$len,#64
+	cmp	$len,#64
+	b.lo	.Less_than_128
+
+	ld1.8	{$T0-$T3},[$inp],#64
+	eor	$A0,$A0,$T0
+	eor	$B0,$B0,$T1
+	eor	$C0,$C0,$T2
+	eor	$D0,$D0,$T3
+	st1.8	{$A0-$D0},[$out],#64
+	b.eq	.Ldone_neon
+	sub	$len,$len,#64
+	cmp	$len,#64
+	b.lo	.Less_than_192
+
+	ld1.8	{$T0-$T3},[$inp],#64
+	eor	$A1,$A1,$T0
+	eor	$B1,$B1,$T1
+	eor	$C1,$C1,$T2
+	eor	$D1,$D1,$T3
+	st1.8	{$A1-$D1},[$out],#64
+	b.eq	.Ldone_neon
+	sub	$len,$len,#64
+
+	st1.8	{$A2-$D2},[sp]
+	b	.Last_neon
+
+.Less_than_128:
+	st1.8	{$A0-$D0},[sp]
+	b	.Last_neon
+.Less_than_192:
+	st1.8	{$A1-$D1},[sp]
+	b	.Last_neon
+
+.align	4
+.Last_neon:
+	sub	$out,$out,#1
+	add	$inp,$inp,$len
+	add	$out,$out,$len
+	add	$ctr,sp,$len
+	neg	$len,$len
+
+.Loop_tail_neon:
+	ldrb	w10,[$inp,$len]
+	ldrb	w11,[$ctr,$len]
+	add	$len,$len,#1
+	eor	w10,w10,w11
+	strb	w10,[$out,$len]
+	cbnz	$len,.Loop_tail_neon
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+.Ldone_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_neon,.-ChaCha20_neon
+___
+{
+my ($T0,$T1,$T2,$T3,$T4,$T5)=@K;
+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,
+    $A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(0..23));
+
+$code.=<<___;
+.type	ChaCha20_512_neon,%function
+.align	5
+ChaCha20_512_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	@x[0],.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+
+.L512_or_more_neon:
+	sub	sp,sp,#128+64
+
+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
+	ld1	{@K[0]},[@x[0]],#16
+	ldp	@d[2],@d[3],[$key]		// load key
+	ldp	@d[4],@d[5],[$key,#16]
+	ld1	{@K[1],@K[2]},[$key]
+	ldp	@d[6],@d[7],[$ctr]		// load counter
+	ld1	{@K[3]},[$ctr]
+	ld1	{$ONE},[@x[0]]
+#ifdef	__ARMEB__
+	rev64	@K[0],@K[0]
+	ror	@d[2],@d[2],#32
+	ror	@d[3],@d[3],#32
+	ror	@d[4],@d[4],#32
+	ror	@d[5],@d[5],#32
+	ror	@d[6],@d[6],#32
+	ror	@d[7],@d[7],#32
+#endif
+	add	@K[3],@K[3],$ONE		// += 1
+	stp	@K[0],@K[1],[sp,#0]		// off-load key block, invariant part
+	add	@K[3],@K[3],$ONE		// not typo
+	str	@K[2],[sp,#32]
+	add	@K[4],@K[3],$ONE
+	add	@K[5],@K[4],$ONE
+	add	@K[6],@K[5],$ONE
+	shl	$ONE,$ONE,#2			// 1 -> 4
+
+	stp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	stp	d10,d11,[sp,#128+16]
+	stp	d12,d13,[sp,#128+32]
+	stp	d14,d15,[sp,#128+48]
+
+	sub	$len,$len,#512			// not typo
+
+.Loop_outer_512_neon:
+	 mov	$A0,@K[0]
+	 mov	$A1,@K[0]
+	 mov	$A2,@K[0]
+	 mov	$A3,@K[0]
+	 mov	$A4,@K[0]
+	 mov	$A5,@K[0]
+	 mov	$B0,@K[1]
+	mov.32	@x[0],@d[0]			// unpack key block
+	 mov	$B1,@K[1]
+	lsr	@x[1],@d[0],#32
+	 mov	$B2,@K[1]
+	mov.32	@x[2],@d[1]
+	 mov	$B3,@K[1]
+	lsr	@x[3],@d[1],#32
+	 mov	$B4,@K[1]
+	mov.32	@x[4],@d[2]
+	 mov	$B5,@K[1]
+	lsr	@x[5],@d[2],#32
+	 mov	$D0,@K[3]
+	mov.32	@x[6],@d[3]
+	 mov	$D1,@K[4]
+	lsr	@x[7],@d[3],#32
+	 mov	$D2,@K[5]
+	mov.32	@x[8],@d[4]
+	 mov	$D3,@K[6]
+	lsr	@x[9],@d[4],#32
+	 mov	$C0,@K[2]
+	mov.32	@x[10],@d[5]
+	 mov	$C1,@K[2]
+	lsr	@x[11],@d[5],#32
+	 add	$D4,$D0,$ONE			// +4
+	mov.32	@x[12],@d[6]
+	 add	$D5,$D1,$ONE			// +4
+	lsr	@x[13],@d[6],#32
+	 mov	$C2,@K[2]
+	mov.32	@x[14],@d[7]
+	 mov	$C3,@K[2]
+	lsr	@x[15],@d[7],#32
+	 mov	$C4,@K[2]
+	 stp	@K[3],@K[4],[sp,#48]		// off-load key block, variable part
+	 mov	$C5,@K[2]
+	 str	@K[5],[sp,#80]
+
+	mov	$ctr,#5
+	subs	$len,$len,#512
+.Loop_upper_neon:
+	sub	$ctr,$ctr,#1
+___
+	my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+	my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+	my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+	my @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
+	my @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
+	my @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
+	my @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+	my $diff = ($#thread0+1)*6 - $#thread67 - 1;
+	my $i = 0;
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread67));
+		eval(shift(@thread1));	eval(shift(@thread67));
+		eval(shift(@thread2));	eval(shift(@thread67));
+		eval(shift(@thread3));	eval(shift(@thread67));
+		eval(shift(@thread4));	eval(shift(@thread67));
+		eval(shift(@thread5));	eval(shift(@thread67));
+	}
+
+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread67));
+		eval(shift(@thread1));	eval(shift(@thread67));
+		eval(shift(@thread2));	eval(shift(@thread67));
+		eval(shift(@thread3));	eval(shift(@thread67));
+		eval(shift(@thread4));	eval(shift(@thread67));
+		eval(shift(@thread5));	eval(shift(@thread67));
+	}
+$code.=<<___;
+	cbnz	$ctr,.Loop_upper_neon
+
+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
+	add	@x[1],@x[1],@d[0],lsr#32
+	add.32	@x[2],@x[2],@d[1]
+	add	@x[3],@x[3],@d[1],lsr#32
+	add.32	@x[4],@x[4],@d[2]
+	add	@x[5],@x[5],@d[2],lsr#32
+	add.32	@x[6],@x[6],@d[3]
+	add	@x[7],@x[7],@d[3],lsr#32
+	add.32	@x[8],@x[8],@d[4]
+	add	@x[9],@x[9],@d[4],lsr#32
+	add.32	@x[10],@x[10],@d[5]
+	add	@x[11],@x[11],@d[5],lsr#32
+	add.32	@x[12],@x[12],@d[6]
+	add	@x[13],@x[13],@d[6],lsr#32
+	add.32	@x[14],@x[14],@d[7]
+	add	@x[15],@x[15],@d[7],lsr#32
+
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	add	@x[2],@x[2],@x[3],lsl#32
+	ldp	@x[1],@x[3],[$inp,#0]		// load input
+	add	@x[4],@x[4],@x[5],lsl#32
+	add	@x[6],@x[6],@x[7],lsl#32
+	ldp	@x[5],@x[7],[$inp,#16]
+	add	@x[8],@x[8],@x[9],lsl#32
+	add	@x[10],@x[10],@x[11],lsl#32
+	ldp	@x[9],@x[11],[$inp,#32]
+	add	@x[12],@x[12],@x[13],lsl#32
+	add	@x[14],@x[14],@x[15],lsl#32
+	ldp	@x[13],@x[15],[$inp,#48]
+	add	$inp,$inp,#64
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	eor	@x[0],@x[0],@x[1]
+	eor	@x[2],@x[2],@x[3]
+	eor	@x[4],@x[4],@x[5]
+	eor	@x[6],@x[6],@x[7]
+	eor	@x[8],@x[8],@x[9]
+	eor	@x[10],@x[10],@x[11]
+	eor	@x[12],@x[12],@x[13]
+	eor	@x[14],@x[14],@x[15]
+
+	 stp	@x[0],@x[2],[$out,#0]		// store output
+	 add	@d[6],@d[6],#1			// increment counter
+	mov.32	@x[0],@d[0]			// unpack key block
+	lsr	@x[1],@d[0],#32
+	 stp	@x[4],@x[6],[$out,#16]
+	mov.32	@x[2],@d[1]
+	lsr	@x[3],@d[1],#32
+	 stp	@x[8],@x[10],[$out,#32]
+	mov.32	@x[4],@d[2]
+	lsr	@x[5],@d[2],#32
+	 stp	@x[12],@x[14],[$out,#48]
+	 add	$out,$out,#64
+	mov.32	@x[6],@d[3]
+	lsr	@x[7],@d[3],#32
+	mov.32	@x[8],@d[4]
+	lsr	@x[9],@d[4],#32
+	mov.32	@x[10],@d[5]
+	lsr	@x[11],@d[5],#32
+	mov.32	@x[12],@d[6]
+	lsr	@x[13],@d[6],#32
+	mov.32	@x[14],@d[7]
+	lsr	@x[15],@d[7],#32
+
+	mov	$ctr,#5
+.Loop_lower_neon:
+	sub	$ctr,$ctr,#1
+___
+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread67));
+		eval(shift(@thread1));	eval(shift(@thread67));
+		eval(shift(@thread2));	eval(shift(@thread67));
+		eval(shift(@thread3));	eval(shift(@thread67));
+		eval(shift(@thread4));	eval(shift(@thread67));
+		eval(shift(@thread5));	eval(shift(@thread67));
+	}
+
+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+	foreach (@thread0) {
+		eval;			eval(shift(@thread67));
+		eval(shift(@thread1));	eval(shift(@thread67));
+		eval(shift(@thread2));	eval(shift(@thread67));
+		eval(shift(@thread3));	eval(shift(@thread67));
+		eval(shift(@thread4));	eval(shift(@thread67));
+		eval(shift(@thread5));	eval(shift(@thread67));
+	}
+$code.=<<___;
+	cbnz	$ctr,.Loop_lower_neon
+
+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
+	 ldp	@K[0],@K[1],[sp,#0]
+	add	@x[1],@x[1],@d[0],lsr#32
+	 ldp	@K[2],@K[3],[sp,#32]
+	add.32	@x[2],@x[2],@d[1]
+	 ldp	@K[4],@K[5],[sp,#64]
+	add	@x[3],@x[3],@d[1],lsr#32
+	 add	$A0,$A0,@K[0]
+	add.32	@x[4],@x[4],@d[2]
+	 add	$A1,$A1,@K[0]
+	add	@x[5],@x[5],@d[2],lsr#32
+	 add	$A2,$A2,@K[0]
+	add.32	@x[6],@x[6],@d[3]
+	 add	$A3,$A3,@K[0]
+	add	@x[7],@x[7],@d[3],lsr#32
+	 add	$A4,$A4,@K[0]
+	add.32	@x[8],@x[8],@d[4]
+	 add	$A5,$A5,@K[0]
+	add	@x[9],@x[9],@d[4],lsr#32
+	 add	$C0,$C0,@K[2]
+	add.32	@x[10],@x[10],@d[5]
+	 add	$C1,$C1,@K[2]
+	add	@x[11],@x[11],@d[5],lsr#32
+	 add	$C2,$C2,@K[2]
+	add.32	@x[12],@x[12],@d[6]
+	 add	$C3,$C3,@K[2]
+	add	@x[13],@x[13],@d[6],lsr#32
+	 add	$C4,$C4,@K[2]
+	add.32	@x[14],@x[14],@d[7]
+	 add	$C5,$C5,@K[2]
+	add	@x[15],@x[15],@d[7],lsr#32
+	 add	$D4,$D4,$ONE			// +4
+	add	@x[0],@x[0],@x[1],lsl#32	// pack
+	 add	$D5,$D5,$ONE			// +4
+	add	@x[2],@x[2],@x[3],lsl#32
+	 add	$D0,$D0,@K[3]
+	ldp	@x[1],@x[3],[$inp,#0]		// load input
+	 add	$D1,$D1,@K[4]
+	add	@x[4],@x[4],@x[5],lsl#32
+	 add	$D2,$D2,@K[5]
+	add	@x[6],@x[6],@x[7],lsl#32
+	 add	$D3,$D3,@K[6]
+	ldp	@x[5],@x[7],[$inp,#16]
+	 add	$D4,$D4,@K[3]
+	add	@x[8],@x[8],@x[9],lsl#32
+	 add	$D5,$D5,@K[4]
+	add	@x[10],@x[10],@x[11],lsl#32
+	 add	$B0,$B0,@K[1]
+	ldp	@x[9],@x[11],[$inp,#32]
+	 add	$B1,$B1,@K[1]
+	add	@x[12],@x[12],@x[13],lsl#32
+	 add	$B2,$B2,@K[1]
+	add	@x[14],@x[14],@x[15],lsl#32
+	 add	$B3,$B3,@K[1]
+	ldp	@x[13],@x[15],[$inp,#48]
+	 add	$B4,$B4,@K[1]
+	add	$inp,$inp,#64
+	 add	$B5,$B5,@K[1]
+
+#ifdef	__ARMEB__
+	rev	@x[0],@x[0]
+	rev	@x[2],@x[2]
+	rev	@x[4],@x[4]
+	rev	@x[6],@x[6]
+	rev	@x[8],@x[8]
+	rev	@x[10],@x[10]
+	rev	@x[12],@x[12]
+	rev	@x[14],@x[14]
+#endif
+	ld1.8	{$T0-$T3},[$inp],#64
+	eor	@x[0],@x[0],@x[1]
+	eor	@x[2],@x[2],@x[3]
+	eor	@x[4],@x[4],@x[5]
+	eor	@x[6],@x[6],@x[7]
+	eor	@x[8],@x[8],@x[9]
+	 eor	$A0,$A0,$T0
+	eor	@x[10],@x[10],@x[11]
+	 eor	$B0,$B0,$T1
+	eor	@x[12],@x[12],@x[13]
+	 eor	$C0,$C0,$T2
+	eor	@x[14],@x[14],@x[15]
+	 eor	$D0,$D0,$T3
+	 ld1.8	{$T0-$T3},[$inp],#64
+
+	stp	@x[0],@x[2],[$out,#0]		// store output
+	 add	@d[6],@d[6],#7			// increment counter
+	stp	@x[4],@x[6],[$out,#16]
+	stp	@x[8],@x[10],[$out,#32]
+	stp	@x[12],@x[14],[$out,#48]
+	add	$out,$out,#64
+	st1.8	{$A0-$D0},[$out],#64
+
+	ld1.8	{$A0-$D0},[$inp],#64
+	eor	$A1,$A1,$T0
+	eor	$B1,$B1,$T1
+	eor	$C1,$C1,$T2
+	eor	$D1,$D1,$T3
+	st1.8	{$A1-$D1},[$out],#64
+
+	ld1.8	{$A1-$D1},[$inp],#64
+	eor	$A2,$A2,$A0
+	 ldp	@K[0],@K[1],[sp,#0]
+	eor	$B2,$B2,$B0
+	 ldp	@K[2],@K[3],[sp,#32]
+	eor	$C2,$C2,$C0
+	eor	$D2,$D2,$D0
+	st1.8	{$A2-$D2},[$out],#64
+
+	ld1.8	{$A2-$D2},[$inp],#64
+	eor	$A3,$A3,$A1
+	eor	$B3,$B3,$B1
+	eor	$C3,$C3,$C1
+	eor	$D3,$D3,$D1
+	st1.8	{$A3-$D3},[$out],#64
+
+	ld1.8	{$A3-$D3},[$inp],#64
+	eor	$A4,$A4,$A2
+	eor	$B4,$B4,$B2
+	eor	$C4,$C4,$C2
+	eor	$D4,$D4,$D2
+	st1.8	{$A4-$D4},[$out],#64
+
+	shl	$A0,$ONE,#1			// 4 -> 8
+	eor	$A5,$A5,$A3
+	eor	$B5,$B5,$B3
+	eor	$C5,$C5,$C3
+	eor	$D5,$D5,$D3
+	st1.8	{$A5-$D5},[$out],#64
+
+	add	@K[3],@K[3],$A0			// += 8
+	add	@K[4],@K[4],$A0
+	add	@K[5],@K[5],$A0
+	add	@K[6],@K[6],$A0
+
+	b.hs	.Loop_outer_512_neon
+
+	adds	$len,$len,#512
+	ushr	$A0,$ONE,#2			// 4 -> 1
+
+	ldp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	ldp	d10,d11,[sp,#128+16]
+	ldp	d12,d13,[sp,#128+32]
+	ldp	d14,d15,[sp,#128+48]
+
+	stp	@K[0],$ONE,[sp,#0]		// wipe off-load area
+	stp	@K[0],$ONE,[sp,#32]
+	stp	@K[0],$ONE,[sp,#64]
+
+	b.eq	.Ldone_512_neon
+
+	cmp	$len,#192
+	sub	@K[3],@K[3],$A0			// -= 1
+	sub	@K[4],@K[4],$A0
+	sub	@K[5],@K[5],$A0
+	add	sp,sp,#128
+	b.hs	.Loop_outer_neon
+
+	eor	@K[1],@K[1],@K[1]
+	eor	@K[2],@K[2],@K[2]
+	eor	@K[3],@K[3],@K[3]
+	eor	@K[4],@K[4],@K[4]
+	eor	@K[5],@K[5],@K[5]
+	eor	@K[6],@K[6],@K[6]
+	b	.Loop_outer
+
+.Ldone_512_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#128+64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_512_neon,.-ChaCha20_512_neon
+___
+}
+}}}
+
+foreach (split("\n",$code)) {
+	s/\`([^\`]*)\`/eval $1/geo;
+
+	(s/\b([a-z]+)\.32\b/$1/ and (s/x([0-9]+)/w$1/g or 1))	or
+	(m/\b(eor|ext|mov)\b/ and (s/\.4s/\.16b/g or 1))	or
+	(s/\b((?:ld|st)1)\.8\b/$1/ and (s/\.4s/\.16b/g or 1))	or
+	(m/\b(ld|st)[rp]\b/ and (s/v([0-9]+)\.4s/q$1/g or 1))	or
+	(s/\brev32\.16\b/rev32/ and (s/\.4s/\.8h/g or 1));
+
+	#s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
+
+	print $_,"\n";
+}
+close STDOUT;	# flush
diff --git a/src/crypto/chacha/asm/chacha-x86.pl b/src/crypto/chacha/asm/chacha-x86.pl
new file mode 100755
index 0000000..e576029
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-x86.pl
@@ -0,0 +1,769 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# January 2015
+#
+# ChaCha20 for x86.
+#
+# Performance in cycles per byte out of large buffer.
+#
+#		1xIALU/gcc	4xSSSE3
+# Pentium	17.5/+80%
+# PIII		14.2/+60%
+# P4		18.6/+84%
+# Core2		9.56/+89%	4.83
+# Westmere	9.50/+45%	3.35
+# Sandy Bridge	10.7/+47%	3.24
+# Haswell	8.22/+50%	2.89
+# Silvermont	17.8/+36%	8.53
+# Sledgehammer	10.2/+54%
+# Bulldozer	13.5/+50%	4.39(*)
+#
+# (*)  Bulldozer actually executes 4xXOP code path that delivers 3.50;
+#
+# Modified from upstream OpenSSL to remove the XOP code.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"chacha-x86.pl",$ARGV[$#ARGV] eq "386");
+
+$xmm=$ymm=0;
+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+$ymm=$xmm;
+
+$a="eax";
+($b,$b_)=("ebx","ebp");
+($c,$c_)=("ecx","esi");
+($d,$d_)=("edx","edi");
+
+sub QUARTERROUND {
+my ($ai,$bi,$ci,$di,$i)=@_;
+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di));	# next
+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di));	# previous
+
+	#       a   b   c   d
+	#
+	#       0   4   8  12 < even round
+	#       1   5   9  13
+	#       2   6  10  14
+	#       3   7  11  15
+	#       0   5  10  15 < odd round
+	#       1   6  11  12
+	#       2   7   8  13
+	#       3   4   9  14
+
+	if ($i==0) {
+            my $j=4;
+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
+	} elsif ($i==3) {
+            my $j=0;
+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
+	} elsif ($i==4) {
+            my $j=4;
+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
+	} elsif ($i==7) {
+            my $j=0;
+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
+	}
+
+	#&add	($a,$b);			# see elsewhere
+	&xor	($d,$a);
+	 &mov	(&DWP(4*$cp,"esp"),$c_)		if ($ai>0 && $ai<3);
+	&rol	($d,16);
+	 &mov	(&DWP(4*$bp,"esp"),$b_)		if ($i!=0);
+	&add	($c,$d);
+	 &mov	($c_,&DWP(4*$cn,"esp"))		if ($ai>0 && $ai<3);
+	&xor	($b,$c);
+	 &mov	($d_,&DWP(4*$dn,"esp"))		if ($di!=$dn);
+	&rol	($b,12);
+	 &mov	($b_,&DWP(4*$bn,"esp"))		if ($i<7);
+	 &mov	($b_,&DWP(128,"esp"))		if ($i==7);	# loop counter
+	&add	($a,$b);
+	&xor	($d,$a);
+	&mov	(&DWP(4*$ai,"esp"),$a);
+	&rol	($d,8);
+	&mov	($a,&DWP(4*$an,"esp"));
+	&add	($c,$d);
+	&mov	(&DWP(4*$di,"esp"),$d)		if ($di!=$dn);
+	&mov	($d_,$d)			if ($di==$dn);
+	&xor	($b,$c);
+	 &add	($a,$b_)			if ($i<7);	# elsewhere
+	&rol	($b,7);
+
+	($b,$b_)=($b_,$b);
+	($c,$c_)=($c_,$c);
+	($d,$d_)=($d_,$d);
+}
+
+&static_label("ssse3_shortcut");
+&static_label("ssse3_data");
+&static_label("pic_point");
+
+&function_begin("ChaCha20_ctr32");
+	&xor	("eax","eax");
+	&cmp	("eax",&wparam(2));		# len==0?
+	&je	(&label("no_data"));
+if ($xmm) {
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop("eax");
+	&picmeup("ebp","OPENSSL_ia32cap_P","eax",&label("pic_point"));
+	&test	(&DWP(0,"ebp"),1<<24);		# test FXSR bit
+	&jz	(&label("x86"));
+	&test	(&DWP(4,"ebp"),1<<9);		# test SSSE3 bit
+	&jz	(&label("x86"));
+	&jmp	(&label("ssse3_shortcut"));
+&set_label("x86");
+}
+	&mov	("esi",&wparam(3));		# key
+	&mov	("edi",&wparam(4));		# counter and nonce
+
+	&stack_push(33);
+
+	&mov	("eax",&DWP(4*0,"esi"));	# copy key
+	&mov	("ebx",&DWP(4*1,"esi"));
+	&mov	("ecx",&DWP(4*2,"esi"));
+	&mov	("edx",&DWP(4*3,"esi"));
+	&mov	(&DWP(64+4*4,"esp"),"eax");
+	&mov	(&DWP(64+4*5,"esp"),"ebx");
+	&mov	(&DWP(64+4*6,"esp"),"ecx");
+	&mov	(&DWP(64+4*7,"esp"),"edx");
+	&mov	("eax",&DWP(4*4,"esi"));
+	&mov	("ebx",&DWP(4*5,"esi"));
+	&mov	("ecx",&DWP(4*6,"esi"));
+	&mov	("edx",&DWP(4*7,"esi"));
+	&mov	(&DWP(64+4*8,"esp"),"eax");
+	&mov	(&DWP(64+4*9,"esp"),"ebx");
+	&mov	(&DWP(64+4*10,"esp"),"ecx");
+	&mov	(&DWP(64+4*11,"esp"),"edx");
+	&mov	("eax",&DWP(4*0,"edi"));	# copy counter and nonce
+	&mov	("ebx",&DWP(4*1,"edi"));
+	&mov	("ecx",&DWP(4*2,"edi"));
+	&mov	("edx",&DWP(4*3,"edi"));
+	&sub	("eax",1);
+	&mov	(&DWP(64+4*12,"esp"),"eax");
+	&mov	(&DWP(64+4*13,"esp"),"ebx");
+	&mov	(&DWP(64+4*14,"esp"),"ecx");
+	&mov	(&DWP(64+4*15,"esp"),"edx");
+	&jmp	(&label("entry"));
+
+&set_label("outer_loop",16);
+	&mov	(&wparam(1),$b);		# save input
+	&mov	(&wparam(0),$a);		# save output
+	&mov	(&wparam(2),$c);		# save len
+&set_label("entry");
+	&mov	($a,0x61707865);
+	&mov	(&DWP(4*1,"esp"),0x3320646e);
+	&mov	(&DWP(4*2,"esp"),0x79622d32);
+	&mov	(&DWP(4*3,"esp"),0x6b206574);
+
+	&mov	($b, &DWP(64+4*5,"esp"));	# copy key material
+	&mov	($b_,&DWP(64+4*6,"esp"));
+	&mov	($c, &DWP(64+4*10,"esp"));
+	&mov	($c_,&DWP(64+4*11,"esp"));
+	&mov	($d, &DWP(64+4*13,"esp"));
+	&mov	($d_,&DWP(64+4*14,"esp"));
+	&mov	(&DWP(4*5,"esp"),$b);
+	&mov	(&DWP(4*6,"esp"),$b_);
+	&mov	(&DWP(4*10,"esp"),$c);
+	&mov	(&DWP(4*11,"esp"),$c_);
+	&mov	(&DWP(4*13,"esp"),$d);
+	&mov	(&DWP(4*14,"esp"),$d_);
+
+	&mov	($b, &DWP(64+4*7,"esp"));
+	&mov	($d_,&DWP(64+4*15,"esp"));
+	&mov	($d, &DWP(64+4*12,"esp"));
+	&mov	($b_,&DWP(64+4*4,"esp"));
+	&mov	($c, &DWP(64+4*8,"esp"));
+	&mov	($c_,&DWP(64+4*9,"esp"));
+	&add	($d,1);				# counter value
+	&mov	(&DWP(4*7,"esp"),$b);
+	&mov	(&DWP(4*15,"esp"),$d_);
+	&mov	(&DWP(64+4*12,"esp"),$d);	# save counter value
+
+	&mov	($b,10);			# loop counter
+	&jmp	(&label("loop"));
+
+&set_label("loop",16);
+	&add	($a,$b_);			# elsewhere
+	&mov	(&DWP(128,"esp"),$b);		# save loop counter
+	&mov	($b,$b_);
+	&QUARTERROUND(0, 4, 8, 12, 0);
+	&QUARTERROUND(1, 5, 9, 13, 1);
+	&QUARTERROUND(2, 6,10, 14, 2);
+	&QUARTERROUND(3, 7,11, 15, 3);
+	&QUARTERROUND(0, 5,10, 15, 4);
+	&QUARTERROUND(1, 6,11, 12, 5);
+	&QUARTERROUND(2, 7, 8, 13, 6);
+	&QUARTERROUND(3, 4, 9, 14, 7);
+	&dec	($b);
+	&jnz	(&label("loop"));
+
+	&mov	($b,&wparam(2));		# load len
+
+	&add	($a,0x61707865);		# accumulate key material
+	&add	($b_,&DWP(64+4*4,"esp"));
+	&add	($c, &DWP(64+4*8,"esp"));
+	&add	($c_,&DWP(64+4*9,"esp"));
+
+	&cmp	($b,64);
+	&jb	(&label("tail"));
+
+	&mov	($b,&wparam(1));		# load input pointer
+	&add	($d, &DWP(64+4*12,"esp"));
+	&add	($d_,&DWP(64+4*14,"esp"));
+
+	&xor	($a, &DWP(4*0,$b));		# xor with input
+	&xor	($b_,&DWP(4*4,$b));
+	&mov	(&DWP(4*0,"esp"),$a);		# off-load for later write
+	&mov	($a,&wparam(0));		# load output pointer
+	&xor	($c, &DWP(4*8,$b));
+	&xor	($c_,&DWP(4*9,$b));
+	&xor	($d, &DWP(4*12,$b));
+	&xor	($d_,&DWP(4*14,$b));
+	&mov	(&DWP(4*4,"esp"),$b_);
+	&mov	($b_,&DWP(4*0,"esp"));
+	&mov	(&DWP(4*8,"esp"),$c);
+	&mov	(&DWP(4*9,"esp"),$c_);
+	&mov	(&DWP(4*12,"esp"),$d);
+	&mov	(&DWP(4*14,"esp"),$d_);
+
+	&mov	(&DWP(4*0,$a),$b_);		# write output in order
+	&mov	($b_,&DWP(4*1,"esp"));
+	&mov	($c, &DWP(4*2,"esp"));
+	&mov	($c_,&DWP(4*3,"esp"));
+	&mov	($d, &DWP(4*5,"esp"));
+	&mov	($d_,&DWP(4*6,"esp"));
+	&add	($b_,0x3320646e);		# accumulate key material
+	&add	($c, 0x79622d32);
+	&add	($c_,0x6b206574);
+	&add	($d, &DWP(64+4*5,"esp"));
+	&add	($d_,&DWP(64+4*6,"esp"));
+	&xor	($b_,&DWP(4*1,$b));
+	&xor	($c, &DWP(4*2,$b));
+	&xor	($c_,&DWP(4*3,$b));
+	&xor	($d, &DWP(4*5,$b));
+	&xor	($d_,&DWP(4*6,$b));
+	&mov	(&DWP(4*1,$a),$b_);
+	&mov	($b_,&DWP(4*4,"esp"));
+	&mov	(&DWP(4*2,$a),$c);
+	&mov	(&DWP(4*3,$a),$c_);
+	&mov	(&DWP(4*4,$a),$b_);
+	&mov	(&DWP(4*5,$a),$d);
+	&mov	(&DWP(4*6,$a),$d_);
+
+	&mov	($c,&DWP(4*7,"esp"));
+	&mov	($d,&DWP(4*8,"esp"));
+	&mov	($d_,&DWP(4*9,"esp"));
+	&add	($c,&DWP(64+4*7,"esp"));
+	&mov	($b_, &DWP(4*10,"esp"));
+	&xor	($c,&DWP(4*7,$b));
+	&mov	($c_,&DWP(4*11,"esp"));
+	&mov	(&DWP(4*7,$a),$c);
+	&mov	(&DWP(4*8,$a),$d);
+	&mov	(&DWP(4*9,$a),$d_);
+
+	&add	($b_, &DWP(64+4*10,"esp"));
+	&add	($c_,&DWP(64+4*11,"esp"));
+	&xor	($b_, &DWP(4*10,$b));
+	&xor	($c_,&DWP(4*11,$b));
+	&mov	(&DWP(4*10,$a),$b_);
+	&mov	(&DWP(4*11,$a),$c_);
+
+	&mov	($c,&DWP(4*12,"esp"));
+	&mov	($c_,&DWP(4*14,"esp"));
+	&mov	($d, &DWP(4*13,"esp"));
+	&mov	($d_,&DWP(4*15,"esp"));
+	&add	($d, &DWP(64+4*13,"esp"));
+	&add	($d_,&DWP(64+4*15,"esp"));
+	&xor	($d, &DWP(4*13,$b));
+	&xor	($d_,&DWP(4*15,$b));
+	&lea	($b,&DWP(4*16,$b));
+	&mov	(&DWP(4*12,$a),$c);
+	&mov	($c,&wparam(2));		# len
+	&mov	(&DWP(4*13,$a),$d);
+	&mov	(&DWP(4*14,$a),$c_);
+	&mov	(&DWP(4*15,$a),$d_);
+	&lea	($a,&DWP(4*16,$a));
+	&sub	($c,64);
+	&jnz	(&label("outer_loop"));
+
+	&jmp	(&label("done"));
+
+&set_label("tail");
+	&add	($d, &DWP(64+4*12,"esp"));
+	&add	($d_,&DWP(64+4*14,"esp"));
+	&mov	(&DWP(4*0,"esp"),$a);
+	&mov	(&DWP(4*4,"esp"),$b_);
+	&mov	(&DWP(4*8,"esp"),$c);
+	&mov	(&DWP(4*9,"esp"),$c_);
+	&mov	(&DWP(4*12,"esp"),$d);
+	&mov	(&DWP(4*14,"esp"),$d_);
+
+	&mov	($b_,&DWP(4*1,"esp"));
+	&mov	($c, &DWP(4*2,"esp"));
+	&mov	($c_,&DWP(4*3,"esp"));
+	&mov	($d, &DWP(4*5,"esp"));
+	&mov	($d_,&DWP(4*6,"esp"));
+	&add	($b_,0x3320646e);		# accumulate key material
+	&add	($c, 0x79622d32);
+	&add	($c_,0x6b206574);
+	&add	($d, &DWP(64+4*5,"esp"));
+	&add	($d_,&DWP(64+4*6,"esp"));
+	&mov	(&DWP(4*1,"esp"),$b_);
+	&mov	(&DWP(4*2,"esp"),$c);
+	&mov	(&DWP(4*3,"esp"),$c_);
+	&mov	(&DWP(4*5,"esp"),$d);
+	&mov	(&DWP(4*6,"esp"),$d_);
+
+	&mov	($b_,&DWP(4*7,"esp"));
+	&mov	($c, &DWP(4*10,"esp"));
+	&mov	($c_,&DWP(4*11,"esp"));
+	&mov	($d, &DWP(4*13,"esp"));
+	&mov	($d_,&DWP(4*15,"esp"));
+	&add	($b_,&DWP(64+4*7,"esp"));
+	&add	($c, &DWP(64+4*10,"esp"));
+	&add	($c_,&DWP(64+4*11,"esp"));
+	&add	($d, &DWP(64+4*13,"esp"));
+	&add	($d_,&DWP(64+4*15,"esp"));
+	&mov	(&DWP(4*7,"esp"),$b_);
+	&mov	($b_,&wparam(1));		# load input
+	&mov	(&DWP(4*10,"esp"),$c);
+	&mov	($c,&wparam(0));		# load output
+	&mov	(&DWP(4*11,"esp"),$c_);
+	&xor	($c_,$c_);
+	&mov	(&DWP(4*13,"esp"),$d);
+	&mov	(&DWP(4*15,"esp"),$d_);
+
+	&xor	("eax","eax");
+	&xor	("edx","edx");
+&set_label("tail_loop");
+	&movb	("al",&BP(0,$c_,$b_));
+	&movb	("dl",&BP(0,"esp",$c_));
+	&lea	($c_,&DWP(1,$c_));
+	&xor	("al","dl");
+	&mov	(&BP(-1,$c,$c_),"al");
+	&dec	($b);
+	&jnz	(&label("tail_loop"));
+
+&set_label("done");
+	&stack_pop(33);
+&set_label("no_data");
+&function_end("ChaCha20_ctr32");
+
+if ($xmm) {
+my ($xa,$xa_,$xb,$xb_,$xc,$xc_,$xd,$xd_)=map("xmm$_",(0..7));
+my ($out,$inp,$len)=("edi","esi","ecx");
+
+sub QUARTERROUND_SSSE3 {
+my ($ai,$bi,$ci,$di,$i)=@_;
+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di));	# next
+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di));	# previous
+
+	#       a   b   c   d
+	#
+	#       0   4   8  12 < even round
+	#       1   5   9  13
+	#       2   6  10  14
+	#       3   7  11  15
+	#       0   5  10  15 < odd round
+	#       1   6  11  12
+	#       2   7   8  13
+	#       3   4   9  14
+
+	if ($i==0) {
+            my $j=4;
+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
+	} elsif ($i==3) {
+            my $j=0;
+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
+	} elsif ($i==4) {
+            my $j=4;
+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
+	} elsif ($i==7) {
+            my $j=0;
+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
+	}
+
+	#&paddd	($xa,$xb);			# see elsewhere
+	#&pxor	($xd,$xa);			# see elsewhere
+	 &movdqa(&QWP(16*$cp-128,"ebx"),$xc_)	if ($ai>0 && $ai<3);
+	&pshufb	($xd,&QWP(0,"eax"));		# rot16
+	 &movdqa(&QWP(16*$bp-128,"ebx"),$xb_)	if ($i!=0);
+	&paddd	($xc,$xd);
+	 &movdqa($xc_,&QWP(16*$cn-128,"ebx"))	if ($ai>0 && $ai<3);
+	&pxor	($xb,$xc);
+	 &movdqa($xb_,&QWP(16*$bn-128,"ebx"))	if ($i<7);
+	&movdqa	($xa_,$xb);			# borrow as temporary
+	&pslld	($xb,12);
+	&psrld	($xa_,20);
+	&por	($xb,$xa_);
+	 &movdqa($xa_,&QWP(16*$an-128,"ebx"));
+	&paddd	($xa,$xb);
+	 &movdqa($xd_,&QWP(16*$dn-128,"ebx"))	if ($di!=$dn);
+	&pxor	($xd,$xa);
+	&movdqa	(&QWP(16*$ai-128,"ebx"),$xa);
+	&pshufb	($xd,&QWP(16,"eax"));		# rot8
+	&paddd	($xc,$xd);
+	&movdqa	(&QWP(16*$di-128,"ebx"),$xd)	if ($di!=$dn);
+	&movdqa	($xd_,$xd)			if ($di==$dn);
+	&pxor	($xb,$xc);
+	 &paddd	($xa_,$xb_)			if ($i<7);	# elsewhere
+	&movdqa	($xa,$xb);			# borrow as temporary
+	&pslld	($xb,7);
+	&psrld	($xa,25);
+	 &pxor	($xd_,$xa_)			if ($i<7);	# elsewhere
+	&por	($xb,$xa);
+
+	($xa,$xa_)=($xa_,$xa);
+	($xb,$xb_)=($xb_,$xb);
+	($xc,$xc_)=($xc_,$xc);
+	($xd,$xd_)=($xd_,$xd);
+}
+
+&function_begin("ChaCha20_ssse3");
+&set_label("ssse3_shortcut");
+	&mov		($out,&wparam(0));
+	&mov		($inp,&wparam(1));
+	&mov		($len,&wparam(2));
+	&mov		("edx",&wparam(3));		# key
+	&mov		("ebx",&wparam(4));		# counter and nonce
+
+	&mov		("ebp","esp");
+	&stack_push	(131);
+	&and		("esp",-64);
+	&mov		(&DWP(512,"esp"),"ebp");
+
+	&lea		("eax",&DWP(&label("ssse3_data")."-".
+				    &label("pic_point"),"eax"));
+	&movdqu		("xmm3",&QWP(0,"ebx"));		# counter and nonce
+
+	&cmp		($len,64*4);
+	&jb		(&label("1x"));
+
+	&mov		(&DWP(512+4,"esp"),"edx");	# offload pointers
+	&mov		(&DWP(512+8,"esp"),"ebx");
+	&sub		($len,64*4);			# bias len
+	&lea		("ebp",&DWP(256+128,"esp"));	# size optimization
+
+	&movdqu		("xmm7",&QWP(0,"edx"));		# key
+	&pshufd		("xmm0","xmm3",0x00);
+	&pshufd		("xmm1","xmm3",0x55);
+	&pshufd		("xmm2","xmm3",0xaa);
+	&pshufd		("xmm3","xmm3",0xff);
+	 &paddd		("xmm0",&QWP(16*3,"eax"));	# fix counters
+	&pshufd		("xmm4","xmm7",0x00);
+	&pshufd		("xmm5","xmm7",0x55);
+	 &psubd		("xmm0",&QWP(16*4,"eax"));
+	&pshufd		("xmm6","xmm7",0xaa);
+	&pshufd		("xmm7","xmm7",0xff);
+	&movdqa		(&QWP(16*12-128,"ebp"),"xmm0");
+	&movdqa		(&QWP(16*13-128,"ebp"),"xmm1");
+	&movdqa		(&QWP(16*14-128,"ebp"),"xmm2");
+	&movdqa		(&QWP(16*15-128,"ebp"),"xmm3");
+	 &movdqu	("xmm3",&QWP(16,"edx"));	# key
+	&movdqa		(&QWP(16*4-128,"ebp"),"xmm4");
+	&movdqa		(&QWP(16*5-128,"ebp"),"xmm5");
+	&movdqa		(&QWP(16*6-128,"ebp"),"xmm6");
+	&movdqa		(&QWP(16*7-128,"ebp"),"xmm7");
+	 &movdqa	("xmm7",&QWP(16*2,"eax"));	# sigma
+	 &lea		("ebx",&DWP(128,"esp"));	# size optimization
+
+	&pshufd		("xmm0","xmm3",0x00);
+	&pshufd		("xmm1","xmm3",0x55);
+	&pshufd		("xmm2","xmm3",0xaa);
+	&pshufd		("xmm3","xmm3",0xff);
+	&pshufd		("xmm4","xmm7",0x00);
+	&pshufd		("xmm5","xmm7",0x55);
+	&pshufd		("xmm6","xmm7",0xaa);
+	&pshufd		("xmm7","xmm7",0xff);
+	&movdqa		(&QWP(16*8-128,"ebp"),"xmm0");
+	&movdqa		(&QWP(16*9-128,"ebp"),"xmm1");
+	&movdqa		(&QWP(16*10-128,"ebp"),"xmm2");
+	&movdqa		(&QWP(16*11-128,"ebp"),"xmm3");
+	&movdqa		(&QWP(16*0-128,"ebp"),"xmm4");
+	&movdqa		(&QWP(16*1-128,"ebp"),"xmm5");
+	&movdqa		(&QWP(16*2-128,"ebp"),"xmm6");
+	&movdqa		(&QWP(16*3-128,"ebp"),"xmm7");
+
+	&lea		($inp,&DWP(128,$inp));		# size optimization
+	&lea		($out,&DWP(128,$out));		# size optimization
+	&jmp		(&label("outer_loop"));
+
+&set_label("outer_loop",16);
+	#&movdqa	("xmm0",&QWP(16*0-128,"ebp"));	# copy key material
+	&movdqa		("xmm1",&QWP(16*1-128,"ebp"));
+	&movdqa		("xmm2",&QWP(16*2-128,"ebp"));
+	&movdqa		("xmm3",&QWP(16*3-128,"ebp"));
+	#&movdqa	("xmm4",&QWP(16*4-128,"ebp"));
+	&movdqa		("xmm5",&QWP(16*5-128,"ebp"));
+	&movdqa		("xmm6",&QWP(16*6-128,"ebp"));
+	&movdqa		("xmm7",&QWP(16*7-128,"ebp"));
+	#&movdqa	(&QWP(16*0-128,"ebx"),"xmm0");
+	&movdqa		(&QWP(16*1-128,"ebx"),"xmm1");
+	&movdqa		(&QWP(16*2-128,"ebx"),"xmm2");
+	&movdqa		(&QWP(16*3-128,"ebx"),"xmm3");
+	#&movdqa	(&QWP(16*4-128,"ebx"),"xmm4");
+	&movdqa		(&QWP(16*5-128,"ebx"),"xmm5");
+	&movdqa		(&QWP(16*6-128,"ebx"),"xmm6");
+	&movdqa		(&QWP(16*7-128,"ebx"),"xmm7");
+	#&movdqa	("xmm0",&QWP(16*8-128,"ebp"));
+	#&movdqa	("xmm1",&QWP(16*9-128,"ebp"));
+	&movdqa		("xmm2",&QWP(16*10-128,"ebp"));
+	&movdqa		("xmm3",&QWP(16*11-128,"ebp"));
+	&movdqa		("xmm4",&QWP(16*12-128,"ebp"));
+	&movdqa		("xmm5",&QWP(16*13-128,"ebp"));
+	&movdqa		("xmm6",&QWP(16*14-128,"ebp"));
+	&movdqa		("xmm7",&QWP(16*15-128,"ebp"));
+	&paddd		("xmm4",&QWP(16*4,"eax"));	# counter value
+	#&movdqa	(&QWP(16*8-128,"ebx"),"xmm0");
+	#&movdqa	(&QWP(16*9-128,"ebx"),"xmm1");
+	&movdqa		(&QWP(16*10-128,"ebx"),"xmm2");
+	&movdqa		(&QWP(16*11-128,"ebx"),"xmm3");
+	&movdqa		(&QWP(16*12-128,"ebx"),"xmm4");
+	&movdqa		(&QWP(16*13-128,"ebx"),"xmm5");
+	&movdqa		(&QWP(16*14-128,"ebx"),"xmm6");
+	&movdqa		(&QWP(16*15-128,"ebx"),"xmm7");
+	&movdqa		(&QWP(16*12-128,"ebp"),"xmm4");	# save counter value
+
+	&movdqa		($xa, &QWP(16*0-128,"ebp"));
+	&movdqa		($xd, "xmm4");
+	&movdqa		($xb_,&QWP(16*4-128,"ebp"));
+	&movdqa		($xc, &QWP(16*8-128,"ebp"));
+	&movdqa		($xc_,&QWP(16*9-128,"ebp"));
+
+	&mov		("edx",10);			# loop counter
+	&nop		();
+
+&set_label("loop",16);
+	&paddd		($xa,$xb_);			# elsewhere
+	&movdqa		($xb,$xb_);
+	&pxor		($xd,$xa);			# elsewhere
+	&QUARTERROUND_SSSE3(0, 4, 8, 12, 0);
+	&QUARTERROUND_SSSE3(1, 5, 9, 13, 1);
+	&QUARTERROUND_SSSE3(2, 6,10, 14, 2);
+	&QUARTERROUND_SSSE3(3, 7,11, 15, 3);
+	&QUARTERROUND_SSSE3(0, 5,10, 15, 4);
+	&QUARTERROUND_SSSE3(1, 6,11, 12, 5);
+	&QUARTERROUND_SSSE3(2, 7, 8, 13, 6);
+	&QUARTERROUND_SSSE3(3, 4, 9, 14, 7);
+	&dec		("edx");
+	&jnz		(&label("loop"));
+
+	&movdqa		(&QWP(16*4-128,"ebx"),$xb_);
+	&movdqa		(&QWP(16*8-128,"ebx"),$xc);
+	&movdqa		(&QWP(16*9-128,"ebx"),$xc_);
+	&movdqa		(&QWP(16*12-128,"ebx"),$xd);
+	&movdqa		(&QWP(16*14-128,"ebx"),$xd_);
+
+    my ($xa0,$xa1,$xa2,$xa3,$xt0,$xt1,$xt2,$xt3)=map("xmm$_",(0..7));
+
+    for($i=0;$i<256;$i+=64) {
+	#&movdqa	($xa0,&QWP($i+16*0-128,"ebx"));	# it's there
+	&movdqa		($xa1,&QWP($i+16*1-128,"ebx"));
+	&movdqa		($xa2,&QWP($i+16*2-128,"ebx"));
+	&movdqa		($xa3,&QWP($i+16*3-128,"ebx"));
+
+	&paddd		($xa0,&QWP($i+16*0-128,"ebp"));	# accumulate key material
+	&paddd		($xa1,&QWP($i+16*1-128,"ebp"));
+	&paddd		($xa2,&QWP($i+16*2-128,"ebp"));
+	&paddd		($xa3,&QWP($i+16*3-128,"ebp"));
+
+	&movdqa		($xt2,$xa0);		# "de-interlace" data
+	&punpckldq	($xa0,$xa1);
+	&movdqa		($xt3,$xa2);
+	&punpckldq	($xa2,$xa3);
+	&punpckhdq	($xt2,$xa1);
+	&punpckhdq	($xt3,$xa3);
+	&movdqa		($xa1,$xa0);
+	&punpcklqdq	($xa0,$xa2);		# "a0"
+	&movdqa		($xa3,$xt2);
+	&punpcklqdq	($xt2,$xt3);		# "a2"
+	&punpckhqdq	($xa1,$xa2);		# "a1"
+	&punpckhqdq	($xa3,$xt3);		# "a3"
+
+	#($xa2,$xt2)=($xt2,$xa2);
+
+	&movdqa		(&QWP($i+16*0-128,"ebx"),$xa0);
+	&movdqa		($xa0,&QWP($i+16*4-128,"ebx"))	if ($i<192);
+	&movdqa		(&QWP($i+16*1-128,"ebx"),$xa1);
+	&movdqa		(&QWP($i+16*2-128,"ebx"),$xt2);
+	&movdqa		(&QWP($i+16*3-128,"ebx"),$xa3);
+    }
+    for($i=0;$i<256;$i+=64) {
+	my $j = 16*($i/64);
+	&movdqu		($xa0,&QWP($i+16*0-128,$inp));	# load input
+	&movdqu		($xa1,&QWP($i+16*1-128,$inp));
+	&movdqu		($xa2,&QWP($i+16*2-128,$inp));
+	&movdqu		($xa3,&QWP($i+16*3-128,$inp));
+	&pxor		($xa0,&QWP($j+64*0-128,"ebx"));
+	&pxor		($xa1,&QWP($j+64*1-128,"ebx"));
+	&pxor		($xa2,&QWP($j+64*2-128,"ebx"));
+	&pxor		($xa3,&QWP($j+64*3-128,"ebx"));
+	&movdqu		(&QWP($i+16*0-128,$out),$xa0);	# write output
+	&movdqu		(&QWP($i+16*1-128,$out),$xa1);
+	&movdqu		(&QWP($i+16*2-128,$out),$xa2);
+	&movdqu		(&QWP($i+16*3-128,$out),$xa3);
+    }
+	&lea		($inp,&DWP(256,$inp));
+	&lea		($out,&DWP(256,$out));
+	&sub		($len,64*4);
+	&jnc		(&label("outer_loop"));
+
+	&add		($len,64*4);
+	&jz		(&label("done"));
+
+	&mov		("ebx",&DWP(512+8,"esp"));	# restore pointers
+	&lea		($inp,&DWP(-128,$inp));
+	&mov		("edx",&DWP(512+4,"esp"));
+	&lea		($out,&DWP(-128,$out));
+
+	&movd		("xmm2",&DWP(16*12-128,"ebp"));	# counter value
+	&movdqu		("xmm3",&QWP(0,"ebx"));
+	&paddd		("xmm2",&QWP(16*6,"eax"));	# +four
+	&pand		("xmm3",&QWP(16*7,"eax"));
+	&por		("xmm3","xmm2");		# counter value
+{
+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));
+
+sub SSSE3ROUND {	# critical path is 20 "SIMD ticks" per round
+	&paddd		($a,$b);
+	&pxor		($d,$a);
+	&pshufb		($d,$rot16);
+
+	&paddd		($c,$d);
+	&pxor		($b,$c);
+	&movdqa		($t,$b);
+	&psrld		($b,20);
+	&pslld		($t,12);
+	&por		($b,$t);
+
+	&paddd		($a,$b);
+	&pxor		($d,$a);
+	&pshufb		($d,$rot24);
+
+	&paddd		($c,$d);
+	&pxor		($b,$c);
+	&movdqa		($t,$b);
+	&psrld		($b,25);
+	&pslld		($t,7);
+	&por		($b,$t);
+}
+
+&set_label("1x");
+	&movdqa		($a,&QWP(16*2,"eax"));		# sigma
+	&movdqu		($b,&QWP(0,"edx"));
+	&movdqu		($c,&QWP(16,"edx"));
+	#&movdqu	($d,&QWP(0,"ebx"));		# already loaded
+	&movdqa		($rot16,&QWP(0,"eax"));
+	&movdqa		($rot24,&QWP(16,"eax"));
+	&mov		(&DWP(16*3,"esp"),"ebp");
+
+	&movdqa		(&QWP(16*0,"esp"),$a);
+	&movdqa		(&QWP(16*1,"esp"),$b);
+	&movdqa		(&QWP(16*2,"esp"),$c);
+	&movdqa		(&QWP(16*3,"esp"),$d);
+	&mov		("edx",10);
+	&jmp		(&label("loop1x"));
+
+&set_label("outer1x",16);
+	&movdqa		($d,&QWP(16*5,"eax"));		# one
+	&movdqa		($a,&QWP(16*0,"esp"));
+	&movdqa		($b,&QWP(16*1,"esp"));
+	&movdqa		($c,&QWP(16*2,"esp"));
+	&paddd		($d,&QWP(16*3,"esp"));
+	&mov		("edx",10);
+	&movdqa		(&QWP(16*3,"esp"),$d);
+	&jmp		(&label("loop1x"));
+
+&set_label("loop1x",16);
+	&SSSE3ROUND();
+	&pshufd	($c,$c,0b01001110);
+	&pshufd	($b,$b,0b00111001);
+	&pshufd	($d,$d,0b10010011);
+	&nop	();
+
+	&SSSE3ROUND();
+	&pshufd	($c,$c,0b01001110);
+	&pshufd	($b,$b,0b10010011);
+	&pshufd	($d,$d,0b00111001);
+
+	&dec		("edx");
+	&jnz		(&label("loop1x"));
+
+	&paddd		($a,&QWP(16*0,"esp"));
+	&paddd		($b,&QWP(16*1,"esp"));
+	&paddd		($c,&QWP(16*2,"esp"));
+	&paddd		($d,&QWP(16*3,"esp"));
+
+	&cmp		($len,64);
+	&jb		(&label("tail"));
+
+	&movdqu		($t,&QWP(16*0,$inp));
+	&movdqu		($t1,&QWP(16*1,$inp));
+	&pxor		($a,$t);		# xor with input
+	&movdqu		($t,&QWP(16*2,$inp));
+	&pxor		($b,$t1);
+	&movdqu		($t1,&QWP(16*3,$inp));
+	&pxor		($c,$t);
+	&pxor		($d,$t1);
+	&lea		($inp,&DWP(16*4,$inp));	# inp+=64
+
+	&movdqu		(&QWP(16*0,$out),$a);	# write output
+	&movdqu		(&QWP(16*1,$out),$b);
+	&movdqu		(&QWP(16*2,$out),$c);
+	&movdqu		(&QWP(16*3,$out),$d);
+	&lea		($out,&DWP(16*4,$out));	# inp+=64
+
+	&sub		($len,64);
+	&jnz		(&label("outer1x"));
+
+	&jmp		(&label("done"));
+
+&set_label("tail");
+	&movdqa		(&QWP(16*0,"esp"),$a);
+	&movdqa		(&QWP(16*1,"esp"),$b);
+	&movdqa		(&QWP(16*2,"esp"),$c);
+	&movdqa		(&QWP(16*3,"esp"),$d);
+
+	&xor		("eax","eax");
+	&xor		("edx","edx");
+	&xor		("ebp","ebp");
+
+&set_label("tail_loop");
+	&movb		("al",&BP(0,"esp","ebp"));
+	&movb		("dl",&BP(0,$inp,"ebp"));
+	&lea		("ebp",&DWP(1,"ebp"));
+	&xor		("al","dl");
+	&movb		(&BP(-1,$out,"ebp"),"al");
+	&dec		($len);
+	&jnz		(&label("tail_loop"));
+}
+&set_label("done");
+	&mov		("esp",&DWP(512,"esp"));
+&function_end("ChaCha20_ssse3");
+
+&align	(64);
+&set_label("ssse3_data");
+&data_byte(0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd);
+&data_byte(0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe);
+&data_word(0x61707865,0x3320646e,0x79622d32,0x6b206574);
+&data_word(0,1,2,3);
+&data_word(4,4,4,4);
+&data_word(1,0,0,0);
+&data_word(4,0,0,0);
+&data_word(0,-1,-1,-1);
+&align	(64);
+}
+&asciz	("ChaCha20 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/src/crypto/chacha/asm/chacha-x86_64.pl b/src/crypto/chacha/asm/chacha-x86_64.pl
new file mode 100755
index 0000000..55b726d
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-x86_64.pl
@@ -0,0 +1,1767 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# November 2014
+#
+# ChaCha20 for x86_64.
+#
+# Performance in cycles per byte out of large buffer.
+#
+#		IALU/gcc 4.8(i)	1xSSSE3/SSE2	4xSSSE3	    8xAVX2
+#
+# P4		9.48/+99%	-/22.7(ii)	-
+# Core2		7.83/+55%	7.90/8.08	4.35
+# Westmere	7.19/+50%	5.60/6.70	3.00
+# Sandy Bridge	8.31/+42%	5.45/6.76	2.72
+# Ivy Bridge	6.71/+46%	5.40/6.49	2.41
+# Haswell	5.92/+43%	5.20/6.45	2.42	    1.23
+# Silvermont	12.0/+33%	7.75/7.40	7.03(iii)
+# Sledgehammer	7.28/+52%	-/14.2(ii)	-
+# Bulldozer	9.66/+28%	9.85/11.1	3.06(iv)
+# VIA Nano	10.5/+46%	6.72/8.60	6.05
+#
+# (i)	compared to older gcc 3.x one can observe >2x improvement on
+#	most platforms;
+# (ii)	as it can be seen, SSE2 performance is too low on legacy
+#	processors; NxSSE2 results are naturally better, but not
+#	impressively better than IALU ones, which is why you won't
+#	find SSE2 code below;
+# (iii)	this is not optimal result for Atom because of MSROM
+#	limitations, SSE2 can do better, but gain is considered too
+#	low to justify the [maintenance] effort;
+# (iv)	Bulldozer actually executes 4xXOP code path that delivers 2.20;
+#
+# Modified from upstream OpenSSL to remove the XOP code.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+$avx = 2;
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# input parameter block
+($out,$inp,$len,$key,$counter)=("%rdi","%rsi","%rdx","%rcx","%r8");
+
+$code.=<<___;
+.text
+
+.extern OPENSSL_ia32cap_P
+
+.align	64
+.Lzero:
+.long	0,0,0,0
+.Lone:
+.long	1,0,0,0
+.Linc:
+.long	0,1,2,3
+.Lfour:
+.long	4,4,4,4
+.Lincy:
+.long	0,2,4,6,1,3,5,7
+.Leight:
+.long	8,8,8,8,8,8,8,8
+.Lrot16:
+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+.Lrot24:
+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+.Lsigma:
+.asciz	"expand 32-byte k"
+.asciz	"ChaCha20 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+sub AUTOLOAD()          # thunk [simplified] 32-bit style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
+  my $arg = pop;
+    $arg = "\$$arg" if ($arg*1 eq $arg);
+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
+}
+
+@x=("%eax","%ebx","%ecx","%edx",map("%r${_}d",(8..11)),
+    "%nox","%nox","%nox","%nox",map("%r${_}d",(12..15)));
+@t=("%esi","%edi");
+
+sub ROUND {			# critical path is 24 cycles per round
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_)=map("\"$_\"",@t);
+my @x=map("\"$_\"",@x);
+
+	# Consider order in which variables are addressed by their
+	# index:
+	#
+	#	a   b   c   d
+	#
+	#	0   4   8  12 < even round
+	#	1   5   9  13
+	#	2   6  10  14
+	#	3   7  11  15
+	#	0   5  10  15 < odd round
+	#	1   6  11  12
+	#	2   7   8  13
+	#	3   4   9  14
+	#
+	# 'a', 'b' and 'd's are permanently allocated in registers,
+	# @x[0..7,12..15], while 'c's are maintained in memory. If
+	# you observe 'c' column, you'll notice that pair of 'c's is
+	# invariant between rounds. This means that we have to reload
+	# them once per round, in the middle. This is why you'll see
+	# bunch of 'c' stores and loads in the middle, but none in
+	# the beginning or end.
+
+	# Normally instructions would be interleaved to favour in-order
+	# execution. Generally out-of-order cores manage it gracefully,
+	# but not this time for some reason. As in-order execution
+	# cores are dying breed, old Atom is the only one around,
+	# instructions are left uninterleaved. Besides, Atom is better
+	# off executing 1xSSSE3 code anyway...
+
+	(
+	"&add	(@x[$a0],@x[$b0])",	# Q1
+	"&xor	(@x[$d0],@x[$a0])",
+	"&rol	(@x[$d0],16)",
+	 "&add	(@x[$a1],@x[$b1])",	# Q2
+	 "&xor	(@x[$d1],@x[$a1])",
+	 "&rol	(@x[$d1],16)",
+
+	"&add	($xc,@x[$d0])",
+	"&xor	(@x[$b0],$xc)",
+	"&rol	(@x[$b0],12)",
+	 "&add	($xc_,@x[$d1])",
+	 "&xor	(@x[$b1],$xc_)",
+	 "&rol	(@x[$b1],12)",
+
+	"&add	(@x[$a0],@x[$b0])",
+	"&xor	(@x[$d0],@x[$a0])",
+	"&rol	(@x[$d0],8)",
+	 "&add	(@x[$a1],@x[$b1])",
+	 "&xor	(@x[$d1],@x[$a1])",
+	 "&rol	(@x[$d1],8)",
+
+	"&add	($xc,@x[$d0])",
+	"&xor	(@x[$b0],$xc)",
+	"&rol	(@x[$b0],7)",
+	 "&add	($xc_,@x[$d1])",
+	 "&xor	(@x[$b1],$xc_)",
+	 "&rol	(@x[$b1],7)",
+
+	"&mov	(\"4*$c0(%rsp)\",$xc)",	# reload pair of 'c's
+	 "&mov	(\"4*$c1(%rsp)\",$xc_)",
+	"&mov	($xc,\"4*$c2(%rsp)\")",
+	 "&mov	($xc_,\"4*$c3(%rsp)\")",
+
+	"&add	(@x[$a2],@x[$b2])",	# Q3
+	"&xor	(@x[$d2],@x[$a2])",
+	"&rol	(@x[$d2],16)",
+	 "&add	(@x[$a3],@x[$b3])",	# Q4
+	 "&xor	(@x[$d3],@x[$a3])",
+	 "&rol	(@x[$d3],16)",
+
+	"&add	($xc,@x[$d2])",
+	"&xor	(@x[$b2],$xc)",
+	"&rol	(@x[$b2],12)",
+	 "&add	($xc_,@x[$d3])",
+	 "&xor	(@x[$b3],$xc_)",
+	 "&rol	(@x[$b3],12)",
+
+	"&add	(@x[$a2],@x[$b2])",
+	"&xor	(@x[$d2],@x[$a2])",
+	"&rol	(@x[$d2],8)",
+	 "&add	(@x[$a3],@x[$b3])",
+	 "&xor	(@x[$d3],@x[$a3])",
+	 "&rol	(@x[$d3],8)",
+
+	"&add	($xc,@x[$d2])",
+	"&xor	(@x[$b2],$xc)",
+	"&rol	(@x[$b2],7)",
+	 "&add	($xc_,@x[$d3])",
+	 "&xor	(@x[$b3],$xc_)",
+	 "&rol	(@x[$b3],7)"
+	);
+}
+
+########################################################################
+# Generic code path that handles all lengths on pre-SSSE3 processors.
+$code.=<<___;
+.globl	ChaCha20_ctr32
+.type	ChaCha20_ctr32,\@function,5
+.align	64
+ChaCha20_ctr32:
+	cmp	\$0,$len
+	je	.Lno_data
+	mov	OPENSSL_ia32cap_P+4(%rip),%r10
+	test	\$`1<<(41-32)`,%r10d
+	jnz	.LChaCha20_ssse3
+
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	sub	\$64+24,%rsp
+
+	#movdqa	.Lsigma(%rip),%xmm0
+	movdqu	($key),%xmm1
+	movdqu	16($key),%xmm2
+	movdqu	($counter),%xmm3
+	movdqa	.Lone(%rip),%xmm4
+
+	#movdqa	%xmm0,4*0(%rsp)		# key[0]
+	movdqa	%xmm1,4*4(%rsp)		# key[1]
+	movdqa	%xmm2,4*8(%rsp)		# key[2]
+	movdqa	%xmm3,4*12(%rsp)	# key[3]
+	mov	$len,%rbp		# reassign $len
+	jmp	.Loop_outer
+
+.align	32
+.Loop_outer:
+	mov	\$0x61707865,@x[0]      # 'expa'
+	mov	\$0x3320646e,@x[1]      # 'nd 3'
+	mov	\$0x79622d32,@x[2]      # '2-by'
+	mov	\$0x6b206574,@x[3]      # 'te k'
+	mov	4*4(%rsp),@x[4]
+	mov	4*5(%rsp),@x[5]
+	mov	4*6(%rsp),@x[6]
+	mov	4*7(%rsp),@x[7]
+	movd	%xmm3,@x[12]
+	mov	4*13(%rsp),@x[13]
+	mov	4*14(%rsp),@x[14]
+	mov	4*15(%rsp),@x[15]
+
+	mov	%rbp,64+0(%rsp)		# save len
+	mov	\$10,%ebp
+	mov	$inp,64+8(%rsp)		# save inp
+	movq	%xmm2,%rsi		# "@x[8]"
+	mov	$out,64+16(%rsp)	# save out
+	mov	%rsi,%rdi
+	shr	\$32,%rdi		# "@x[9]"
+	jmp	.Loop
+
+.align	32
+.Loop:
+___
+	foreach (&ROUND (0, 4, 8,12)) { eval; }
+	foreach (&ROUND	(0, 5,10,15)) { eval; }
+	&dec	("%ebp");
+	&jnz	(".Loop");
+
+$code.=<<___;
+	mov	@t[1],4*9(%rsp)		# modulo-scheduled
+	mov	@t[0],4*8(%rsp)
+	mov	64(%rsp),%rbp		# load len
+	movdqa	%xmm2,%xmm1
+	mov	64+8(%rsp),$inp		# load inp
+	paddd	%xmm4,%xmm3		# increment counter
+	mov	64+16(%rsp),$out	# load out
+
+	add	\$0x61707865,@x[0]      # 'expa'
+	add	\$0x3320646e,@x[1]      # 'nd 3'
+	add	\$0x79622d32,@x[2]      # '2-by'
+	add	\$0x6b206574,@x[3]      # 'te k'
+	add	4*4(%rsp),@x[4]
+	add	4*5(%rsp),@x[5]
+	add	4*6(%rsp),@x[6]
+	add	4*7(%rsp),@x[7]
+	add	4*12(%rsp),@x[12]
+	add	4*13(%rsp),@x[13]
+	add	4*14(%rsp),@x[14]
+	add	4*15(%rsp),@x[15]
+	paddd	4*8(%rsp),%xmm1
+
+	cmp	\$64,%rbp
+	jb	.Ltail
+
+	xor	4*0($inp),@x[0]		# xor with input
+	xor	4*1($inp),@x[1]
+	xor	4*2($inp),@x[2]
+	xor	4*3($inp),@x[3]
+	xor	4*4($inp),@x[4]
+	xor	4*5($inp),@x[5]
+	xor	4*6($inp),@x[6]
+	xor	4*7($inp),@x[7]
+	movdqu	4*8($inp),%xmm0
+	xor	4*12($inp),@x[12]
+	xor	4*13($inp),@x[13]
+	xor	4*14($inp),@x[14]
+	xor	4*15($inp),@x[15]
+	lea	4*16($inp),$inp		# inp+=64
+	pxor	%xmm1,%xmm0
+
+	movdqa	%xmm2,4*8(%rsp)
+	movd	%xmm3,4*12(%rsp)
+
+	mov	@x[0],4*0($out)		# write output
+	mov	@x[1],4*1($out)
+	mov	@x[2],4*2($out)
+	mov	@x[3],4*3($out)
+	mov	@x[4],4*4($out)
+	mov	@x[5],4*5($out)
+	mov	@x[6],4*6($out)
+	mov	@x[7],4*7($out)
+	movdqu	%xmm0,4*8($out)
+	mov	@x[12],4*12($out)
+	mov	@x[13],4*13($out)
+	mov	@x[14],4*14($out)
+	mov	@x[15],4*15($out)
+	lea	4*16($out),$out		# out+=64
+
+	sub	\$64,%rbp
+	jnz	.Loop_outer
+
+	jmp	.Ldone
+
+.align	16
+.Ltail:
+	mov	@x[0],4*0(%rsp)
+	mov	@x[1],4*1(%rsp)
+	xor	%rbx,%rbx
+	mov	@x[2],4*2(%rsp)
+	mov	@x[3],4*3(%rsp)
+	mov	@x[4],4*4(%rsp)
+	mov	@x[5],4*5(%rsp)
+	mov	@x[6],4*6(%rsp)
+	mov	@x[7],4*7(%rsp)
+	movdqa	%xmm1,4*8(%rsp)
+	mov	@x[12],4*12(%rsp)
+	mov	@x[13],4*13(%rsp)
+	mov	@x[14],4*14(%rsp)
+	mov	@x[15],4*15(%rsp)
+
+.Loop_tail:
+	movzb	($inp,%rbx),%eax
+	movzb	(%rsp,%rbx),%edx
+	lea	1(%rbx),%rbx
+	xor	%edx,%eax
+	mov	%al,-1($out,%rbx)
+	dec	%rbp
+	jnz	.Loop_tail
+
+.Ldone:
+	add	\$64+24,%rsp
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+.Lno_data:
+	ret
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+########################################################################
+# SSSE3 code path that handles shorter lengths
+{
+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("%xmm$_",(0..7));
+
+sub SSSE3ROUND {	# critical path is 20 "SIMD ticks" per round
+	&paddd	($a,$b);
+	&pxor	($d,$a);
+	&pshufb	($d,$rot16);
+
+	&paddd	($c,$d);
+	&pxor	($b,$c);
+	&movdqa	($t,$b);
+	&psrld	($b,20);
+	&pslld	($t,12);
+	&por	($b,$t);
+
+	&paddd	($a,$b);
+	&pxor	($d,$a);
+	&pshufb	($d,$rot24);
+
+	&paddd	($c,$d);
+	&pxor	($b,$c);
+	&movdqa	($t,$b);
+	&psrld	($b,25);
+	&pslld	($t,7);
+	&por	($b,$t);
+}
+
+my $xframe = $win64 ? 32+32+8 : 24;
+
+$code.=<<___;
+.type	ChaCha20_ssse3,\@function,5
+.align	32
+ChaCha20_ssse3:
+.LChaCha20_ssse3:
+___
+$code.=<<___;
+	cmp	\$128,$len		# we might throw away some data,
+	ja	.LChaCha20_4x		# but overall it won't be slower
+
+.Ldo_sse3_after_all:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+
+	sub	\$64+$xframe,%rsp
+___
+$code.=<<___	if ($win64);
+	movaps	%xmm6,64+32(%rsp)
+	movaps	%xmm7,64+48(%rsp)
+___
+$code.=<<___;
+	movdqa	.Lsigma(%rip),$a
+	movdqu	($key),$b
+	movdqu	16($key),$c
+	movdqu	($counter),$d
+	movdqa	.Lrot16(%rip),$rot16
+	movdqa	.Lrot24(%rip),$rot24
+
+	movdqa	$a,0x00(%rsp)
+	movdqa	$b,0x10(%rsp)
+	movdqa	$c,0x20(%rsp)
+	movdqa	$d,0x30(%rsp)
+	mov	\$10,%ebp
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_outer_ssse3:
+	movdqa	.Lone(%rip),$d
+	movdqa	0x00(%rsp),$a
+	movdqa	0x10(%rsp),$b
+	movdqa	0x20(%rsp),$c
+	paddd	0x30(%rsp),$d
+	mov	\$10,%ebp
+	movdqa	$d,0x30(%rsp)
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_ssse3:
+___
+	&SSSE3ROUND();
+	&pshufd	($c,$c,0b01001110);
+	&pshufd	($b,$b,0b00111001);
+	&pshufd	($d,$d,0b10010011);
+	&nop	();
+
+	&SSSE3ROUND();
+	&pshufd	($c,$c,0b01001110);
+	&pshufd	($b,$b,0b10010011);
+	&pshufd	($d,$d,0b00111001);
+
+	&dec	("%ebp");
+	&jnz	(".Loop_ssse3");
+
+$code.=<<___;
+	paddd	0x00(%rsp),$a
+	paddd	0x10(%rsp),$b
+	paddd	0x20(%rsp),$c
+	paddd	0x30(%rsp),$d
+
+	cmp	\$64,$len
+	jb	.Ltail_ssse3
+
+	movdqu	0x00($inp),$t
+	movdqu	0x10($inp),$t1
+	pxor	$t,$a			# xor with input
+	movdqu	0x20($inp),$t
+	pxor	$t1,$b
+	movdqu	0x30($inp),$t1
+	lea	0x40($inp),$inp		# inp+=64
+	pxor	$t,$c
+	pxor	$t1,$d
+
+	movdqu	$a,0x00($out)		# write output
+	movdqu	$b,0x10($out)
+	movdqu	$c,0x20($out)
+	movdqu	$d,0x30($out)
+	lea	0x40($out),$out		# out+=64
+
+	sub	\$64,$len
+	jnz	.Loop_outer_ssse3
+
+	jmp	.Ldone_ssse3
+
+.align	16
+.Ltail_ssse3:
+	movdqa	$a,0x00(%rsp)
+	movdqa	$b,0x10(%rsp)
+	movdqa	$c,0x20(%rsp)
+	movdqa	$d,0x30(%rsp)
+	xor	%rbx,%rbx
+
+.Loop_tail_ssse3:
+	movzb	($inp,%rbx),%eax
+	movzb	(%rsp,%rbx),%ecx
+	lea	1(%rbx),%rbx
+	xor	%ecx,%eax
+	mov	%al,-1($out,%rbx)
+	dec	$len
+	jnz	.Loop_tail_ssse3
+
+.Ldone_ssse3:
+___
+$code.=<<___	if ($win64);
+	movaps	64+32(%rsp),%xmm6
+	movaps	64+48(%rsp),%xmm7
+___
+$code.=<<___;
+	add	\$64+$xframe,%rsp
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	ret
+.size	ChaCha20_ssse3,.-ChaCha20_ssse3
+___
+}
+
+########################################################################
+# SSSE3 code path that handles longer messages.
+{
+# assign variables to favor Atom front-end
+my ($xd0,$xd1,$xd2,$xd3, $xt0,$xt1,$xt2,$xt3,
+    $xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3)=map("%xmm$_",(0..15));
+my  @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
+	"%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
+
+sub SSSE3_lane_ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
+my @x=map("\"$_\"",@xx);
+
+	# Consider order in which variables are addressed by their
+	# index:
+	#
+	#	a   b   c   d
+	#
+	#	0   4   8  12 < even round
+	#	1   5   9  13
+	#	2   6  10  14
+	#	3   7  11  15
+	#	0   5  10  15 < odd round
+	#	1   6  11  12
+	#	2   7   8  13
+	#	3   4   9  14
+	#
+	# 'a', 'b' and 'd's are permanently allocated in registers,
+	# @x[0..7,12..15], while 'c's are maintained in memory. If
+	# you observe 'c' column, you'll notice that pair of 'c's is
+	# invariant between rounds. This means that we have to reload
+	# them once per round, in the middle. This is why you'll see
+	# bunch of 'c' stores and loads in the middle, but none in
+	# the beginning or end.
+
+	(
+	"&paddd		(@x[$a0],@x[$b0])",	# Q1
+	 "&paddd	(@x[$a1],@x[$b1])",	# Q2
+	"&pxor		(@x[$d0],@x[$a0])",
+	 "&pxor		(@x[$d1],@x[$a1])",
+	"&pshufb	(@x[$d0],$t1)",
+	 "&pshufb	(@x[$d1],$t1)",
+
+	"&paddd		($xc,@x[$d0])",
+	 "&paddd	($xc_,@x[$d1])",
+	"&pxor		(@x[$b0],$xc)",
+	 "&pxor		(@x[$b1],$xc_)",
+	"&movdqa	($t0,@x[$b0])",
+	"&pslld		(@x[$b0],12)",
+	"&psrld		($t0,20)",
+	 "&movdqa	($t1,@x[$b1])",
+	 "&pslld	(@x[$b1],12)",
+	"&por		(@x[$b0],$t0)",
+	 "&psrld	($t1,20)",
+	"&movdqa	($t0,'(%r11)')",	# .Lrot24(%rip)
+	 "&por		(@x[$b1],$t1)",
+
+	"&paddd		(@x[$a0],@x[$b0])",
+	 "&paddd	(@x[$a1],@x[$b1])",
+	"&pxor		(@x[$d0],@x[$a0])",
+	 "&pxor		(@x[$d1],@x[$a1])",
+	"&pshufb	(@x[$d0],$t0)",
+	 "&pshufb	(@x[$d1],$t0)",
+
+	"&paddd		($xc,@x[$d0])",
+	 "&paddd	($xc_,@x[$d1])",
+	"&pxor		(@x[$b0],$xc)",
+	 "&pxor		(@x[$b1],$xc_)",
+	"&movdqa	($t1,@x[$b0])",
+	"&pslld		(@x[$b0],7)",
+	"&psrld		($t1,25)",
+	 "&movdqa	($t0,@x[$b1])",
+	 "&pslld	(@x[$b1],7)",
+	"&por		(@x[$b0],$t1)",
+	 "&psrld	($t0,25)",
+	"&movdqa	($t1,'(%r10)')",	# .Lrot16(%rip)
+	 "&por		(@x[$b1],$t0)",
+
+	"&movdqa	(\"`16*($c0-8)`(%rsp)\",$xc)",	# reload pair of 'c's
+	 "&movdqa	(\"`16*($c1-8)`(%rsp)\",$xc_)",
+	"&movdqa	($xc,\"`16*($c2-8)`(%rsp)\")",
+	 "&movdqa	($xc_,\"`16*($c3-8)`(%rsp)\")",
+
+	"&paddd		(@x[$a2],@x[$b2])",	# Q3
+	 "&paddd	(@x[$a3],@x[$b3])",	# Q4
+	"&pxor		(@x[$d2],@x[$a2])",
+	 "&pxor		(@x[$d3],@x[$a3])",
+	"&pshufb	(@x[$d2],$t1)",
+	 "&pshufb	(@x[$d3],$t1)",
+
+	"&paddd		($xc,@x[$d2])",
+	 "&paddd	($xc_,@x[$d3])",
+	"&pxor		(@x[$b2],$xc)",
+	 "&pxor		(@x[$b3],$xc_)",
+	"&movdqa	($t0,@x[$b2])",
+	"&pslld		(@x[$b2],12)",
+	"&psrld		($t0,20)",
+	 "&movdqa	($t1,@x[$b3])",
+	 "&pslld	(@x[$b3],12)",
+	"&por		(@x[$b2],$t0)",
+	 "&psrld	($t1,20)",
+	"&movdqa	($t0,'(%r11)')",	# .Lrot24(%rip)
+	 "&por		(@x[$b3],$t1)",
+
+	"&paddd		(@x[$a2],@x[$b2])",
+	 "&paddd	(@x[$a3],@x[$b3])",
+	"&pxor		(@x[$d2],@x[$a2])",
+	 "&pxor		(@x[$d3],@x[$a3])",
+	"&pshufb	(@x[$d2],$t0)",
+	 "&pshufb	(@x[$d3],$t0)",
+
+	"&paddd		($xc,@x[$d2])",
+	 "&paddd	($xc_,@x[$d3])",
+	"&pxor		(@x[$b2],$xc)",
+	 "&pxor		(@x[$b3],$xc_)",
+	"&movdqa	($t1,@x[$b2])",
+	"&pslld		(@x[$b2],7)",
+	"&psrld		($t1,25)",
+	 "&movdqa	($t0,@x[$b3])",
+	 "&pslld	(@x[$b3],7)",
+	"&por		(@x[$b2],$t1)",
+	 "&psrld	($t0,25)",
+	"&movdqa	($t1,'(%r10)')",	# .Lrot16(%rip)
+	 "&por		(@x[$b3],$t0)"
+	);
+}
+
+my $xframe = $win64 ? 0xa0 : 0;
+
+$code.=<<___;
+.type	ChaCha20_4x,\@function,5
+.align	32
+ChaCha20_4x:
+.LChaCha20_4x:
+	mov		%r10,%r11
+___
+$code.=<<___	if ($avx>1);
+	shr		\$32,%r10		# OPENSSL_ia32cap_P+8
+	test		\$`1<<5`,%r10		# test AVX2
+	jnz		.LChaCha20_8x
+___
+$code.=<<___;
+	cmp		\$192,$len
+	ja		.Lproceed4x
+
+	and		\$`1<<26|1<<22`,%r11	# isolate XSAVE+MOVBE
+	cmp		\$`1<<22`,%r11		# check for MOVBE without XSAVE
+	je		.Ldo_sse3_after_all	# to detect Atom
+
+.Lproceed4x:
+	lea		-0x78(%rsp),%r11
+	sub		\$0x148+$xframe,%rsp
+___
+	################ stack layout
+	# +0x00		SIMD equivalent of @x[8-12]
+	# ...
+	# +0x40		constant copy of key[0-2] smashed by lanes
+	# ...
+	# +0x100	SIMD counters (with nonce smashed by lanes)
+	# ...
+	# +0x140
+$code.=<<___	if ($win64);
+	movaps		%xmm6,-0x30(%r11)
+	movaps		%xmm7,-0x20(%r11)
+	movaps		%xmm8,-0x10(%r11)
+	movaps		%xmm9,0x00(%r11)
+	movaps		%xmm10,0x10(%r11)
+	movaps		%xmm11,0x20(%r11)
+	movaps		%xmm12,0x30(%r11)
+	movaps		%xmm13,0x40(%r11)
+	movaps		%xmm14,0x50(%r11)
+	movaps		%xmm15,0x60(%r11)
+___
+$code.=<<___;
+	movdqa		.Lsigma(%rip),$xa3	# key[0]
+	movdqu		($key),$xb3		# key[1]
+	movdqu		16($key),$xt3		# key[2]
+	movdqu		($counter),$xd3		# key[3]
+	lea		0x100(%rsp),%rcx	# size optimization
+	lea		.Lrot16(%rip),%r10
+	lea		.Lrot24(%rip),%r11
+
+	pshufd		\$0x00,$xa3,$xa0	# smash key by lanes...
+	pshufd		\$0x55,$xa3,$xa1
+	movdqa		$xa0,0x40(%rsp)		# ... and offload
+	pshufd		\$0xaa,$xa3,$xa2
+	movdqa		$xa1,0x50(%rsp)
+	pshufd		\$0xff,$xa3,$xa3
+	movdqa		$xa2,0x60(%rsp)
+	movdqa		$xa3,0x70(%rsp)
+
+	pshufd		\$0x00,$xb3,$xb0
+	pshufd		\$0x55,$xb3,$xb1
+	movdqa		$xb0,0x80-0x100(%rcx)
+	pshufd		\$0xaa,$xb3,$xb2
+	movdqa		$xb1,0x90-0x100(%rcx)
+	pshufd		\$0xff,$xb3,$xb3
+	movdqa		$xb2,0xa0-0x100(%rcx)
+	movdqa		$xb3,0xb0-0x100(%rcx)
+
+	pshufd		\$0x00,$xt3,$xt0	# "$xc0"
+	pshufd		\$0x55,$xt3,$xt1	# "$xc1"
+	movdqa		$xt0,0xc0-0x100(%rcx)
+	pshufd		\$0xaa,$xt3,$xt2	# "$xc2"
+	movdqa		$xt1,0xd0-0x100(%rcx)
+	pshufd		\$0xff,$xt3,$xt3	# "$xc3"
+	movdqa		$xt2,0xe0-0x100(%rcx)
+	movdqa		$xt3,0xf0-0x100(%rcx)
+
+	pshufd		\$0x00,$xd3,$xd0
+	pshufd		\$0x55,$xd3,$xd1
+	paddd		.Linc(%rip),$xd0	# don't save counters yet
+	pshufd		\$0xaa,$xd3,$xd2
+	movdqa		$xd1,0x110-0x100(%rcx)
+	pshufd		\$0xff,$xd3,$xd3
+	movdqa		$xd2,0x120-0x100(%rcx)
+	movdqa		$xd3,0x130-0x100(%rcx)
+
+	jmp		.Loop_enter4x
+
+.align	32
+.Loop_outer4x:
+	movdqa		0x40(%rsp),$xa0		# re-load smashed key
+	movdqa		0x50(%rsp),$xa1
+	movdqa		0x60(%rsp),$xa2
+	movdqa		0x70(%rsp),$xa3
+	movdqa		0x80-0x100(%rcx),$xb0
+	movdqa		0x90-0x100(%rcx),$xb1
+	movdqa		0xa0-0x100(%rcx),$xb2
+	movdqa		0xb0-0x100(%rcx),$xb3
+	movdqa		0xc0-0x100(%rcx),$xt0	# "$xc0"
+	movdqa		0xd0-0x100(%rcx),$xt1	# "$xc1"
+	movdqa		0xe0-0x100(%rcx),$xt2	# "$xc2"
+	movdqa		0xf0-0x100(%rcx),$xt3	# "$xc3"
+	movdqa		0x100-0x100(%rcx),$xd0
+	movdqa		0x110-0x100(%rcx),$xd1
+	movdqa		0x120-0x100(%rcx),$xd2
+	movdqa		0x130-0x100(%rcx),$xd3
+	paddd		.Lfour(%rip),$xd0	# next SIMD counters
+
+.Loop_enter4x:
+	movdqa		$xt2,0x20(%rsp)		# SIMD equivalent of "@x[10]"
+	movdqa		$xt3,0x30(%rsp)		# SIMD equivalent of "@x[11]"
+	movdqa		(%r10),$xt3		# .Lrot16(%rip)
+	mov		\$10,%eax
+	movdqa		$xd0,0x100-0x100(%rcx)	# save SIMD counters
+	jmp		.Loop4x
+
+.align	32
+.Loop4x:
+___
+	foreach (&SSSE3_lane_ROUND(0, 4, 8,12)) { eval; }
+	foreach (&SSSE3_lane_ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+	dec		%eax
+	jnz		.Loop4x
+
+	paddd		0x40(%rsp),$xa0		# accumulate key material
+	paddd		0x50(%rsp),$xa1
+	paddd		0x60(%rsp),$xa2
+	paddd		0x70(%rsp),$xa3
+
+	movdqa		$xa0,$xt2		# "de-interlace" data
+	punpckldq	$xa1,$xa0
+	movdqa		$xa2,$xt3
+	punpckldq	$xa3,$xa2
+	punpckhdq	$xa1,$xt2
+	punpckhdq	$xa3,$xt3
+	movdqa		$xa0,$xa1
+	punpcklqdq	$xa2,$xa0		# "a0"
+	movdqa		$xt2,$xa3
+	punpcklqdq	$xt3,$xt2		# "a2"
+	punpckhqdq	$xa2,$xa1		# "a1"
+	punpckhqdq	$xt3,$xa3		# "a3"
+___
+	($xa2,$xt2)=($xt2,$xa2);
+$code.=<<___;
+	paddd		0x80-0x100(%rcx),$xb0
+	paddd		0x90-0x100(%rcx),$xb1
+	paddd		0xa0-0x100(%rcx),$xb2
+	paddd		0xb0-0x100(%rcx),$xb3
+
+	movdqa		$xa0,0x00(%rsp)		# offload $xaN
+	movdqa		$xa1,0x10(%rsp)
+	movdqa		0x20(%rsp),$xa0		# "xc2"
+	movdqa		0x30(%rsp),$xa1		# "xc3"
+
+	movdqa		$xb0,$xt2
+	punpckldq	$xb1,$xb0
+	movdqa		$xb2,$xt3
+	punpckldq	$xb3,$xb2
+	punpckhdq	$xb1,$xt2
+	punpckhdq	$xb3,$xt3
+	movdqa		$xb0,$xb1
+	punpcklqdq	$xb2,$xb0		# "b0"
+	movdqa		$xt2,$xb3
+	punpcklqdq	$xt3,$xt2		# "b2"
+	punpckhqdq	$xb2,$xb1		# "b1"
+	punpckhqdq	$xt3,$xb3		# "b3"
+___
+	($xb2,$xt2)=($xt2,$xb2);
+	my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
+$code.=<<___;
+	paddd		0xc0-0x100(%rcx),$xc0
+	paddd		0xd0-0x100(%rcx),$xc1
+	paddd		0xe0-0x100(%rcx),$xc2
+	paddd		0xf0-0x100(%rcx),$xc3
+
+	movdqa		$xa2,0x20(%rsp)		# keep offloading $xaN
+	movdqa		$xa3,0x30(%rsp)
+
+	movdqa		$xc0,$xt2
+	punpckldq	$xc1,$xc0
+	movdqa		$xc2,$xt3
+	punpckldq	$xc3,$xc2
+	punpckhdq	$xc1,$xt2
+	punpckhdq	$xc3,$xt3
+	movdqa		$xc0,$xc1
+	punpcklqdq	$xc2,$xc0		# "c0"
+	movdqa		$xt2,$xc3
+	punpcklqdq	$xt3,$xt2		# "c2"
+	punpckhqdq	$xc2,$xc1		# "c1"
+	punpckhqdq	$xt3,$xc3		# "c3"
+___
+	($xc2,$xt2)=($xt2,$xc2);
+	($xt0,$xt1)=($xa2,$xa3);		# use $xaN as temporary
+$code.=<<___;
+	paddd		0x100-0x100(%rcx),$xd0
+	paddd		0x110-0x100(%rcx),$xd1
+	paddd		0x120-0x100(%rcx),$xd2
+	paddd		0x130-0x100(%rcx),$xd3
+
+	movdqa		$xd0,$xt2
+	punpckldq	$xd1,$xd0
+	movdqa		$xd2,$xt3
+	punpckldq	$xd3,$xd2
+	punpckhdq	$xd1,$xt2
+	punpckhdq	$xd3,$xt3
+	movdqa		$xd0,$xd1
+	punpcklqdq	$xd2,$xd0		# "d0"
+	movdqa		$xt2,$xd3
+	punpcklqdq	$xt3,$xt2		# "d2"
+	punpckhqdq	$xd2,$xd1		# "d1"
+	punpckhqdq	$xt3,$xd3		# "d3"
+___
+	($xd2,$xt2)=($xt2,$xd2);
+$code.=<<___;
+	cmp		\$64*4,$len
+	jb		.Ltail4x
+
+	movdqu		0x00($inp),$xt0		# xor with input
+	movdqu		0x10($inp),$xt1
+	movdqu		0x20($inp),$xt2
+	movdqu		0x30($inp),$xt3
+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
+	pxor		$xb0,$xt1
+	pxor		$xc0,$xt2
+	pxor		$xd0,$xt3
+
+	 movdqu		$xt0,0x00($out)
+	movdqu		0x40($inp),$xt0
+	 movdqu		$xt1,0x10($out)
+	movdqu		0x50($inp),$xt1
+	 movdqu		$xt2,0x20($out)
+	movdqu		0x60($inp),$xt2
+	 movdqu		$xt3,0x30($out)
+	movdqu		0x70($inp),$xt3
+	lea		0x80($inp),$inp		# size optimization
+	pxor		0x10(%rsp),$xt0
+	pxor		$xb1,$xt1
+	pxor		$xc1,$xt2
+	pxor		$xd1,$xt3
+
+	 movdqu		$xt0,0x40($out)
+	movdqu		0x00($inp),$xt0
+	 movdqu		$xt1,0x50($out)
+	movdqu		0x10($inp),$xt1
+	 movdqu		$xt2,0x60($out)
+	movdqu		0x20($inp),$xt2
+	 movdqu		$xt3,0x70($out)
+	 lea		0x80($out),$out		# size optimization
+	movdqu		0x30($inp),$xt3
+	pxor		0x20(%rsp),$xt0
+	pxor		$xb2,$xt1
+	pxor		$xc2,$xt2
+	pxor		$xd2,$xt3
+
+	 movdqu		$xt0,0x00($out)
+	movdqu		0x40($inp),$xt0
+	 movdqu		$xt1,0x10($out)
+	movdqu		0x50($inp),$xt1
+	 movdqu		$xt2,0x20($out)
+	movdqu		0x60($inp),$xt2
+	 movdqu		$xt3,0x30($out)
+	movdqu		0x70($inp),$xt3
+	lea		0x80($inp),$inp		# inp+=64*4
+	pxor		0x30(%rsp),$xt0
+	pxor		$xb3,$xt1
+	pxor		$xc3,$xt2
+	pxor		$xd3,$xt3
+	movdqu		$xt0,0x40($out)
+	movdqu		$xt1,0x50($out)
+	movdqu		$xt2,0x60($out)
+	movdqu		$xt3,0x70($out)
+	lea		0x80($out),$out		# out+=64*4
+
+	sub		\$64*4,$len
+	jnz		.Loop_outer4x
+
+	jmp		.Ldone4x
+
+.Ltail4x:
+	cmp		\$192,$len
+	jae		.L192_or_more4x
+	cmp		\$128,$len
+	jae		.L128_or_more4x
+	cmp		\$64,$len
+	jae		.L64_or_more4x
+
+	#movdqa		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
+	xor		%r10,%r10
+	#movdqa		$xt0,0x00(%rsp)
+	movdqa		$xb0,0x10(%rsp)
+	movdqa		$xc0,0x20(%rsp)
+	movdqa		$xd0,0x30(%rsp)
+	jmp		.Loop_tail4x
+
+.align	32
+.L64_or_more4x:
+	movdqu		0x00($inp),$xt0		# xor with input
+	movdqu		0x10($inp),$xt1
+	movdqu		0x20($inp),$xt2
+	movdqu		0x30($inp),$xt3
+	pxor		0x00(%rsp),$xt0		# $xaxN is offloaded, remember?
+	pxor		$xb0,$xt1
+	pxor		$xc0,$xt2
+	pxor		$xd0,$xt3
+	movdqu		$xt0,0x00($out)
+	movdqu		$xt1,0x10($out)
+	movdqu		$xt2,0x20($out)
+	movdqu		$xt3,0x30($out)
+	je		.Ldone4x
+
+	movdqa		0x10(%rsp),$xt0		# $xaN is offloaded, remember?
+	lea		0x40($inp),$inp		# inp+=64*1
+	xor		%r10,%r10
+	movdqa		$xt0,0x00(%rsp)
+	movdqa		$xb1,0x10(%rsp)
+	lea		0x40($out),$out		# out+=64*1
+	movdqa		$xc1,0x20(%rsp)
+	sub		\$64,$len		# len-=64*1
+	movdqa		$xd1,0x30(%rsp)
+	jmp		.Loop_tail4x
+
+.align	32
+.L128_or_more4x:
+	movdqu		0x00($inp),$xt0		# xor with input
+	movdqu		0x10($inp),$xt1
+	movdqu		0x20($inp),$xt2
+	movdqu		0x30($inp),$xt3
+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
+	pxor		$xb0,$xt1
+	pxor		$xc0,$xt2
+	pxor		$xd0,$xt3
+
+	 movdqu		$xt0,0x00($out)
+	movdqu		0x40($inp),$xt0
+	 movdqu		$xt1,0x10($out)
+	movdqu		0x50($inp),$xt1
+	 movdqu		$xt2,0x20($out)
+	movdqu		0x60($inp),$xt2
+	 movdqu		$xt3,0x30($out)
+	movdqu		0x70($inp),$xt3
+	pxor		0x10(%rsp),$xt0
+	pxor		$xb1,$xt1
+	pxor		$xc1,$xt2
+	pxor		$xd1,$xt3
+	movdqu		$xt0,0x40($out)
+	movdqu		$xt1,0x50($out)
+	movdqu		$xt2,0x60($out)
+	movdqu		$xt3,0x70($out)
+	je		.Ldone4x
+
+	movdqa		0x20(%rsp),$xt0		# $xaN is offloaded, remember?
+	lea		0x80($inp),$inp		# inp+=64*2
+	xor		%r10,%r10
+	movdqa		$xt0,0x00(%rsp)
+	movdqa		$xb2,0x10(%rsp)
+	lea		0x80($out),$out		# out+=64*2
+	movdqa		$xc2,0x20(%rsp)
+	sub		\$128,$len		# len-=64*2
+	movdqa		$xd2,0x30(%rsp)
+	jmp		.Loop_tail4x
+
+.align	32
+.L192_or_more4x:
+	movdqu		0x00($inp),$xt0		# xor with input
+	movdqu		0x10($inp),$xt1
+	movdqu		0x20($inp),$xt2
+	movdqu		0x30($inp),$xt3
+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
+	pxor		$xb0,$xt1
+	pxor		$xc0,$xt2
+	pxor		$xd0,$xt3
+
+	 movdqu		$xt0,0x00($out)
+	movdqu		0x40($inp),$xt0
+	 movdqu		$xt1,0x10($out)
+	movdqu		0x50($inp),$xt1
+	 movdqu		$xt2,0x20($out)
+	movdqu		0x60($inp),$xt2
+	 movdqu		$xt3,0x30($out)
+	movdqu		0x70($inp),$xt3
+	lea		0x80($inp),$inp		# size optimization
+	pxor		0x10(%rsp),$xt0
+	pxor		$xb1,$xt1
+	pxor		$xc1,$xt2
+	pxor		$xd1,$xt3
+
+	 movdqu		$xt0,0x40($out)
+	movdqu		0x00($inp),$xt0
+	 movdqu		$xt1,0x50($out)
+	movdqu		0x10($inp),$xt1
+	 movdqu		$xt2,0x60($out)
+	movdqu		0x20($inp),$xt2
+	 movdqu		$xt3,0x70($out)
+	 lea		0x80($out),$out		# size optimization
+	movdqu		0x30($inp),$xt3
+	pxor		0x20(%rsp),$xt0
+	pxor		$xb2,$xt1
+	pxor		$xc2,$xt2
+	pxor		$xd2,$xt3
+	movdqu		$xt0,0x00($out)
+	movdqu		$xt1,0x10($out)
+	movdqu		$xt2,0x20($out)
+	movdqu		$xt3,0x30($out)
+	je		.Ldone4x
+
+	movdqa		0x30(%rsp),$xt0		# $xaN is offloaded, remember?
+	lea		0x40($inp),$inp		# inp+=64*3
+	xor		%r10,%r10
+	movdqa		$xt0,0x00(%rsp)
+	movdqa		$xb3,0x10(%rsp)
+	lea		0x40($out),$out		# out+=64*3
+	movdqa		$xc3,0x20(%rsp)
+	sub		\$192,$len		# len-=64*3
+	movdqa		$xd3,0x30(%rsp)
+
+.Loop_tail4x:
+	movzb		($inp,%r10),%eax
+	movzb		(%rsp,%r10),%ecx
+	lea		1(%r10),%r10
+	xor		%ecx,%eax
+	mov		%al,-1($out,%r10)
+	dec		$len
+	jnz		.Loop_tail4x
+
+.Ldone4x:
+___
+$code.=<<___	if ($win64);
+	lea		0x140+0x30(%rsp),%r11
+	movaps		-0x30(%r11),%xmm6
+	movaps		-0x20(%r11),%xmm7
+	movaps		-0x10(%r11),%xmm8
+	movaps		0x00(%r11),%xmm9
+	movaps		0x10(%r11),%xmm10
+	movaps		0x20(%r11),%xmm11
+	movaps		0x30(%r11),%xmm12
+	movaps		0x40(%r11),%xmm13
+	movaps		0x50(%r11),%xmm14
+	movaps		0x60(%r11),%xmm15
+___
+$code.=<<___;
+	add		\$0x148+$xframe,%rsp
+	ret
+.size	ChaCha20_4x,.-ChaCha20_4x
+___
+}
+
+########################################################################
+# AVX2 code path
+if ($avx>1) {
+my ($xb0,$xb1,$xb2,$xb3, $xd0,$xd1,$xd2,$xd3,
+    $xa0,$xa1,$xa2,$xa3, $xt0,$xt1,$xt2,$xt3)=map("%ymm$_",(0..15));
+my @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
+	"%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
+
+sub AVX2_lane_ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
+my @x=map("\"$_\"",@xx);
+
+	# Consider order in which variables are addressed by their
+	# index:
+	#
+	#	a   b   c   d
+	#
+	#	0   4   8  12 < even round
+	#	1   5   9  13
+	#	2   6  10  14
+	#	3   7  11  15
+	#	0   5  10  15 < odd round
+	#	1   6  11  12
+	#	2   7   8  13
+	#	3   4   9  14
+	#
+	# 'a', 'b' and 'd's are permanently allocated in registers,
+	# @x[0..7,12..15], while 'c's are maintained in memory. If
+	# you observe 'c' column, you'll notice that pair of 'c's is
+	# invariant between rounds. This means that we have to reload
+	# them once per round, in the middle. This is why you'll see
+	# bunch of 'c' stores and loads in the middle, but none in
+	# the beginning or end.
+
+	(
+	"&vpaddd	(@x[$a0],@x[$a0],@x[$b0])",	# Q1
+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
+	"&vpshufb	(@x[$d0],@x[$d0],$t1)",
+	 "&vpaddd	(@x[$a1],@x[$a1],@x[$b1])",	# Q2
+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
+	 "&vpshufb	(@x[$d1],@x[$d1],$t1)",
+
+	"&vpaddd	($xc,$xc,@x[$d0])",
+	"&vpxor		(@x[$b0],$xc,@x[$b0])",
+	"&vpslld	($t0,@x[$b0],12)",
+	"&vpsrld	(@x[$b0],@x[$b0],20)",
+	"&vpor		(@x[$b0],$t0,@x[$b0])",
+	"&vbroadcasti128($t0,'(%r11)')",		# .Lrot24(%rip)
+	 "&vpaddd	($xc_,$xc_,@x[$d1])",
+	 "&vpxor	(@x[$b1],$xc_,@x[$b1])",
+	 "&vpslld	($t1,@x[$b1],12)",
+	 "&vpsrld	(@x[$b1],@x[$b1],20)",
+	 "&vpor		(@x[$b1],$t1,@x[$b1])",
+
+	"&vpaddd	(@x[$a0],@x[$a0],@x[$b0])",
+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
+	"&vpshufb	(@x[$d0],@x[$d0],$t0)",
+	 "&vpaddd	(@x[$a1],@x[$a1],@x[$b1])",
+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
+	 "&vpshufb	(@x[$d1],@x[$d1],$t0)",
+
+	"&vpaddd	($xc,$xc,@x[$d0])",
+	"&vpxor		(@x[$b0],$xc,@x[$b0])",
+	"&vpslld	($t1,@x[$b0],7)",
+	"&vpsrld	(@x[$b0],@x[$b0],25)",
+	"&vpor		(@x[$b0],$t1,@x[$b0])",
+	"&vbroadcasti128($t1,'(%r10)')",		# .Lrot16(%rip)
+	 "&vpaddd	($xc_,$xc_,@x[$d1])",
+	 "&vpxor	(@x[$b1],$xc_,@x[$b1])",
+	 "&vpslld	($t0,@x[$b1],7)",
+	 "&vpsrld	(@x[$b1],@x[$b1],25)",
+	 "&vpor		(@x[$b1],$t0,@x[$b1])",
+
+	"&vmovdqa	(\"`32*($c0-8)`(%rsp)\",$xc)",	# reload pair of 'c's
+	 "&vmovdqa	(\"`32*($c1-8)`(%rsp)\",$xc_)",
+	"&vmovdqa	($xc,\"`32*($c2-8)`(%rsp)\")",
+	 "&vmovdqa	($xc_,\"`32*($c3-8)`(%rsp)\")",
+
+	"&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",	# Q3
+	"&vpxor		(@x[$d2],@x[$a2],@x[$d2])",
+	"&vpshufb	(@x[$d2],@x[$d2],$t1)",
+	 "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",	# Q4
+	 "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
+	 "&vpshufb	(@x[$d3],@x[$d3],$t1)",
+
+	"&vpaddd	($xc,$xc,@x[$d2])",
+	"&vpxor		(@x[$b2],$xc,@x[$b2])",
+	"&vpslld	($t0,@x[$b2],12)",
+	"&vpsrld	(@x[$b2],@x[$b2],20)",
+	"&vpor		(@x[$b2],$t0,@x[$b2])",
+	"&vbroadcasti128($t0,'(%r11)')",		# .Lrot24(%rip)
+	 "&vpaddd	($xc_,$xc_,@x[$d3])",
+	 "&vpxor	(@x[$b3],$xc_,@x[$b3])",
+	 "&vpslld	($t1,@x[$b3],12)",
+	 "&vpsrld	(@x[$b3],@x[$b3],20)",
+	 "&vpor		(@x[$b3],$t1,@x[$b3])",
+
+	"&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",
+	"&vpxor		(@x[$d2],@x[$a2],@x[$d2])",
+	"&vpshufb	(@x[$d2],@x[$d2],$t0)",
+	 "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",
+	 "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
+	 "&vpshufb	(@x[$d3],@x[$d3],$t0)",
+
+	"&vpaddd	($xc,$xc,@x[$d2])",
+	"&vpxor		(@x[$b2],$xc,@x[$b2])",
+	"&vpslld	($t1,@x[$b2],7)",
+	"&vpsrld	(@x[$b2],@x[$b2],25)",
+	"&vpor		(@x[$b2],$t1,@x[$b2])",
+	"&vbroadcasti128($t1,'(%r10)')",		# .Lrot16(%rip)
+	 "&vpaddd	($xc_,$xc_,@x[$d3])",
+	 "&vpxor	(@x[$b3],$xc_,@x[$b3])",
+	 "&vpslld	($t0,@x[$b3],7)",
+	 "&vpsrld	(@x[$b3],@x[$b3],25)",
+	 "&vpor		(@x[$b3],$t0,@x[$b3])"
+	);
+}
+
+my $xframe = $win64 ? 0xb0 : 8;
+
+$code.=<<___;
+.type	ChaCha20_8x,\@function,5
+.align	32
+ChaCha20_8x:
+.LChaCha20_8x:
+	mov		%rsp,%r10
+	sub		\$0x280+$xframe,%rsp
+	and		\$-32,%rsp
+___
+$code.=<<___	if ($win64);
+	lea		0x290+0x30(%rsp),%r11
+	movaps		%xmm6,-0x30(%r11)
+	movaps		%xmm7,-0x20(%r11)
+	movaps		%xmm8,-0x10(%r11)
+	movaps		%xmm9,0x00(%r11)
+	movaps		%xmm10,0x10(%r11)
+	movaps		%xmm11,0x20(%r11)
+	movaps		%xmm12,0x30(%r11)
+	movaps		%xmm13,0x40(%r11)
+	movaps		%xmm14,0x50(%r11)
+	movaps		%xmm15,0x60(%r11)
+___
+$code.=<<___;
+	vzeroupper
+	mov		%r10,0x280(%rsp)
+
+	################ stack layout
+	# +0x00		SIMD equivalent of @x[8-12]
+	# ...
+	# +0x80		constant copy of key[0-2] smashed by lanes
+	# ...
+	# +0x200	SIMD counters (with nonce smashed by lanes)
+	# ...
+	# +0x280	saved %rsp
+
+	vbroadcasti128	.Lsigma(%rip),$xa3	# key[0]
+	vbroadcasti128	($key),$xb3		# key[1]
+	vbroadcasti128	16($key),$xt3		# key[2]
+	vbroadcasti128	($counter),$xd3		# key[3]
+	lea		0x100(%rsp),%rcx	# size optimization
+	lea		0x200(%rsp),%rax	# size optimization
+	lea		.Lrot16(%rip),%r10
+	lea		.Lrot24(%rip),%r11
+
+	vpshufd		\$0x00,$xa3,$xa0	# smash key by lanes...
+	vpshufd		\$0x55,$xa3,$xa1
+	vmovdqa		$xa0,0x80-0x100(%rcx)	# ... and offload
+	vpshufd		\$0xaa,$xa3,$xa2
+	vmovdqa		$xa1,0xa0-0x100(%rcx)
+	vpshufd		\$0xff,$xa3,$xa3
+	vmovdqa		$xa2,0xc0-0x100(%rcx)
+	vmovdqa		$xa3,0xe0-0x100(%rcx)
+
+	vpshufd		\$0x00,$xb3,$xb0
+	vpshufd		\$0x55,$xb3,$xb1
+	vmovdqa		$xb0,0x100-0x100(%rcx)
+	vpshufd		\$0xaa,$xb3,$xb2
+	vmovdqa		$xb1,0x120-0x100(%rcx)
+	vpshufd		\$0xff,$xb3,$xb3
+	vmovdqa		$xb2,0x140-0x100(%rcx)
+	vmovdqa		$xb3,0x160-0x100(%rcx)
+
+	vpshufd		\$0x00,$xt3,$xt0	# "xc0"
+	vpshufd		\$0x55,$xt3,$xt1	# "xc1"
+	vmovdqa		$xt0,0x180-0x200(%rax)
+	vpshufd		\$0xaa,$xt3,$xt2	# "xc2"
+	vmovdqa		$xt1,0x1a0-0x200(%rax)
+	vpshufd		\$0xff,$xt3,$xt3	# "xc3"
+	vmovdqa		$xt2,0x1c0-0x200(%rax)
+	vmovdqa		$xt3,0x1e0-0x200(%rax)
+
+	vpshufd		\$0x00,$xd3,$xd0
+	vpshufd		\$0x55,$xd3,$xd1
+	vpaddd		.Lincy(%rip),$xd0,$xd0	# don't save counters yet
+	vpshufd		\$0xaa,$xd3,$xd2
+	vmovdqa		$xd1,0x220-0x200(%rax)
+	vpshufd		\$0xff,$xd3,$xd3
+	vmovdqa		$xd2,0x240-0x200(%rax)
+	vmovdqa		$xd3,0x260-0x200(%rax)
+
+	jmp		.Loop_enter8x
+
+.align	32
+.Loop_outer8x:
+	vmovdqa		0x80-0x100(%rcx),$xa0	# re-load smashed key
+	vmovdqa		0xa0-0x100(%rcx),$xa1
+	vmovdqa		0xc0-0x100(%rcx),$xa2
+	vmovdqa		0xe0-0x100(%rcx),$xa3
+	vmovdqa		0x100-0x100(%rcx),$xb0
+	vmovdqa		0x120-0x100(%rcx),$xb1
+	vmovdqa		0x140-0x100(%rcx),$xb2
+	vmovdqa		0x160-0x100(%rcx),$xb3
+	vmovdqa		0x180-0x200(%rax),$xt0	# "xc0"
+	vmovdqa		0x1a0-0x200(%rax),$xt1	# "xc1"
+	vmovdqa		0x1c0-0x200(%rax),$xt2	# "xc2"
+	vmovdqa		0x1e0-0x200(%rax),$xt3	# "xc3"
+	vmovdqa		0x200-0x200(%rax),$xd0
+	vmovdqa		0x220-0x200(%rax),$xd1
+	vmovdqa		0x240-0x200(%rax),$xd2
+	vmovdqa		0x260-0x200(%rax),$xd3
+	vpaddd		.Leight(%rip),$xd0,$xd0	# next SIMD counters
+
+.Loop_enter8x:
+	vmovdqa		$xt2,0x40(%rsp)		# SIMD equivalent of "@x[10]"
+	vmovdqa		$xt3,0x60(%rsp)		# SIMD equivalent of "@x[11]"
+	vbroadcasti128	(%r10),$xt3
+	vmovdqa		$xd0,0x200-0x200(%rax)	# save SIMD counters
+	mov		\$10,%eax
+	jmp		.Loop8x
+
+.align	32
+.Loop8x:
+___
+	foreach (&AVX2_lane_ROUND(0, 4, 8,12)) { eval; }
+	foreach (&AVX2_lane_ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+	dec		%eax
+	jnz		.Loop8x
+
+	lea		0x200(%rsp),%rax	# size optimization
+	vpaddd		0x80-0x100(%rcx),$xa0,$xa0	# accumulate key
+	vpaddd		0xa0-0x100(%rcx),$xa1,$xa1
+	vpaddd		0xc0-0x100(%rcx),$xa2,$xa2
+	vpaddd		0xe0-0x100(%rcx),$xa3,$xa3
+
+	vpunpckldq	$xa1,$xa0,$xt2		# "de-interlace" data
+	vpunpckldq	$xa3,$xa2,$xt3
+	vpunpckhdq	$xa1,$xa0,$xa0
+	vpunpckhdq	$xa3,$xa2,$xa2
+	vpunpcklqdq	$xt3,$xt2,$xa1		# "a0"
+	vpunpckhqdq	$xt3,$xt2,$xt2		# "a1"
+	vpunpcklqdq	$xa2,$xa0,$xa3		# "a2"
+	vpunpckhqdq	$xa2,$xa0,$xa0		# "a3"
+___
+	($xa0,$xa1,$xa2,$xa3,$xt2)=($xa1,$xt2,$xa3,$xa0,$xa2);
+$code.=<<___;
+	vpaddd		0x100-0x100(%rcx),$xb0,$xb0
+	vpaddd		0x120-0x100(%rcx),$xb1,$xb1
+	vpaddd		0x140-0x100(%rcx),$xb2,$xb2
+	vpaddd		0x160-0x100(%rcx),$xb3,$xb3
+
+	vpunpckldq	$xb1,$xb0,$xt2
+	vpunpckldq	$xb3,$xb2,$xt3
+	vpunpckhdq	$xb1,$xb0,$xb0
+	vpunpckhdq	$xb3,$xb2,$xb2
+	vpunpcklqdq	$xt3,$xt2,$xb1		# "b0"
+	vpunpckhqdq	$xt3,$xt2,$xt2		# "b1"
+	vpunpcklqdq	$xb2,$xb0,$xb3		# "b2"
+	vpunpckhqdq	$xb2,$xb0,$xb0		# "b3"
+___
+	($xb0,$xb1,$xb2,$xb3,$xt2)=($xb1,$xt2,$xb3,$xb0,$xb2);
+$code.=<<___;
+	vperm2i128	\$0x20,$xb0,$xa0,$xt3	# "de-interlace" further
+	vperm2i128	\$0x31,$xb0,$xa0,$xb0
+	vperm2i128	\$0x20,$xb1,$xa1,$xa0
+	vperm2i128	\$0x31,$xb1,$xa1,$xb1
+	vperm2i128	\$0x20,$xb2,$xa2,$xa1
+	vperm2i128	\$0x31,$xb2,$xa2,$xb2
+	vperm2i128	\$0x20,$xb3,$xa3,$xa2
+	vperm2i128	\$0x31,$xb3,$xa3,$xb3
+___
+	($xa0,$xa1,$xa2,$xa3,$xt3)=($xt3,$xa0,$xa1,$xa2,$xa3);
+	my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
+$code.=<<___;
+	vmovdqa		$xa0,0x00(%rsp)		# offload $xaN
+	vmovdqa		$xa1,0x20(%rsp)
+	vmovdqa		0x40(%rsp),$xc2		# $xa0
+	vmovdqa		0x60(%rsp),$xc3		# $xa1
+
+	vpaddd		0x180-0x200(%rax),$xc0,$xc0
+	vpaddd		0x1a0-0x200(%rax),$xc1,$xc1
+	vpaddd		0x1c0-0x200(%rax),$xc2,$xc2
+	vpaddd		0x1e0-0x200(%rax),$xc3,$xc3
+
+	vpunpckldq	$xc1,$xc0,$xt2
+	vpunpckldq	$xc3,$xc2,$xt3
+	vpunpckhdq	$xc1,$xc0,$xc0
+	vpunpckhdq	$xc3,$xc2,$xc2
+	vpunpcklqdq	$xt3,$xt2,$xc1		# "c0"
+	vpunpckhqdq	$xt3,$xt2,$xt2		# "c1"
+	vpunpcklqdq	$xc2,$xc0,$xc3		# "c2"
+	vpunpckhqdq	$xc2,$xc0,$xc0		# "c3"
+___
+	($xc0,$xc1,$xc2,$xc3,$xt2)=($xc1,$xt2,$xc3,$xc0,$xc2);
+$code.=<<___;
+	vpaddd		0x200-0x200(%rax),$xd0,$xd0
+	vpaddd		0x220-0x200(%rax),$xd1,$xd1
+	vpaddd		0x240-0x200(%rax),$xd2,$xd2
+	vpaddd		0x260-0x200(%rax),$xd3,$xd3
+
+	vpunpckldq	$xd1,$xd0,$xt2
+	vpunpckldq	$xd3,$xd2,$xt3
+	vpunpckhdq	$xd1,$xd0,$xd0
+	vpunpckhdq	$xd3,$xd2,$xd2
+	vpunpcklqdq	$xt3,$xt2,$xd1		# "d0"
+	vpunpckhqdq	$xt3,$xt2,$xt2		# "d1"
+	vpunpcklqdq	$xd2,$xd0,$xd3		# "d2"
+	vpunpckhqdq	$xd2,$xd0,$xd0		# "d3"
+___
+	($xd0,$xd1,$xd2,$xd3,$xt2)=($xd1,$xt2,$xd3,$xd0,$xd2);
+$code.=<<___;
+	vperm2i128	\$0x20,$xd0,$xc0,$xt3	# "de-interlace" further
+	vperm2i128	\$0x31,$xd0,$xc0,$xd0
+	vperm2i128	\$0x20,$xd1,$xc1,$xc0
+	vperm2i128	\$0x31,$xd1,$xc1,$xd1
+	vperm2i128	\$0x20,$xd2,$xc2,$xc1
+	vperm2i128	\$0x31,$xd2,$xc2,$xd2
+	vperm2i128	\$0x20,$xd3,$xc3,$xc2
+	vperm2i128	\$0x31,$xd3,$xc3,$xd3
+___
+	($xc0,$xc1,$xc2,$xc3,$xt3)=($xt3,$xc0,$xc1,$xc2,$xc3);
+	($xb0,$xb1,$xb2,$xb3,$xc0,$xc1,$xc2,$xc3)=
+	($xc0,$xc1,$xc2,$xc3,$xb0,$xb1,$xb2,$xb3);
+	($xa0,$xa1)=($xt2,$xt3);
+$code.=<<___;
+	vmovdqa		0x00(%rsp),$xa0		# $xaN was offloaded, remember?
+	vmovdqa		0x20(%rsp),$xa1
+
+	cmp		\$64*8,$len
+	jb		.Ltail8x
+
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	lea		0x80($inp),$inp		# size optimization
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	lea		0x80($out),$out		# size optimization
+
+	vpxor		0x00($inp),$xa1,$xa1
+	vpxor		0x20($inp),$xb1,$xb1
+	vpxor		0x40($inp),$xc1,$xc1
+	vpxor		0x60($inp),$xd1,$xd1
+	lea		0x80($inp),$inp		# size optimization
+	vmovdqu		$xa1,0x00($out)
+	vmovdqu		$xb1,0x20($out)
+	vmovdqu		$xc1,0x40($out)
+	vmovdqu		$xd1,0x60($out)
+	lea		0x80($out),$out		# size optimization
+
+	vpxor		0x00($inp),$xa2,$xa2
+	vpxor		0x20($inp),$xb2,$xb2
+	vpxor		0x40($inp),$xc2,$xc2
+	vpxor		0x60($inp),$xd2,$xd2
+	lea		0x80($inp),$inp		# size optimization
+	vmovdqu		$xa2,0x00($out)
+	vmovdqu		$xb2,0x20($out)
+	vmovdqu		$xc2,0x40($out)
+	vmovdqu		$xd2,0x60($out)
+	lea		0x80($out),$out		# size optimization
+
+	vpxor		0x00($inp),$xa3,$xa3
+	vpxor		0x20($inp),$xb3,$xb3
+	vpxor		0x40($inp),$xc3,$xc3
+	vpxor		0x60($inp),$xd3,$xd3
+	lea		0x80($inp),$inp		# size optimization
+	vmovdqu		$xa3,0x00($out)
+	vmovdqu		$xb3,0x20($out)
+	vmovdqu		$xc3,0x40($out)
+	vmovdqu		$xd3,0x60($out)
+	lea		0x80($out),$out		# size optimization
+
+	sub		\$64*8,$len
+	jnz		.Loop_outer8x
+
+	jmp		.Ldone8x
+
+.Ltail8x:
+	cmp		\$448,$len
+	jae		.L448_or_more8x
+	cmp		\$384,$len
+	jae		.L384_or_more8x
+	cmp		\$320,$len
+	jae		.L320_or_more8x
+	cmp		\$256,$len
+	jae		.L256_or_more8x
+	cmp		\$192,$len
+	jae		.L192_or_more8x
+	cmp		\$128,$len
+	jae		.L128_or_more8x
+	cmp		\$64,$len
+	jae		.L64_or_more8x
+
+	xor		%r10,%r10
+	vmovdqa		$xa0,0x00(%rsp)
+	vmovdqa		$xb0,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L64_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	je		.Ldone8x
+
+	lea		0x40($inp),$inp		# inp+=64*1
+	xor		%r10,%r10
+	vmovdqa		$xc0,0x00(%rsp)
+	lea		0x40($out),$out		# out+=64*1
+	sub		\$64,$len		# len-=64*1
+	vmovdqa		$xd0,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L128_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	je		.Ldone8x
+
+	lea		0x80($inp),$inp		# inp+=64*2
+	xor		%r10,%r10
+	vmovdqa		$xa1,0x00(%rsp)
+	lea		0x80($out),$out		# out+=64*2
+	sub		\$128,$len		# len-=64*2
+	vmovdqa		$xb1,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L192_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vpxor		0x80($inp),$xa1,$xa1
+	vpxor		0xa0($inp),$xb1,$xb1
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	vmovdqu		$xa1,0x80($out)
+	vmovdqu		$xb1,0xa0($out)
+	je		.Ldone8x
+
+	lea		0xc0($inp),$inp		# inp+=64*3
+	xor		%r10,%r10
+	vmovdqa		$xc1,0x00(%rsp)
+	lea		0xc0($out),$out		# out+=64*3
+	sub		\$192,$len		# len-=64*3
+	vmovdqa		$xd1,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L256_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vpxor		0x80($inp),$xa1,$xa1
+	vpxor		0xa0($inp),$xb1,$xb1
+	vpxor		0xc0($inp),$xc1,$xc1
+	vpxor		0xe0($inp),$xd1,$xd1
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	vmovdqu		$xa1,0x80($out)
+	vmovdqu		$xb1,0xa0($out)
+	vmovdqu		$xc1,0xc0($out)
+	vmovdqu		$xd1,0xe0($out)
+	je		.Ldone8x
+
+	lea		0x100($inp),$inp	# inp+=64*4
+	xor		%r10,%r10
+	vmovdqa		$xa2,0x00(%rsp)
+	lea		0x100($out),$out	# out+=64*4
+	sub		\$256,$len		# len-=64*4
+	vmovdqa		$xb2,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L320_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vpxor		0x80($inp),$xa1,$xa1
+	vpxor		0xa0($inp),$xb1,$xb1
+	vpxor		0xc0($inp),$xc1,$xc1
+	vpxor		0xe0($inp),$xd1,$xd1
+	vpxor		0x100($inp),$xa2,$xa2
+	vpxor		0x120($inp),$xb2,$xb2
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	vmovdqu		$xa1,0x80($out)
+	vmovdqu		$xb1,0xa0($out)
+	vmovdqu		$xc1,0xc0($out)
+	vmovdqu		$xd1,0xe0($out)
+	vmovdqu		$xa2,0x100($out)
+	vmovdqu		$xb2,0x120($out)
+	je		.Ldone8x
+
+	lea		0x140($inp),$inp	# inp+=64*5
+	xor		%r10,%r10
+	vmovdqa		$xc2,0x00(%rsp)
+	lea		0x140($out),$out	# out+=64*5
+	sub		\$320,$len		# len-=64*5
+	vmovdqa		$xd2,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L384_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vpxor		0x80($inp),$xa1,$xa1
+	vpxor		0xa0($inp),$xb1,$xb1
+	vpxor		0xc0($inp),$xc1,$xc1
+	vpxor		0xe0($inp),$xd1,$xd1
+	vpxor		0x100($inp),$xa2,$xa2
+	vpxor		0x120($inp),$xb2,$xb2
+	vpxor		0x140($inp),$xc2,$xc2
+	vpxor		0x160($inp),$xd2,$xd2
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	vmovdqu		$xa1,0x80($out)
+	vmovdqu		$xb1,0xa0($out)
+	vmovdqu		$xc1,0xc0($out)
+	vmovdqu		$xd1,0xe0($out)
+	vmovdqu		$xa2,0x100($out)
+	vmovdqu		$xb2,0x120($out)
+	vmovdqu		$xc2,0x140($out)
+	vmovdqu		$xd2,0x160($out)
+	je		.Ldone8x
+
+	lea		0x180($inp),$inp	# inp+=64*6
+	xor		%r10,%r10
+	vmovdqa		$xa3,0x00(%rsp)
+	lea		0x180($out),$out	# out+=64*6
+	sub		\$384,$len		# len-=64*6
+	vmovdqa		$xb3,0x20(%rsp)
+	jmp		.Loop_tail8x
+
+.align	32
+.L448_or_more8x:
+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
+	vpxor		0x20($inp),$xb0,$xb0
+	vpxor		0x40($inp),$xc0,$xc0
+	vpxor		0x60($inp),$xd0,$xd0
+	vpxor		0x80($inp),$xa1,$xa1
+	vpxor		0xa0($inp),$xb1,$xb1
+	vpxor		0xc0($inp),$xc1,$xc1
+	vpxor		0xe0($inp),$xd1,$xd1
+	vpxor		0x100($inp),$xa2,$xa2
+	vpxor		0x120($inp),$xb2,$xb2
+	vpxor		0x140($inp),$xc2,$xc2
+	vpxor		0x160($inp),$xd2,$xd2
+	vpxor		0x180($inp),$xa3,$xa3
+	vpxor		0x1a0($inp),$xb3,$xb3
+	vmovdqu		$xa0,0x00($out)
+	vmovdqu		$xb0,0x20($out)
+	vmovdqu		$xc0,0x40($out)
+	vmovdqu		$xd0,0x60($out)
+	vmovdqu		$xa1,0x80($out)
+	vmovdqu		$xb1,0xa0($out)
+	vmovdqu		$xc1,0xc0($out)
+	vmovdqu		$xd1,0xe0($out)
+	vmovdqu		$xa2,0x100($out)
+	vmovdqu		$xb2,0x120($out)
+	vmovdqu		$xc2,0x140($out)
+	vmovdqu		$xd2,0x160($out)
+	vmovdqu		$xa3,0x180($out)
+	vmovdqu		$xb3,0x1a0($out)
+	je		.Ldone8x
+
+	lea		0x1c0($inp),$inp	# inp+=64*7
+	xor		%r10,%r10
+	vmovdqa		$xc3,0x00(%rsp)
+	lea		0x1c0($out),$out	# out+=64*7
+	sub		\$448,$len		# len-=64*7
+	vmovdqa		$xd3,0x20(%rsp)
+
+.Loop_tail8x:
+	movzb		($inp,%r10),%eax
+	movzb		(%rsp,%r10),%ecx
+	lea		1(%r10),%r10
+	xor		%ecx,%eax
+	mov		%al,-1($out,%r10)
+	dec		$len
+	jnz		.Loop_tail8x
+
+.Ldone8x:
+	vzeroall
+___
+$code.=<<___	if ($win64);
+	lea		0x290+0x30(%rsp),%r11
+	movaps		-0x30(%r11),%xmm6
+	movaps		-0x20(%r11),%xmm7
+	movaps		-0x10(%r11),%xmm8
+	movaps		0x00(%r11),%xmm9
+	movaps		0x10(%r11),%xmm10
+	movaps		0x20(%r11),%xmm11
+	movaps		0x30(%r11),%xmm12
+	movaps		0x40(%r11),%xmm13
+	movaps		0x50(%r11),%xmm14
+	movaps		0x60(%r11),%xmm15
+___
+$code.=<<___;
+	mov		0x280(%rsp),%rsp
+	ret
+.size	ChaCha20_8x,.-ChaCha20_8x
+___
+}
+
+foreach (split("\n",$code)) {
+	s/\`([^\`]*)\`/eval $1/geo;
+
+	s/%x#%y/%x/go;
+
+	print $_,"\n";
+}
+
+close STDOUT;
diff --git a/src/crypto/chacha/chacha_generic.c b/src/crypto/chacha/chacha.c
similarity index 73%
rename from src/crypto/chacha/chacha_generic.c
rename to src/crypto/chacha/chacha.c
index f262033..afe1b2a 100644
--- a/src/crypto/chacha/chacha_generic.c
+++ b/src/crypto/chacha/chacha.c
@@ -21,7 +21,49 @@
 #include <openssl/cpu.h>
 
 
-#if defined(OPENSSL_WINDOWS) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || !defined(__SSE2__)
+#define U8TO32_LITTLE(p)                              \
+  (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
+   ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24))
+
+#if !defined(OPENSSL_NO_ASM) &&                         \
+    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
+
+/* ChaCha20_ctr32 is defined in asm/chacha-*.pl. */
+void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
+                    const uint32_t key[8], const uint32_t counter[4]);
+
+void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
+                      const uint8_t key[32], const uint8_t nonce[12],
+                      uint32_t counter) {
+  uint32_t counter_nonce[4];
+  counter_nonce[0] = counter;
+  counter_nonce[1] = U8TO32_LITTLE(nonce + 0);
+  counter_nonce[2] = U8TO32_LITTLE(nonce + 4);
+  counter_nonce[3] = U8TO32_LITTLE(nonce + 8);
+
+  const uint32_t *key_ptr = (const uint32_t *)key;
+#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64)
+  /* The assembly expects the key to be four-byte aligned. */
+  uint32_t key_u32[8];
+  if ((((uintptr_t)key) & 3) != 0) {
+    key_u32[0] = U8TO32_LITTLE(key + 0);
+    key_u32[1] = U8TO32_LITTLE(key + 4);
+    key_u32[2] = U8TO32_LITTLE(key + 8);
+    key_u32[3] = U8TO32_LITTLE(key + 12);
+    key_u32[4] = U8TO32_LITTLE(key + 16);
+    key_u32[5] = U8TO32_LITTLE(key + 20);
+    key_u32[6] = U8TO32_LITTLE(key + 24);
+    key_u32[7] = U8TO32_LITTLE(key + 28);
+
+    key_ptr = key_u32;
+  }
+#endif
+
+  ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce);
+}
+
+#else
 
 /* sigma contains the ChaCha constants, which happen to be an ASCII string. */
 static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
@@ -40,10 +82,6 @@
     (p)[3] = (v >> 24) & 0xff; \
   }
 
-#define U8TO32_LITTLE(p)                              \
-  (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
-   ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24))
-
 /* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
 #define QUARTERROUND(a,b,c,d) \
   x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
@@ -51,13 +89,6 @@
   x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
   x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
 
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-/* Defined in chacha_vec.c */
-void CRYPTO_chacha_20_neon(uint8_t *out, const uint8_t *in, size_t in_len,
-                           const uint8_t key[32], const uint8_t nonce[12],
-                           uint32_t counter);
-#endif
-
 /* chacha_core performs 20 rounds of ChaCha on the input words in
  * |input| and writes the 64 output bytes to |output|. */
 static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
@@ -91,13 +122,6 @@
   uint8_t buf[64];
   size_t todo, i;
 
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-  if (CRYPTO_is_NEON_capable()) {
-    CRYPTO_chacha_20_neon(out, in, in_len, key, nonce, counter);
-    return;
-  }
-#endif
-
   input[0] = U8TO32_LITTLE(sigma + 0);
   input[1] = U8TO32_LITTLE(sigma + 4);
   input[2] = U8TO32_LITTLE(sigma + 8);
@@ -137,4 +161,4 @@
   }
 }
 
-#endif /* OPENSSL_WINDOWS || !OPENSSL_X86_64 && !OPENSSL_X86 || !__SSE2__ */
+#endif
diff --git a/src/crypto/chacha/chacha_test.cc b/src/crypto/chacha/chacha_test.cc
new file mode 100644
index 0000000..f364f98
--- /dev/null
+++ b/src/crypto/chacha/chacha_test.cc
@@ -0,0 +1,257 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <memory>
+
+#include <openssl/crypto.h>
+#include <openssl/chacha.h>
+
+
+static const uint8_t kKey[32] = {
+    0x98, 0xbe, 0xf1, 0x46, 0x9b, 0xe7, 0x26, 0x98, 0x37, 0xa4, 0x5b,
+    0xfb, 0xc9, 0x2a, 0x5a, 0x6a, 0xc7, 0x62, 0x50, 0x7c, 0xf9, 0x64,
+    0x43, 0xbf, 0x33, 0xb9, 0x6b, 0x1b, 0xd4, 0xc6, 0xf8, 0xf6,
+};
+
+static const uint8_t kNonce[12] = {
+    0x44, 0xe7, 0x92, 0xd6, 0x33, 0x35, 0xab, 0xb1, 0x58, 0x2e, 0x92, 0x53,
+};
+
+static uint32_t kCounter = 42;
+
+static const uint8_t kInput[] = {
+    0x58, 0x28, 0xd5, 0x30, 0x36, 0x2c, 0x60, 0x55, 0x29, 0xf8, 0xe1, 0x8c,
+    0xae, 0x15, 0x15, 0x26, 0xf2, 0x3a, 0x73, 0xa0, 0xf3, 0x12, 0xa3, 0x88,
+    0x5f, 0x2b, 0x74, 0x23, 0x3d, 0xc9, 0x05, 0x23, 0xc6, 0x54, 0x49, 0x1e,
+    0x44, 0x88, 0x14, 0xd9, 0xda, 0x37, 0x15, 0xdc, 0xb7, 0xe4, 0x23, 0xb3,
+    0x9d, 0x7e, 0x16, 0x68, 0x35, 0xfc, 0x02, 0x6d, 0xcc, 0x8a, 0xe5, 0xdd,
+    0x5f, 0xe4, 0xd2, 0x56, 0x6f, 0x12, 0x9c, 0x9c, 0x7d, 0x6a, 0x38, 0x48,
+    0xbd, 0xdf, 0xd9, 0xac, 0x1b, 0xa2, 0x4d, 0xc5, 0x43, 0x04, 0x3c, 0xd7,
+    0x99, 0xe1, 0xa7, 0x13, 0x9c, 0x51, 0xc2, 0x6d, 0xf9, 0xcf, 0x07, 0x3b,
+    0xe4, 0xbf, 0x93, 0xa3, 0xa9, 0xb4, 0xc5, 0xf0, 0x1a, 0xe4, 0x8d, 0x5f,
+    0xc6, 0xc4, 0x7c, 0x69, 0x7a, 0xde, 0x1a, 0xc1, 0xc9, 0xcf, 0xc2, 0x4e,
+    0x7a, 0x25, 0x2c, 0x32, 0xe9, 0x17, 0xba, 0x68, 0xf1, 0x37, 0x5d, 0x62,
+    0x84, 0x46, 0xf5, 0x80, 0x7f, 0x1a, 0x71, 0xf7, 0xbe, 0x72, 0x4b, 0xb8,
+    0x1c, 0xfe, 0x3e, 0xbd, 0xae, 0x0d, 0x73, 0x0d, 0x87, 0x4a, 0x31, 0xc3,
+    0x3d, 0x46, 0x6f, 0xb3, 0xd7, 0x6b, 0xe3, 0xb8, 0x70, 0x17, 0x8e, 0x7a,
+    0x6a, 0x0e, 0xbf, 0xa8, 0xbc, 0x2b, 0xdb, 0xfa, 0x4f, 0xb6, 0x26, 0x20,
+    0xee, 0x63, 0xf0, 0x6d, 0x26, 0xac, 0x6a, 0x18, 0x37, 0x6e, 0x59, 0x81,
+    0xd1, 0x60, 0xe6, 0x40, 0xd5, 0x6d, 0x68, 0xba, 0x8b, 0x65, 0x4a, 0xf9,
+    0xf1, 0xae, 0x56, 0x24, 0x8f, 0xe3, 0x8e, 0xe7, 0x7e, 0x6f, 0xcf, 0x92,
+    0xdf, 0xa9, 0x75, 0x3a, 0xd6, 0x2e, 0x1c, 0xaf, 0xf2, 0xd6, 0x8b, 0x39,
+    0xad, 0xd2, 0x5d, 0xfb, 0xd7, 0xdf, 0x05, 0x57, 0x0d, 0xf7, 0xf6, 0x8f,
+    0x2d, 0x14, 0xb0, 0x4e, 0x1a, 0x3c, 0x77, 0x04, 0xcd, 0x3c, 0x5c, 0x58,
+    0x52, 0x10, 0x6f, 0xcf, 0x5c, 0x03, 0xc8, 0x5f, 0x85, 0x2b, 0x05, 0x82,
+    0x60, 0xda, 0xcc, 0xcd, 0xd6, 0x88, 0xbf, 0xc0, 0x10, 0xb3, 0x6f, 0x54,
+    0x54, 0x42, 0xbc, 0x4b, 0x77, 0x21, 0x4d, 0xee, 0x87, 0x45, 0x06, 0x4c,
+    0x60, 0x38, 0xd2, 0x7e, 0x1d, 0x30, 0x6c, 0x55, 0xf0, 0x38, 0x80, 0x1c,
+    0xde, 0x3d, 0xea, 0x68, 0x3e, 0xf6, 0x3e, 0x59, 0xcf, 0x0d, 0x08, 0xae,
+    0x8c, 0x02, 0x0b, 0xc1, 0x72, 0x6a, 0xb4, 0x6d, 0xf3, 0xf7, 0xb3, 0xef,
+    0x3a, 0xb1, 0x06, 0xf2, 0xf4, 0xd6, 0x69, 0x7b, 0x3e, 0xa2, 0x16, 0x31,
+    0x31, 0x79, 0xb6, 0x33, 0xa9, 0xca, 0x8a, 0xa8, 0xbe, 0xf3, 0xe9, 0x38,
+    0x28, 0xd1, 0xe1, 0x3b, 0x4e, 0x2e, 0x47, 0x35, 0xa4, 0x61, 0x14, 0x1e,
+    0x42, 0x2c, 0x49, 0x55, 0xea, 0xe3, 0xb3, 0xce, 0x39, 0xd3, 0xb3, 0xef,
+    0x4a, 0x4d, 0x78, 0x49, 0xbd, 0xf6, 0x7c, 0x0a, 0x2c, 0xd3, 0x26, 0xcb,
+    0xd9, 0x6a, 0xad, 0x63, 0x93, 0xa7, 0x29, 0x92, 0xdc, 0x1f, 0xaf, 0x61,
+    0x82, 0x80, 0x74, 0xb2, 0x9c, 0x4a, 0x86, 0x73, 0x50, 0xd8, 0xd1, 0xff,
+    0xee, 0x1a, 0xe2, 0xdd, 0xa2, 0x61, 0xbd, 0x10, 0xc3, 0x5f, 0x67, 0x9f,
+    0x29, 0xe4, 0xd3, 0x70, 0xe5, 0x67, 0x3a, 0xd2, 0x20, 0x00, 0xcc, 0x25,
+    0x15, 0x96, 0x54, 0x45, 0x85, 0xed, 0x82, 0x88, 0x3b, 0x9f, 0x3b, 0xc3,
+    0x04, 0xd4, 0x23, 0xb1, 0x0d, 0xdc, 0xc8, 0x26, 0x9d, 0x28, 0xb3, 0x25,
+    0x4d, 0x52, 0xe5, 0x33, 0xf3, 0xed, 0x2c, 0xb8, 0x1a, 0xcf, 0xc3, 0x52,
+    0xb4, 0x2f, 0xc7, 0x79, 0x96, 0x14, 0x7d, 0x72, 0x27, 0x72, 0x85, 0xea,
+    0x6d, 0x41, 0xa0, 0x22, 0x13, 0x6d, 0x06, 0x83, 0xa4, 0xdd, 0x0f, 0x69,
+    0xd2, 0x01, 0xcd, 0xc6, 0xb8, 0x64, 0x5c, 0x2c, 0x79, 0xd1, 0xc7, 0xd3,
+    0x31, 0xdb, 0x2c, 0xff, 0xda, 0xd0, 0x69, 0x31, 0xad, 0x83, 0x5f, 0xed,
+    0x6a, 0x97, 0xe4, 0x00, 0x43, 0xb0, 0x2e, 0x97, 0xae, 0x00, 0x5f, 0x5c,
+    0xb9, 0xe8, 0x39, 0x80, 0x10, 0xca, 0x0c, 0xfa, 0xf0, 0xb5, 0xcd, 0xaa,
+    0x27, 0x11, 0x60, 0xd9, 0x21, 0x86, 0x93, 0x91, 0x9f, 0x2d, 0x1a, 0x8e,
+    0xde, 0x0b, 0xb5, 0xcb, 0x05, 0x24, 0x30, 0x45, 0x4d, 0x11, 0x75, 0xfd,
+    0xe5, 0xa0, 0xa9, 0x4e, 0x3a, 0x8c, 0x3b, 0x52, 0x5a, 0x37, 0x18, 0x05,
+    0x4a, 0x7a, 0x09, 0x6a, 0xe6, 0xd5, 0xa9, 0xa6, 0x71, 0x47, 0x4c, 0x50,
+    0xe1, 0x3e, 0x8a, 0x21, 0x2b, 0x4f, 0x0e, 0xe3, 0xcb, 0x72, 0xc5, 0x28,
+    0x3e, 0x5a, 0x33, 0xec, 0x48, 0x92, 0x2e, 0xa1, 0x24, 0x57, 0x09, 0x0f,
+    0x01, 0x85, 0x3b, 0x34, 0x39, 0x7e, 0xc7, 0x90, 0x62, 0xe2, 0xdc, 0x5d,
+    0x0a, 0x2c, 0x51, 0x26, 0x95, 0x3a, 0x95, 0x92, 0xa5, 0x39, 0x8f, 0x0c,
+    0x83, 0x0b, 0x9d, 0x38, 0xab, 0x98, 0x2a, 0xc4, 0x01, 0xc4, 0x0d, 0x77,
+    0x13, 0xcb, 0xca, 0xf1, 0x28, 0x31, 0x52, 0x75, 0x27, 0x2c, 0xf0, 0x04,
+    0x86, 0xc8, 0xf3, 0x3d, 0xf2, 0x9d, 0x8f, 0x55, 0x52, 0x40, 0x3f, 0xaa,
+    0x22, 0x7f, 0xe7, 0x69, 0x3b, 0xee, 0x44, 0x09, 0xde, 0xff, 0xb0, 0x69,
+    0x3a, 0xae, 0x74, 0xe9, 0x9d, 0x33, 0xae, 0x8b, 0x6d, 0x60, 0x04, 0xff,
+    0x53, 0x3f, 0x88, 0xe9, 0x63, 0x9b, 0xb1, 0x6d, 0x2c, 0x22, 0x15, 0x5a,
+    0x15, 0xd9, 0xe5, 0xcb, 0x03, 0x78, 0x3c, 0xca, 0x59, 0x8c, 0xc8, 0xc2,
+    0x86, 0xff, 0xd2, 0x79, 0xd6, 0xc6, 0xec, 0x5b, 0xbb, 0xa0, 0xae, 0x01,
+    0x20, 0x09, 0x2e, 0x38, 0x5d, 0xda, 0x5d, 0xe0, 0x59, 0x4e, 0xe5, 0x8b,
+    0x84, 0x8f, 0xb6, 0xe0, 0x56, 0x9f, 0x21, 0xa1, 0xcf, 0xb2, 0x0f, 0x2c,
+    0x93, 0xf8, 0xcf, 0x37, 0xc1, 0x9f, 0x32, 0x98, 0x21, 0x65, 0x52, 0x66,
+    0x6e, 0xd3, 0x71, 0x98, 0x55, 0xb9, 0x46, 0x9f, 0x1a, 0x35, 0xc4, 0x47,
+    0x69, 0x62, 0x70, 0x4b, 0x77, 0x9e, 0xe4, 0x21, 0xe6, 0x32, 0x5a, 0x26,
+    0x05, 0xba, 0x57, 0x53, 0xd7, 0x9b, 0x55, 0x3c, 0xbb, 0x53, 0x79, 0x60,
+    0x9c, 0xc8, 0x4d, 0xf7, 0xf5, 0x1d, 0x54, 0x02, 0x91, 0x68, 0x0e, 0xaa,
+    0xca, 0x5a, 0x78, 0x0c, 0x28, 0x9a, 0xc3, 0xac, 0x49, 0xc0, 0xf4, 0x85,
+    0xee, 0x59, 0x76, 0x7e, 0x28, 0x4e, 0xf1, 0x5c, 0x63, 0xf7, 0xce, 0x0e,
+    0x2c, 0x21, 0xa0, 0x58, 0xe9, 0x01, 0xfd, 0xeb, 0xd1, 0xaf, 0xe6, 0xef,
+    0x93, 0xb3, 0x95, 0x51, 0x60, 0xa2, 0x74, 0x40, 0x15, 0xe5, 0xf4, 0x0a,
+    0xca, 0x6d, 0x9a, 0x37, 0x42, 0x4d, 0x5a, 0x58, 0x49, 0x0f, 0xe9, 0x02,
+    0xfc, 0x77, 0xd8, 0x59, 0xde, 0xdd, 0xad, 0x4b, 0x99, 0x2e, 0x64, 0x73,
+    0xad, 0x42, 0x2f, 0xf3, 0x2c, 0x0d, 0x49, 0xe4, 0x2e, 0x6c, 0xa4, 0x73,
+    0x75, 0x18, 0x14, 0x85, 0xbb, 0x64, 0xb4, 0xa1, 0xb0, 0x6e, 0x01, 0xc0,
+    0xcf, 0x17, 0x9c, 0xc5, 0x28, 0xc3, 0x2d, 0x6c, 0x17, 0x2a, 0x3d, 0x06,
+    0x5c, 0xf3, 0xb4, 0x49, 0x75, 0xad, 0x17, 0x69, 0xd4, 0xca, 0x65, 0xae,
+    0x44, 0x71, 0xa5, 0xf6, 0x0d, 0x0f, 0x8e, 0x37, 0xc7, 0x43, 0xce, 0x6b,
+    0x08, 0xe9, 0xd1, 0x34, 0x48, 0x8f, 0xc9, 0xfc, 0xf3, 0x5d, 0x2d, 0xec,
+    0x62, 0xd3, 0xf0, 0xb3, 0xfe, 0x2e, 0x40, 0x55, 0x76, 0x54, 0xc7, 0xb4,
+    0x61, 0x16, 0xcc, 0x7c, 0x1c, 0x19, 0x24, 0xe6, 0x4d, 0xd4, 0xc3, 0x77,
+    0x67, 0x1f, 0x3c, 0x74, 0x79, 0xa1, 0xf8, 0x85, 0x88, 0x1d, 0x6f, 0xa4,
+    0x7e, 0x2c, 0x21, 0x9f, 0x49, 0xf5, 0xaa, 0x4e, 0xf3, 0x4a, 0xfa, 0x9d,
+    0xbe, 0xf6, 0xce, 0xda, 0xb5, 0xab, 0x39, 0xbd, 0x16, 0x41, 0xa9, 0x4a,
+    0xac, 0x09, 0x01, 0xca,
+};
+static const uint8_t kOutput[] = {
+    0x54, 0x30, 0x6a, 0x13, 0xda, 0x59, 0x6b, 0x6d, 0x59, 0x49, 0xc8, 0xc5,
+    0xab, 0x26, 0xd4, 0x8a, 0xad, 0xc0, 0x3d, 0xaf, 0x14, 0xb9, 0x15, 0xb8,
+    0xca, 0xdf, 0x17, 0xa7, 0x03, 0xd3, 0xc5, 0x06, 0x01, 0xef, 0x21, 0xdd,
+    0xa3, 0x0b, 0x9e, 0x48, 0xb8, 0x5e, 0x0b, 0x87, 0x9f, 0x95, 0x23, 0x68,
+    0x85, 0x69, 0xd2, 0x5d, 0xaf, 0x57, 0xe9, 0x27, 0x11, 0x3d, 0x49, 0xfa,
+    0xf1, 0x08, 0xcc, 0x15, 0xec, 0x1d, 0x19, 0x16, 0x12, 0x9b, 0xc8, 0x66,
+    0x1f, 0xfa, 0x2c, 0x93, 0xf4, 0x99, 0x11, 0x27, 0x31, 0x0e, 0xd8, 0x46,
+    0x47, 0x40, 0x11, 0x70, 0x01, 0xca, 0xe8, 0x5b, 0xc5, 0x91, 0xc8, 0x3a,
+    0xdc, 0xaa, 0xf3, 0x4b, 0x80, 0xe5, 0xbc, 0x03, 0xd0, 0x89, 0x72, 0xbc,
+    0xce, 0x2a, 0x76, 0x0c, 0xf5, 0xda, 0x4c, 0x10, 0x06, 0x35, 0x41, 0xb1,
+    0xe6, 0xb4, 0xaa, 0x7a, 0xef, 0xf0, 0x62, 0x4a, 0xc5, 0x9f, 0x2c, 0xaf,
+    0xb8, 0x2f, 0xd9, 0xd1, 0x01, 0x7a, 0x36, 0x2f, 0x3e, 0x83, 0xa5, 0xeb,
+    0x81, 0x70, 0xa0, 0x57, 0x17, 0x46, 0xea, 0x9e, 0xcb, 0x0e, 0x74, 0xd3,
+    0x44, 0x57, 0x1d, 0x40, 0x06, 0xf8, 0xb7, 0xcb, 0x5f, 0xf4, 0x79, 0xbd,
+    0x11, 0x19, 0xd6, 0xee, 0xf8, 0xb0, 0xaa, 0xdd, 0x00, 0x62, 0xad, 0x3b,
+    0x88, 0x9a, 0x88, 0x5b, 0x1b, 0x07, 0xc9, 0xae, 0x9e, 0xa6, 0x94, 0xe5,
+    0x55, 0xdb, 0x45, 0x23, 0xb9, 0x2c, 0xcd, 0x29, 0xd3, 0x54, 0xc3, 0x88,
+    0x1e, 0x5f, 0x52, 0xf2, 0x09, 0x00, 0x26, 0x26, 0x1a, 0xed, 0xf5, 0xc2,
+    0xa9, 0x7d, 0xf9, 0x21, 0x5a, 0xaf, 0x6d, 0xab, 0x8e, 0x16, 0x84, 0x96,
+    0xb5, 0x4f, 0xcf, 0x1e, 0xa3, 0xaf, 0x08, 0x9f, 0x79, 0x86, 0xc3, 0xbe,
+    0x0c, 0x70, 0xcb, 0x8f, 0xf3, 0xc5, 0xf8, 0xe8, 0x4b, 0x21, 0x7d, 0x18,
+    0xa9, 0xed, 0x8b, 0xfb, 0x6b, 0x5a, 0x6f, 0x26, 0x0b, 0x56, 0x04, 0x7c,
+    0xfe, 0x0e, 0x1e, 0xc1, 0x3f, 0x82, 0xc5, 0x73, 0xbd, 0x53, 0x0c, 0xf0,
+    0xe2, 0xc9, 0xf3, 0x3d, 0x1b, 0x6d, 0xba, 0x70, 0xc1, 0x6d, 0xb6, 0x00,
+    0x28, 0xe1, 0xc4, 0x78, 0x62, 0x04, 0xda, 0x23, 0x86, 0xc3, 0xda, 0x74,
+    0x3d, 0x7c, 0xd6, 0x76, 0x29, 0xb2, 0x27, 0x2e, 0xb2, 0x35, 0x42, 0x60,
+    0x82, 0xcf, 0x30, 0x2c, 0x59, 0xe4, 0xe3, 0xd0, 0x74, 0x1f, 0x58, 0xe8,
+    0xda, 0x47, 0x45, 0x73, 0x1c, 0x05, 0x93, 0xae, 0x75, 0xbe, 0x1f, 0x81,
+    0xd8, 0xb7, 0xb3, 0xff, 0xfc, 0x8b, 0x52, 0x9e, 0xed, 0x8b, 0x37, 0x9f,
+    0xe0, 0xb8, 0xa2, 0x66, 0xe1, 0x6a, 0xc5, 0x1f, 0x1d, 0xf0, 0xde, 0x3f,
+    0x3d, 0xb0, 0x28, 0xf3, 0xaa, 0x4e, 0x4d, 0x31, 0xb0, 0x26, 0x79, 0x2b,
+    0x08, 0x0f, 0xe9, 0x2f, 0x79, 0xb3, 0xc8, 0xdd, 0xa7, 0x89, 0xa8, 0xa8,
+    0x1d, 0x59, 0x0e, 0x4f, 0x1e, 0x93, 0x1f, 0x70, 0x7f, 0x4e, 0x7e, 0xfe,
+    0xb8, 0xca, 0x63, 0xe0, 0xa6, 0x05, 0xcc, 0xd7, 0xde, 0x2a, 0x49, 0x31,
+    0x78, 0x5c, 0x5f, 0x44, 0xb2, 0x9b, 0x91, 0x99, 0x14, 0x29, 0x63, 0x09,
+    0x12, 0xdd, 0x02, 0xd9, 0x7b, 0xe9, 0xf5, 0x12, 0x07, 0xd0, 0xe7, 0xe6,
+    0xe8, 0xdd, 0xda, 0xa4, 0x73, 0xc4, 0x8e, 0xbd, 0x7b, 0xb7, 0xbb, 0xcb,
+    0x83, 0x2f, 0x43, 0xf6, 0x1c, 0x50, 0xae, 0x9b, 0x2e, 0x52, 0x80, 0x18,
+    0x85, 0xa8, 0x23, 0x52, 0x7a, 0x6a, 0xf7, 0x42, 0x36, 0xca, 0x91, 0x5a,
+    0x3d, 0x2a, 0xa0, 0x35, 0x7d, 0x70, 0xfc, 0x4c, 0x18, 0x7c, 0x57, 0x72,
+    0xcf, 0x9b, 0x29, 0xd6, 0xd0, 0xb4, 0xd7, 0xe6, 0x89, 0x70, 0x69, 0x22,
+    0x5e, 0x45, 0x09, 0x4d, 0x49, 0x87, 0x84, 0x5f, 0x8a, 0x5f, 0xe4, 0x15,
+    0xd3, 0xe3, 0x72, 0xaf, 0xb2, 0x30, 0x9c, 0xc1, 0xff, 0x8e, 0x6d, 0x2a,
+    0x76, 0x9e, 0x08, 0x03, 0x7e, 0xe0, 0xc3, 0xc2, 0x97, 0x06, 0x6b, 0x33,
+    0x2b, 0x08, 0xe3, 0xd5, 0x0b, 0xd8, 0x32, 0x67, 0x61, 0x10, 0xed, 0x6b,
+    0xed, 0x50, 0xef, 0xd7, 0x1c, 0x1b, 0xe0, 0x6d, 0xa1, 0x64, 0x19, 0x34,
+    0x2f, 0xe4, 0xe8, 0x54, 0xbf, 0x84, 0x0e, 0xdf, 0x0e, 0x8b, 0xd8, 0xdd,
+    0x77, 0x96, 0xb8, 0x54, 0xab, 0xf2, 0x95, 0x59, 0x0d, 0x0d, 0x0a, 0x15,
+    0x6e, 0x01, 0xf2, 0x24, 0xab, 0xa0, 0xd8, 0xdf, 0x38, 0xea, 0x97, 0x58,
+    0x76, 0x88, 0xbe, 0xaf, 0x45, 0xe3, 0x56, 0x4f, 0x68, 0xe8, 0x4b, 0xe7,
+    0x2b, 0x22, 0x18, 0x96, 0x82, 0x89, 0x25, 0x34, 0xd1, 0xdd, 0x08, 0xea,
+    0x7e, 0x21, 0xef, 0x57, 0x55, 0x43, 0xf7, 0xfa, 0xca, 0x1c, 0xde, 0x99,
+    0x2e, 0x8b, 0xd8, 0xc3, 0xcf, 0x89, 0x4d, 0xfc, 0x3b, 0x7d, 0x4a, 0xc9,
+    0x99, 0xc4, 0x31, 0xb6, 0x7a, 0xae, 0xf8, 0x49, 0xb2, 0x46, 0xc1, 0x60,
+    0x05, 0x75, 0xf3, 0x3d, 0xf2, 0xc9, 0x84, 0xa4, 0xb9, 0x8a, 0x87, 0x2a,
+    0x87, 0x5c, 0x0a, 0xbc, 0x51, 0x7d, 0x9a, 0xf5, 0xc9, 0x24, 0x2d, 0x5e,
+    0xe6, 0xc6, 0xe3, 0xcd, 0x7e, 0xe4, 0xaf, 0x8a, 0x6c, 0x00, 0x04, 0xc8,
+    0xd7, 0xa5, 0xad, 0xfa, 0xb2, 0x08, 0x4a, 0x26, 0x9b, 0x7c, 0xd0, 0xc6,
+    0x13, 0xb1, 0xb9, 0x65, 0x3f, 0x70, 0x30, 0xf9, 0x98, 0x9d, 0x87, 0x99,
+    0x57, 0x71, 0x3e, 0xb1, 0xc3, 0x24, 0xf0, 0xa6, 0xa2, 0x60, 0x9d, 0x66,
+    0xd2, 0x5f, 0xae, 0xe3, 0x94, 0x87, 0xea, 0xd1, 0xea, 0x0d, 0x2a, 0x77,
+    0xef, 0x31, 0xcc, 0xeb, 0xf9, 0x0c, 0xdc, 0x9c, 0x12, 0x80, 0xbb, 0xb0,
+    0x8e, 0xab, 0x9a, 0x04, 0xcd, 0x4b, 0x95, 0x4f, 0x7a, 0x0b, 0x53, 0x7c,
+    0x16, 0xcc, 0x0e, 0xb1, 0x73, 0x10, 0xdd, 0xaa, 0x76, 0x94, 0x90, 0xd9,
+    0x8b, 0x66, 0x41, 0x31, 0xed, 0x8c, 0x7d, 0x74, 0xc4, 0x33, 0xfa, 0xc3,
+    0x43, 0x8d, 0x10, 0xbc, 0x84, 0x4d, 0x0e, 0x95, 0x32, 0xdf, 0x17, 0x43,
+    0x6d, 0xd2, 0x5e, 0x12, 0xb9, 0xed, 0x33, 0xd9, 0x97, 0x6f, 0x4a, 0xcd,
+    0xc3, 0xcd, 0x81, 0x34, 0xbe, 0x7e, 0xa2, 0xd0, 0xa7, 0x91, 0x5d, 0x90,
+    0xf6, 0x5e, 0x4a, 0x25, 0x0f, 0xcc, 0x24, 0xeb, 0xe1, 0xe4, 0x62, 0x6c,
+    0x8f, 0x45, 0x36, 0x97, 0x5d, 0xda, 0x20, 0x2b, 0x86, 0x00, 0x8c, 0x94,
+    0xa9, 0x6a, 0x69, 0xb2, 0xe9, 0xbb, 0x82, 0x8e, 0x41, 0x95, 0xb4, 0xb7,
+    0xf1, 0x55, 0x52, 0x30, 0x39, 0x48, 0xb3, 0x25, 0x82, 0xa9, 0x10, 0x27,
+    0x89, 0xb5, 0xe5, 0x1f, 0xab, 0x72, 0x3c, 0x70, 0x08, 0xce, 0xe6, 0x61,
+    0xbf, 0x19, 0xc8, 0x90, 0x2b, 0x29, 0x30, 0x3e, 0xb8, 0x4c, 0x33, 0xf0,
+    0xf0, 0x15, 0x2e, 0xb7, 0x25, 0xca, 0x99, 0x4b, 0x6f, 0x4b, 0x41, 0x50,
+    0xee, 0x56, 0x99, 0xcf, 0x2b, 0xa4, 0xc4, 0x7c, 0x5c, 0xa6, 0xd4, 0x67,
+    0x04, 0x5c, 0x5d, 0x5f, 0x26, 0x9e, 0x0f, 0xe2, 0x58, 0x68, 0x4c, 0x30,
+    0xcd, 0xef, 0x46, 0xdb, 0x37, 0x6f, 0xbb, 0xc4, 0x80, 0xca, 0x8a, 0x54,
+    0x5d, 0x71, 0x9d, 0x0c, 0xe8, 0xb8, 0x2c, 0x10, 0x90, 0x44, 0xa4, 0x88,
+    0x3f, 0xbc, 0x15, 0x3c, 0xd2, 0xca, 0x0e, 0xc3, 0xe4, 0x6e, 0xef, 0xb0,
+    0xcb, 0xfd, 0x61, 0x7c, 0x27, 0xf2, 0x25, 0xea, 0x71, 0x6d, 0xf7, 0x49,
+    0x9c, 0x81, 0x27, 0xf0, 0x61, 0x33, 0xcf, 0x55, 0x68, 0xd3, 0x73, 0xa4,
+    0xed, 0x35, 0x65, 0x2a, 0xf2, 0x3e, 0xcf, 0x90, 0x98, 0x54, 0x6d, 0x95,
+    0x6a, 0x0c, 0x9c, 0x24, 0x0e, 0xb4, 0xb7, 0x9b, 0x8d, 0x6e, 0x1c, 0xbc,
+    0xeb, 0x17, 0x10, 0x86, 0xda, 0x91, 0x6d, 0x89, 0x4c, 0xeb, 0xf5, 0x50,
+    0x8f, 0x40, 0xcf, 0x4a,
+};
+
+static_assert(sizeof(kInput) == sizeof(kOutput),
+              "Input and output lengths don't match.");
+
+static bool TestChaCha20(size_t len) {
+  std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
+  CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kCounter);
+  if (memcmp(buf.get(), kOutput, len) != 0) {
+    fprintf(stderr, "Mismatch at length %u.\n", static_cast<unsigned>(len));
+    return false;
+  }
+
+  // Test in-place at various offsets.
+  static const size_t kOffsets[] = {
+      0,  1,  2,  8,  15, 16,  17,  31,  32,  33,  63,
+      64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+  };
+  for (size_t offset : kOffsets) {
+    buf.reset(new uint8_t[len + offset]);
+    memcpy(buf.get() + offset, kInput, len);
+    CRYPTO_chacha_20(buf.get(), buf.get() + offset, len, kKey, kNonce,
+                     kCounter);
+    if (memcmp(buf.get(), kOutput, len) != 0) {
+      fprintf(stderr, "Mismatch at length %u with in-place offset %u.\n",
+              static_cast<unsigned>(len), static_cast<unsigned>(offset));
+      return false;
+    }
+  }
+
+  return true;
+}
+
+int main(int argc, char **argv) {
+  CRYPTO_library_init();
+
+  // Run the test with the test vector at all lengths.
+  for (size_t len = 0; len <= sizeof(kInput); len++) {
+    if (!TestChaCha20(len)) {
+      return 1;
+    }
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/chacha/chacha_vec.c b/src/crypto/chacha/chacha_vec.c
deleted file mode 100644
index addbaa3..0000000
--- a/src/crypto/chacha/chacha_vec.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-/* ====================================================================
- *
- * When updating this file, also update chacha_vec_arm.S
- *
- * ==================================================================== */
-
-
-/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
- * marked as public domain. It was been altered to allow for non-aligned inputs
- * and to allow the block counter to be passed in specifically. */
-
-#include <openssl/chacha.h>
-
-#if defined(ASM_GEN) ||          \
-    !defined(OPENSSL_WINDOWS) && \
-        (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) && defined(__SSE2__)
-
-#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
-
-/* Architecture-neutral way to specify 16-byte vector of ints              */
-typedef unsigned vec __attribute__((vector_size(16)));
-
-/* This implementation is designed for Neon, SSE and AltiVec machines. The
- * following specify how to do certain vector operations efficiently on
- * each architecture, using intrinsics.
- * This implementation supports parallel processing of multiple blocks,
- * including potentially using general-purpose registers. */
-#if __ARM_NEON__
-#include <string.h>
-#include <arm_neon.h>
-#define GPR_TOO 1
-#define VBPI 2
-#define ONE (vec) vsetq_lane_u32(1, vdupq_n_u32(0), 0)
-#define LOAD_ALIGNED(m) (vec)(*((vec *)(m)))
-#define LOAD(m) ({ \
-    memcpy(alignment_buffer, m, 16); \
-    LOAD_ALIGNED(alignment_buffer); \
-  })
-#define STORE(m, r) ({ \
-    (*((vec *)(alignment_buffer))) = (r); \
-    memcpy(m, alignment_buffer, 16); \
-  })
-#define ROTV1(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 1)
-#define ROTV2(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 2)
-#define ROTV3(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 3)
-#define ROTW16(x) (vec) vrev32q_u16((uint16x8_t)x)
-#if __clang__
-#define ROTW7(x) (x << ((vec) {7, 7, 7, 7})) ^ (x >> ((vec) {25, 25, 25, 25}))
-#define ROTW8(x) (x << ((vec) {8, 8, 8, 8})) ^ (x >> ((vec) {24, 24, 24, 24}))
-#define ROTW12(x) \
-  (x << ((vec) {12, 12, 12, 12})) ^ (x >> ((vec) {20, 20, 20, 20}))
-#else
-#define ROTW7(x) \
-  (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 7), (uint32x4_t)x, 25)
-#define ROTW8(x) \
-  (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 8), (uint32x4_t)x, 24)
-#define ROTW12(x) \
-  (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 12), (uint32x4_t)x, 20)
-#endif
-#elif __SSE2__
-#include <emmintrin.h>
-#define GPR_TOO 0
-#if __clang__
-#define VBPI 4
-#else
-#define VBPI 3
-#endif
-#define ONE (vec) _mm_set_epi32(0, 0, 0, 1)
-#define LOAD(m) (vec) _mm_loadu_si128((__m128i *)(m))
-#define LOAD_ALIGNED(m) (vec) _mm_load_si128((__m128i *)(m))
-#define STORE(m, r) _mm_storeu_si128((__m128i *)(m), (__m128i)(r))
-#define ROTV1(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(0, 3, 2, 1))
-#define ROTV2(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(1, 0, 3, 2))
-#define ROTV3(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(2, 1, 0, 3))
-#define ROTW7(x) \
-  (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x, 25))
-#define ROTW12(x) \
-  (vec)(_mm_slli_epi32((__m128i)x, 12) ^ _mm_srli_epi32((__m128i)x, 20))
-#if __SSSE3__
-#include <tmmintrin.h>
-#define ROTW8(x)                                                            \
-  (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, \
-                                                  11, 6, 5, 4, 7, 2, 1, 0, 3))
-#define ROTW16(x)                                                           \
-  (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, \
-                                                  10, 5, 4, 7, 6, 1, 0, 3, 2))
-#else
-#define ROTW8(x) \
-  (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x, 24))
-#define ROTW16(x) \
-  (vec)(_mm_slli_epi32((__m128i)x, 16) ^ _mm_srli_epi32((__m128i)x, 16))
-#endif
-#else
-#error-- Implementation supports only machines with neon or SSE2
-#endif
-
-#ifndef REVV_BE
-#define REVV_BE(x)  (x)
-#endif
-
-#ifndef REVW_BE
-#define REVW_BE(x)  (x)
-#endif
-
-#define BPI      (VBPI + GPR_TOO)  /* Blocks computed per loop iteration   */
-
-#define DQROUND_VECTORS(a,b,c,d)                \
-    a += b; d ^= a; d = ROTW16(d);              \
-    c += d; b ^= c; b = ROTW12(b);              \
-    a += b; d ^= a; d = ROTW8(d);               \
-    c += d; b ^= c; b = ROTW7(b);               \
-    b = ROTV1(b); c = ROTV2(c);  d = ROTV3(d);  \
-    a += b; d ^= a; d = ROTW16(d);              \
-    c += d; b ^= c; b = ROTW12(b);              \
-    a += b; d ^= a; d = ROTW8(d);               \
-    c += d; b ^= c; b = ROTW7(b);               \
-    b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
-
-#define QROUND_WORDS(a,b,c,d) \
-  a = a+b; d ^= a; d = d<<16 | d>>16; \
-  c = c+d; b ^= c; b = b<<12 | b>>20; \
-  a = a+b; d ^= a; d = d<< 8 | d>>24; \
-  c = c+d; b ^= c; b = b<< 7 | b>>25;
-
-#define WRITE_XOR(in, op, d, v0, v1, v2, v3)                   \
-	STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0));      \
-	STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1));      \
-	STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2));      \
-	STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
-
-#if __ARM_NEON__
-/* For ARM, we can't depend on NEON support, so this function is compiled with
- * a different name, along with the generic code, and can be enabled at
- * run-time. */
-void CRYPTO_chacha_20_neon(
-#else
-void CRYPTO_chacha_20(
-#endif
-	uint8_t *out,
-	const uint8_t *in,
-	size_t inlen,
-	const uint8_t key[32],
-	const uint8_t nonce[12],
-	uint32_t counter)
-	{
-	unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
-#if defined(__ARM_NEON__)
-	uint32_t np[3];
-	uint8_t alignment_buffer[16] __attribute__((aligned(16)));
-#endif
-	vec s0, s1, s2, s3;
-	__attribute__ ((aligned (16))) unsigned chacha_const[] =
-		{0x61707865,0x3320646E,0x79622D32,0x6B206574};
-	kp = (unsigned *)key;
-#if defined(__ARM_NEON__)
-	memcpy(np, nonce, 12);
-#endif
-	s0 = LOAD_ALIGNED(chacha_const);
-	s1 = LOAD(&((vec*)kp)[0]);
-	s2 = LOAD(&((vec*)kp)[1]);
-	s3 = (vec){
-		counter,
-		((uint32_t*)nonce)[0],
-		((uint32_t*)nonce)[1],
-		((uint32_t*)nonce)[2]
-	};
-
-	for (iters = 0; iters < inlen/(BPI*64); iters++)
-		{
-#if GPR_TOO
-		register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
-				  x9, x10, x11, x12, x13, x14, x15;
-#endif
-#if VBPI > 2
-		vec v8,v9,v10,v11;
-#endif
-#if VBPI > 3
-		vec v12,v13,v14,v15;
-#endif
-
-		vec v0,v1,v2,v3,v4,v5,v6,v7;
-		v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
-		v7 = v3 + ONE;
-#if VBPI > 2
-		v8 = v4; v9 = v5; v10 = v6;
-		v11 =  v7 + ONE;
-#endif
-#if VBPI > 3
-		v12 = v8; v13 = v9; v14 = v10;
-		v15 = v11 + ONE;
-#endif
-#if GPR_TOO
-		x0 = chacha_const[0]; x1 = chacha_const[1];
-		x2 = chacha_const[2]; x3 = chacha_const[3];
-		x4 = kp[0]; x5 = kp[1]; x6  = kp[2]; x7  = kp[3];
-		x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
-		x12 = counter+BPI*iters+(BPI-1); x13 = np[0];
-		x14 = np[1]; x15 = np[2];
-#endif
-		for (i = CHACHA_RNDS/2; i; i--)
-			{
-			DQROUND_VECTORS(v0,v1,v2,v3)
-			DQROUND_VECTORS(v4,v5,v6,v7)
-#if VBPI > 2
-			DQROUND_VECTORS(v8,v9,v10,v11)
-#endif
-#if VBPI > 3
-			DQROUND_VECTORS(v12,v13,v14,v15)
-#endif
-#if GPR_TOO
-			QROUND_WORDS( x0, x4, x8,x12)
-			QROUND_WORDS( x1, x5, x9,x13)
-			QROUND_WORDS( x2, x6,x10,x14)
-			QROUND_WORDS( x3, x7,x11,x15)
-			QROUND_WORDS( x0, x5,x10,x15)
-			QROUND_WORDS( x1, x6,x11,x12)
-			QROUND_WORDS( x2, x7, x8,x13)
-			QROUND_WORDS( x3, x4, x9,x14)
-#endif
-			}
-
-		WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
-		s3 += ONE;
-		WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
-		s3 += ONE;
-#if VBPI > 2
-		WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
-		s3 += ONE;
-#endif
-#if VBPI > 3
-		WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
-		s3 += ONE;
-#endif
-		ip += VBPI*16;
-		op += VBPI*16;
-#if GPR_TOO
-		op[0]  = REVW_BE(REVW_BE(ip[0])  ^ (x0  + chacha_const[0]));
-		op[1]  = REVW_BE(REVW_BE(ip[1])  ^ (x1  + chacha_const[1]));
-		op[2]  = REVW_BE(REVW_BE(ip[2])  ^ (x2  + chacha_const[2]));
-		op[3]  = REVW_BE(REVW_BE(ip[3])  ^ (x3  + chacha_const[3]));
-		op[4]  = REVW_BE(REVW_BE(ip[4])  ^ (x4  + kp[0]));
-		op[5]  = REVW_BE(REVW_BE(ip[5])  ^ (x5  + kp[1]));
-		op[6]  = REVW_BE(REVW_BE(ip[6])  ^ (x6  + kp[2]));
-		op[7]  = REVW_BE(REVW_BE(ip[7])  ^ (x7  + kp[3]));
-		op[8]  = REVW_BE(REVW_BE(ip[8])  ^ (x8  + kp[4]));
-		op[9]  = REVW_BE(REVW_BE(ip[9])  ^ (x9  + kp[5]));
-		op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
-		op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
-		op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter+BPI*iters+(BPI-1)));
-		op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
-		op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
-		op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
-		s3 += ONE;
-		ip += 16;
-		op += 16;
-#endif
-		}
-
-	for (iters = inlen%(BPI*64)/64; iters != 0; iters--)
-		{
-		vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
-		for (i = CHACHA_RNDS/2; i; i--)
-			{
-			DQROUND_VECTORS(v0,v1,v2,v3);
-			}
-		WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
-		s3 += ONE;
-		ip += 16;
-		op += 16;
-		}
-
-	inlen = inlen % 64;
-	if (inlen)
-		{
-		__attribute__ ((aligned (16))) vec buf[4];
-		vec v0,v1,v2,v3;
-		v0 = s0; v1 = s1; v2 = s2; v3 = s3;
-		for (i = CHACHA_RNDS/2; i; i--)
-			{
-			DQROUND_VECTORS(v0,v1,v2,v3);
-			}
-
-		if (inlen >= 16)
-			{
-			STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
-			if (inlen >= 32)
-				{
-				STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
-				if (inlen >= 48)
-					{
-					STORE(op + 8, LOAD(ip +  8) ^
-						      REVV_BE(v2 + s2));
-					buf[3] = REVV_BE(v3 + s3);
-					}
-				else
-					buf[2] = REVV_BE(v2 + s2);
-				}
-			else
-				buf[1] = REVV_BE(v1 + s1);
-			}
-		else
-			buf[0] = REVV_BE(v0 + s0);
-
-		for (i=inlen & ~15; i<inlen; i++)
-			((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
-		}
-	}
-
-#endif /* ASM_GEN || !OPENSSL_WINDOWS && (OPENSSL_X86_64 || OPENSSL_X86) && SSE2 */
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
deleted file mode 100644
index f18c867..0000000
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ /dev/null
@@ -1,1447 +0,0 @@
-# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-# This file contains a pre-compiled version of chacha_vec.c for ARM. This is
-# needed to support switching on NEON code at runtime. If the whole of OpenSSL
-# were to be compiled with the needed flags to build chacha_vec.c, then it
-# wouldn't be possible to run on non-NEON systems.
-#
-# This file was generated by chacha_vec_arm_generate.go using the following
-# compiler command:
-#
-#     /opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a8 -mfpu=neon -fpic -DASM_GEN -I ../../include -S chacha_vec.c -o -
-
-#if !defined(OPENSSL_NO_ASM)
-#if defined(__arm__)
-
-	.syntax unified
-	.cpu cortex-a8
-	.eabi_attribute 27, 3
-
-# EABI attribute 28 sets whether VFP register arguments were used to build this
-# file. If object files are inconsistent on this point, the linker will refuse
-# to link them. Thus we report whatever the compiler expects since we don't use
-# VFP arguments.
-
-#if defined(__ARM_PCS_VFP)
-	.eabi_attribute 28, 1
-#else
-	.eabi_attribute 28, 0
-#endif
-
-	.fpu neon
-	.eabi_attribute 20, 1
-	.eabi_attribute 21, 1
-	.eabi_attribute 23, 3
-	.eabi_attribute 24, 1
-	.eabi_attribute 25, 1
-	.eabi_attribute 26, 2
-	.eabi_attribute 30, 2
-	.eabi_attribute 34, 1
-	.eabi_attribute 18, 4
-	.thumb
-	.file	"chacha_vec.c"
-	.text
-	.align	2
-	.global	CRYPTO_chacha_20_neon
-	.hidden	CRYPTO_chacha_20_neon
-	.thumb
-	.thumb_func
-	.type	CRYPTO_chacha_20_neon, %function
-CRYPTO_chacha_20_neon:
-	@ args = 8, pretend = 0, frame = 160
-	@ frame_needed = 1, uses_anonymous_args = 0
-	push	{r4, r5, r6, r7, r8, r9, r10, fp, lr}
-	mov	r9, r3
-	vpush.64	{d8, d9, d10, d11, d12, d13, d14, d15}
-	mov	r10, r2
-	ldr	r4, .L91+16
-	mov	fp, r1
-	mov	r8, r9
-.LPIC16:
-	add	r4, pc
-	sub	sp, sp, #164
-	add	r7, sp, #0
-	sub	sp, sp, #112
-	add	lr, r7, #148
-	str	r0, [r7, #80]
-	str	r1, [r7, #12]
-	str	r2, [r7, #8]
-	ldmia	r4, {r0, r1, r2, r3}
-	add	r4, sp, #15
-	bic	r4, r4, #15
-	ldr	r6, [r7, #264]
-	str	r4, [r7, #88]
-	mov	r5, r4
-	adds	r4, r4, #64
-	add	ip, r5, #80
-	str	r9, [r7, #56]
-	stmia	r4, {r0, r1, r2, r3}
-	movw	r4, #43691
-	ldr	r0, [r6]	@ unaligned
-	movt	r4, 43690
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r3, [r9, #12]	@ unaligned
-	str	ip, [r7, #84]
-	stmia	lr!, {r0, r1, r2}
-	mov	lr, ip
-	ldr	r1, [r9, #4]	@ unaligned
-	ldr	r2, [r9, #8]	@ unaligned
-	ldr	r0, [r9]	@ unaligned
-	vldr	d24, [r5, #64]
-	vldr	d25, [r5, #72]
-	umull	r4, r5, r10, r4
-	stmia	ip!, {r0, r1, r2, r3}
-	ldr	r0, [r8, #16]!	@ unaligned
-	ldr	r2, [r7, #88]
-	ldr	r4, [r7, #268]
-	ldr	r1, [r8, #4]	@ unaligned
-	vldr	d26, [r2, #80]
-	vldr	d27, [r2, #88]
-	ldr	r3, [r8, #12]	@ unaligned
-	ldr	r2, [r8, #8]	@ unaligned
-	stmia	lr!, {r0, r1, r2, r3}
-	ldr	r3, [r6]
-	ldr	r1, [r6, #4]
-	ldr	r6, [r6, #8]
-	str	r3, [r7, #68]
-	str	r3, [r7, #132]
-	lsrs	r3, r5, #7
-	str	r6, [r7, #140]
-	str	r6, [r7, #60]
-	ldr	r6, [r7, #88]
-	str	r4, [r7, #128]
-	str	r1, [r7, #136]
-	str	r1, [r7, #64]
-	vldr	d28, [r6, #80]
-	vldr	d29, [r6, #88]
-	vldr	d22, [r7, #128]
-	vldr	d23, [r7, #136]
-	beq	.L26
-	mov	r5, r6
-	lsls	r2, r3, #8
-	sub	r3, r2, r3, lsl #6
-	ldr	r2, [r5, #68]
-	ldr	r6, [r6, #64]
-	vldr	d0, .L91
-	vldr	d1, .L91+8
-	str	r2, [r7, #48]
-	ldr	r2, [r5, #72]
-	str	r3, [r7, #4]
-	str	r6, [r7, #52]
-	str	r2, [r7, #44]
-	adds	r2, r4, #2
-	str	r2, [r7, #72]
-	ldr	r2, [r5, #76]
-	str	fp, [r7, #76]
-	str	r2, [r7, #40]
-	ldr	r2, [r7, #80]
-	adds	r3, r2, r3
-	str	r3, [r7, #16]
-.L4:
-	ldr	r5, [r7, #56]
-	add	r8, r7, #40
-	ldr	r4, [r7, #68]
-	vadd.i32	q3, q11, q0
-	ldmia	r8, {r8, r9, r10, fp}
-	mov	r1, r5
-	ldr	r2, [r5, #4]
-	vmov	q8, q14  @ v4si
-	ldr	r3, [r5]
-	vmov	q1, q13  @ v4si
-	ldr	r6, [r1, #28]
-	vmov	q9, q12  @ v4si
-	mov	r0, r2
-	ldr	r2, [r5, #8]
-	str	r4, [r7, #112]
-	movs	r1, #10
-	ldr	r4, [r7, #72]
-	vmov	q2, q11  @ v4si
-	ldr	lr, [r5, #20]
-	vmov	q15, q14  @ v4si
-	str	r3, [r7, #108]
-	vmov	q5, q13  @ v4si
-	str	r2, [r7, #116]
-	vmov	q10, q12  @ v4si
-	ldr	r2, [r5, #12]
-	ldr	ip, [r5, #16]
-	ldr	r3, [r7, #64]
-	ldr	r5, [r5, #24]
-	str	r6, [r7, #120]
-	str	r1, [r7, #92]
-	ldr	r6, [r7, #60]
-	str	r4, [r7, #100]
-	ldr	r1, [r7, #116]
-	ldr	r4, [r7, #108]
-	str	r8, [r7, #96]
-	mov	r8, r10
-	str	lr, [r7, #104]
-	mov	r10, r9
-	mov	lr, r3
-	mov	r9, r5
-	str	r6, [r7, #124]
-	b	.L92
-.L93:
-	.align	3
-.L91:
-	.word	1
-	.word	0
-	.word	0
-	.word	0
-	.word	.LANCHOR0-(.LPIC16+4)
-.L92:
-.L3:
-	vadd.i32	q9, q9, q1
-	add	r3, r8, r0
-	vadd.i32	q10, q10, q5
-	add	r5, fp, r4
-	veor	q3, q3, q9
-	mov	r6, r3
-	veor	q2, q2, q10
-	ldr	r3, [r7, #96]
-	str	r5, [r7, #116]
-	add	r10, r10, r1
-	vrev32.16	q3, q3
-	str	r6, [r7, #108]
-	vadd.i32	q8, q8, q3
-	vrev32.16	q2, q2
-	vadd.i32	q15, q15, q2
-	mov	fp, r3
-	ldr	r3, [r7, #100]
-	veor	q4, q8, q1
-	veor	q6, q15, q5
-	add	fp, fp, r2
-	eors	r3, r3, r5
-	mov	r5, r6
-	ldr	r6, [r7, #112]
-	vshl.i32	q1, q4, #12
-	vshl.i32	q5, q6, #12
-	ror	r3, r3, #16
-	eors	r6, r6, r5
-	eor	lr, lr, r10
-	vsri.32	q1, q4, #20
-	mov	r5, r6
-	ldr	r6, [r7, #124]
-	vsri.32	q5, q6, #20
-	str	r3, [r7, #124]
-	eor	r6, r6, fp
-	ror	r5, r5, #16
-	vadd.i32	q9, q9, q1
-	ror	lr, lr, #16
-	ror	r3, r6, #16
-	ldr	r6, [r7, #124]
-	vadd.i32	q10, q10, q5
-	add	r9, r9, lr
-	veor	q4, q9, q3
-	add	ip, ip, r6
-	ldr	r6, [r7, #104]
-	veor	q6, q10, q2
-	eor	r4, ip, r4
-	str	r3, [r7, #104]
-	vshl.i32	q3, q4, #8
-	eor	r1, r9, r1
-	mov	r8, r6
-	ldr	r6, [r7, #120]
-	vshl.i32	q2, q6, #8
-	ror	r4, r4, #20
-	add	r6, r6, r3
-	vsri.32	q3, q4, #24
-	str	r6, [r7, #100]
-	eors	r2, r2, r6
-	ldr	r6, [r7, #116]
-	vsri.32	q2, q6, #24
-	add	r8, r8, r5
-	ror	r2, r2, #20
-	adds	r6, r4, r6
-	vadd.i32	q4, q8, q3
-	eor	r0, r8, r0
-	vadd.i32	q15, q15, q2
-	mov	r3, r6
-	ldr	r6, [r7, #108]
-	veor	q6, q4, q1
-	ror	r0, r0, #20
-	str	r3, [r7, #112]
-	veor	q5, q15, q5
-	adds	r6, r0, r6
-	str	r6, [r7, #120]
-	mov	r6, r3
-	ldr	r3, [r7, #124]
-	vshl.i32	q8, q6, #7
-	add	fp, fp, r2
-	eors	r3, r3, r6
-	ldr	r6, [r7, #120]
-	vshl.i32	q1, q5, #7
-	ror	r1, r1, #20
-	eors	r5, r5, r6
-	vsri.32	q8, q6, #25
-	ldr	r6, [r7, #104]
-	ror	r3, r3, #24
-	ror	r5, r5, #24
-	vsri.32	q1, q5, #25
-	str	r5, [r7, #116]
-	eor	r6, fp, r6
-	ldr	r5, [r7, #116]
-	add	r10, r10, r1
-	add	ip, r3, ip
-	vext.32	q8, q8, q8, #1
-	str	ip, [r7, #124]
-	add	ip, r5, r8
-	ldr	r5, [r7, #100]
-	eor	lr, r10, lr
-	ror	r6, r6, #24
-	vext.32	q1, q1, q1, #1
-	add	r8, r6, r5
-	vadd.i32	q9, q9, q8
-	ldr	r5, [r7, #124]
-	vext.32	q3, q3, q3, #3
-	vadd.i32	q10, q10, q1
-	ror	lr, lr, #24
-	eor	r0, ip, r0
-	vext.32	q2, q2, q2, #3
-	add	r9, r9, lr
-	eors	r4, r4, r5
-	veor	q3, q9, q3
-	ldr	r5, [r7, #112]
-	eor	r1, r9, r1
-	ror	r0, r0, #25
-	veor	q2, q10, q2
-	adds	r5, r0, r5
-	vext.32	q4, q4, q4, #2
-	str	r5, [r7, #112]
-	ldr	r5, [r7, #120]
-	ror	r1, r1, #25
-	vrev32.16	q3, q3
-	eor	r2, r8, r2
-	vext.32	q15, q15, q15, #2
-	adds	r5, r1, r5
-	vadd.i32	q4, q4, q3
-	ror	r4, r4, #25
-	vrev32.16	q2, q2
-	str	r5, [r7, #100]
-	vadd.i32	q15, q15, q2
-	eors	r3, r3, r5
-	ldr	r5, [r7, #112]
-	add	fp, fp, r4
-	veor	q8, q4, q8
-	ror	r2, r2, #25
-	veor	q1, q15, q1
-	eor	lr, fp, lr
-	eors	r6, r6, r5
-	ror	r3, r3, #16
-	ldr	r5, [r7, #116]
-	add	r10, r10, r2
-	str	r3, [r7, #120]
-	ror	lr, lr, #16
-	ldr	r3, [r7, #120]
-	eor	r5, r10, r5
-	vshl.i32	q5, q8, #12
-	add	ip, lr, ip
-	vshl.i32	q6, q1, #12
-	str	ip, [r7, #104]
-	add	ip, r3, r8
-	str	ip, [r7, #116]
-	ldr	r3, [r7, #124]
-	ror	r5, r5, #16
-	vsri.32	q5, q8, #20
-	ror	r6, r6, #16
-	add	ip, r5, r3
-	ldr	r3, [r7, #104]
-	vsri.32	q6, q1, #20
-	add	r9, r9, r6
-	eor	r2, ip, r2
-	eors	r4, r4, r3
-	ldr	r3, [r7, #116]
-	eor	r0, r9, r0
-	vadd.i32	q9, q9, q5
-	ror	r4, r4, #20
-	eors	r1, r1, r3
-	vadd.i32	q10, q10, q6
-	ror	r3, r2, #20
-	str	r3, [r7, #108]
-	ldr	r3, [r7, #112]
-	veor	q3, q9, q3
-	ror	r0, r0, #20
-	add	r8, r4, fp
-	veor	q2, q10, q2
-	add	fp, r0, r3
-	ldr	r3, [r7, #100]
-	ror	r1, r1, #20
-	mov	r2, r8
-	vshl.i32	q8, q3, #8
-	str	r8, [r7, #96]
-	add	r8, r1, r3
-	ldr	r3, [r7, #108]
-	vmov	q1, q6  @ v4si
-	vshl.i32	q6, q2, #8
-	eor	r6, fp, r6
-	add	r10, r10, r3
-	ldr	r3, [r7, #120]
-	vsri.32	q8, q3, #24
-	eor	lr, r2, lr
-	eor	r3, r8, r3
-	ror	r2, r6, #24
-	vsri.32	q6, q2, #24
-	eor	r5, r10, r5
-	str	r2, [r7, #124]
-	ror	r2, r3, #24
-	ldr	r3, [r7, #104]
-	vmov	q3, q8  @ v4si
-	vadd.i32	q15, q15, q6
-	ror	lr, lr, #24
-	vadd.i32	q8, q4, q8
-	ror	r6, r5, #24
-	add	r5, lr, r3
-	ldr	r3, [r7, #124]
-	veor	q4, q8, q5
-	add	ip, ip, r6
-	vmov	q2, q6  @ v4si
-	add	r9, r9, r3
-	veor	q6, q15, q1
-	ldr	r3, [r7, #116]
-	vshl.i32	q1, q4, #7
-	str	r2, [r7, #100]
-	add	r3, r3, r2
-	str	r3, [r7, #120]
-	vshl.i32	q5, q6, #7
-	eors	r1, r1, r3
-	ldr	r3, [r7, #108]
-	vsri.32	q1, q4, #25
-	eors	r4, r4, r5
-	eor	r0, r9, r0
-	eor	r2, ip, r3
-	vsri.32	q5, q6, #25
-	ldr	r3, [r7, #92]
-	ror	r4, r4, #25
-	str	r6, [r7, #112]
-	ror	r0, r0, #25
-	subs	r3, r3, #1
-	str	r5, [r7, #104]
-	ror	r1, r1, #25
-	ror	r2, r2, #25
-	vext.32	q15, q15, q15, #2
-	str	r3, [r7, #92]
-	vext.32	q2, q2, q2, #1
-	vext.32	q8, q8, q8, #2
-	vext.32	q3, q3, q3, #1
-	vext.32	q5, q5, q5, #3
-	vext.32	q1, q1, q1, #3
-	bne	.L3
-	ldr	r3, [r7, #84]
-	vadd.i32	q4, q12, q10
-	str	r9, [r7, #92]
-	mov	r9, r10
-	mov	r10, r8
-	ldr	r8, [r7, #96]
-	str	lr, [r7, #96]
-	mov	lr, r5
-	ldr	r5, [r7, #52]
-	vadd.i32	q5, q13, q5
-	ldr	r6, [r7, #76]
-	vadd.i32	q15, q14, q15
-	add	fp, fp, r5
-	ldr	r5, [r7, #48]
-	str	r3, [r7, #104]
-	vadd.i32	q7, q14, q8
-	ldr	r3, [r6, #12]	@ unaligned
-	add	r10, r10, r5
-	str	r0, [r7, #36]
-	vadd.i32	q2, q11, q2
-	ldr	r0, [r6]	@ unaligned
-	vadd.i32	q6, q12, q9
-	ldr	r5, [r7, #104]
-	vadd.i32	q1, q13, q1
-	str	r1, [r7, #116]
-	vadd.i32	q11, q11, q0
-	ldr	r1, [r6, #4]	@ unaligned
-	str	r2, [r7, #32]
-	vadd.i32	q3, q11, q3
-	ldr	r2, [r6, #8]	@ unaligned
-	vadd.i32	q11, q11, q0
-	str	r4, [r7, #108]
-	ldr	r4, [r7, #100]
-	vadd.i32	q11, q11, q0
-	stmia	r5!, {r0, r1, r2, r3}
-	ldr	r2, [r7, #88]
-	ldr	r3, [r7, #44]
-	ldr	r5, [r7, #84]
-	vldr	d20, [r2, #80]
-	vldr	d21, [r2, #88]
-	add	r3, r9, r3
-	str	r3, [r7, #104]
-	veor	q10, q10, q4
-	ldr	r3, [r7, #40]
-	add	r3, r8, r3
-	str	r3, [r7, #100]
-	ldr	r3, [r7, #72]
-	vstr	d20, [r2, #80]
-	vstr	d21, [r2, #88]
-	adds	r1, r4, r3
-	str	r1, [r7, #28]
-	ldmia	r5!, {r0, r1, r2, r3}
-	ldr	r4, [r7, #68]
-	ldr	r5, [r7, #112]
-	ldr	r8, [r7, #84]
-	add	r5, r5, r4
-	ldr	r4, [r7, #96]
-	str	r5, [r7, #24]
-	ldr	r5, [r7, #64]
-	add	r4, r4, r5
-	ldr	r5, [r7, #60]
-	str	r4, [r7, #96]
-	ldr	r4, [r7, #124]
-	add	r4, r4, r5
-	str	r4, [r7, #20]
-	ldr	r4, [r7, #80]
-	mov	r5, r8
-	str	r0, [r4]	@ unaligned
-	mov	r0, r4
-	str	r1, [r4, #4]	@ unaligned
-	mov	r4, r8
-	str	r2, [r0, #8]	@ unaligned
-	mov	r8, r0
-	str	r3, [r0, #12]	@ unaligned
-	mov	r9, r4
-	ldr	r0, [r6, #16]!	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r6, [r7, #76]
-	stmia	r5!, {r0, r1, r2, r3}
-	mov	r5, r8
-	ldr	r3, [r7, #88]
-	vldr	d20, [r3, #80]
-	vldr	d21, [r3, #88]
-	veor	q10, q10, q5
-	vstr	d20, [r3, #80]
-	vstr	d21, [r3, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r9
-	str	r0, [r8, #16]	@ unaligned
-	str	r1, [r8, #20]	@ unaligned
-	str	r2, [r8, #24]	@ unaligned
-	str	r3, [r8, #28]	@ unaligned
-	mov	r8, r5
-	ldr	r0, [r6, #32]!	@ unaligned
-	mov	r5, r9
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	ldr	r6, [r7, #76]
-	stmia	r5!, {r0, r1, r2, r3}
-	mov	r5, r8
-	ldr	r1, [r7, #88]
-	vldr	d16, [r1, #80]
-	vldr	d17, [r1, #88]
-	veor	q15, q8, q15
-	vstr	d30, [r1, #80]
-	vstr	d31, [r1, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r9
-	str	r0, [r8, #32]	@ unaligned
-	str	r1, [r8, #36]	@ unaligned
-	str	r2, [r8, #40]	@ unaligned
-	str	r3, [r8, #44]	@ unaligned
-	mov	r8, r5
-	ldr	r0, [r6, #48]!	@ unaligned
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	ldr	r6, [r7, #76]
-	stmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r9
-	ldr	r1, [r7, #88]
-	str	r9, [r7, #112]
-	vldr	d18, [r1, #80]
-	vldr	d19, [r1, #88]
-	veor	q9, q9, q2
-	vstr	d18, [r1, #80]
-	vstr	d19, [r1, #88]
-	ldmia	r9!, {r0, r1, r2, r3}
-	str	r0, [r5, #48]	@ unaligned
-	str	r1, [r5, #52]	@ unaligned
-	str	r2, [r5, #56]	@ unaligned
-	str	r3, [r5, #60]	@ unaligned
-	ldr	r0, [r6, #64]!	@ unaligned
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	ldr	r6, [r7, #76]
-	mov	r9, r6
-	mov	r6, r4
-	stmia	r6!, {r0, r1, r2, r3}
-	mov	r6, r4
-	ldr	r1, [r7, #88]
-	vldr	d18, [r1, #80]
-	vldr	d19, [r1, #88]
-	veor	q9, q9, q6
-	vstr	d18, [r1, #80]
-	vstr	d19, [r1, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r6
-	str	r3, [r5, #76]	@ unaligned
-	mov	r3, r9
-	str	r2, [r5, #72]	@ unaligned
-	str	r0, [r5, #64]	@ unaligned
-	str	r1, [r5, #68]	@ unaligned
-	mov	r5, r4
-	ldr	r0, [r3, #80]!	@ unaligned
-	mov	r9, r3
-	ldr	r1, [r9, #4]	@ unaligned
-	ldr	r2, [r9, #8]	@ unaligned
-	ldr	r3, [r9, #12]	@ unaligned
-	mov	r9, r4
-	ldr	r6, [r7, #76]
-	str	r9, [r7, #124]
-	stmia	r5!, {r0, r1, r2, r3}
-	mov	r5, r8
-	ldr	r1, [r7, #88]
-	vldr	d18, [r1, #80]
-	vldr	d19, [r1, #88]
-	veor	q1, q9, q1
-	vstr	d2, [r1, #80]
-	vstr	d3, [r1, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r9
-	str	r0, [r8, #80]	@ unaligned
-	str	r1, [r8, #84]	@ unaligned
-	str	r2, [r8, #88]	@ unaligned
-	str	r3, [r8, #92]	@ unaligned
-	ldr	r0, [r6, #96]!	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r6, [r7, #76]
-	stmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r9
-	ldr	r3, [r7, #88]
-	vldr	d16, [r3, #80]
-	vldr	d17, [r3, #88]
-	veor	q8, q8, q7
-	vstr	d16, [r3, #80]
-	vstr	d17, [r3, #88]
-	ldmia	r9!, {r0, r1, r2, r3}
-	str	r0, [r5, #96]	@ unaligned
-	str	r1, [r5, #100]	@ unaligned
-	str	r2, [r5, #104]	@ unaligned
-	str	r3, [r5, #108]	@ unaligned
-	ldr	r0, [r6, #112]!	@ unaligned
-	ldr	r1, [r6, #4]	@ unaligned
-	ldr	r2, [r6, #8]	@ unaligned
-	ldr	r3, [r6, #12]	@ unaligned
-	mov	r6, r4
-	stmia	r6!, {r0, r1, r2, r3}
-	mov	r6, r5
-	ldr	r3, [r7, #88]
-	vldr	d16, [r3, #80]
-	vldr	d17, [r3, #88]
-	veor	q8, q8, q3
-	vstr	d16, [r3, #80]
-	vstr	d17, [r3, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	mov	r4, r5
-	mov	r8, r4
-	str	r2, [r5, #120]	@ unaligned
-	ldr	r2, [r7, #76]
-	str	r0, [r5, #112]	@ unaligned
-	str	r1, [r5, #116]	@ unaligned
-	str	r3, [r5, #124]	@ unaligned
-	ldr	r3, [r2, #128]
-	ldr	r1, [r7, #104]
-	eor	r3, fp, r3
-	str	r3, [r5, #128]
-	ldr	r3, [r2, #132]
-	mov	r5, r2
-	eor	r3, r10, r3
-	str	r3, [r6, #132]
-	ldr	r3, [r2, #136]
-	mov	r6, r5
-	eors	r1, r1, r3
-	str	r1, [r8, #136]
-	ldr	r1, [r7, #56]
-	ldr	r3, [r2, #140]
-	ldr	r2, [r7, #100]
-	ldr	r0, [r7, #108]
-	eors	r3, r3, r2
-	str	r3, [r4, #140]
-	ldr	r3, [r1]
-	ldr	r2, [r5, #144]
-	mov	r8, r0
-	add	r8, r8, r3
-	mov	r5, r6
-	mov	r3, r8
-	eors	r2, r2, r3
-	str	r2, [r4, #144]
-	ldr	r3, [r6, #148]
-	ldr	r2, [r1, #4]
-	ldr	r6, [r7, #36]
-	add	r6, r6, r2
-	eors	r3, r3, r6
-	mov	r6, r1
-	str	r3, [r4, #148]
-	ldr	r2, [r1, #8]
-	ldr	r1, [r7, #116]
-	ldr	r3, [r5, #152]
-	mov	r8, r1
-	add	r8, r8, r2
-	ldr	r1, [r7, #32]
-	mov	r2, r8
-	eors	r3, r3, r2
-	str	r3, [r4, #152]
-	mov	r8, r4
-	ldr	r2, [r6, #12]
-	ldr	r3, [r5, #156]
-	add	r1, r1, r2
-	eors	r3, r3, r1
-	str	r3, [r4, #156]
-	ldr	r2, [r6, #16]
-	mov	r1, r4
-	ldr	r3, [r5, #160]
-	mov	r4, r5
-	add	ip, ip, r2
-	mov	r5, r6
-	eor	r3, ip, r3
-	str	r3, [r1, #160]
-	ldr	r2, [r6, #20]
-	ldr	r3, [r4, #164]
-	add	lr, lr, r2
-	ldr	r2, [r7, #92]
-	eor	r3, lr, r3
-	str	r3, [r1, #164]
-	ldr	r6, [r5, #24]
-	mov	lr, r4
-	ldr	r3, [r4, #168]
-	add	r2, r2, r6
-	ldr	r6, [r7, #120]
-	eors	r3, r3, r2
-	str	r3, [r1, #168]
-	ldr	r5, [r5, #28]
-	ldr	r3, [r4, #172]
-	add	r6, r6, r5
-	eors	r3, r3, r6
-	str	r3, [r1, #172]
-	ldr	r4, [r4, #176]
-	ldr	r0, [r7, #28]
-	ldr	r5, [r7, #24]
-	eors	r4, r4, r0
-	str	r4, [r8, #176]
-	ldr	r0, [lr, #180]
-	ldr	r2, [r7, #96]
-	eors	r0, r0, r5
-	str	r0, [r8, #180]
-	ldr	r1, [lr, #184]
-	ldr	r4, [r7, #20]
-	eors	r1, r1, r2
-	str	r1, [r8, #184]
-	ldr	r2, [lr, #188]
-	add	r1, lr, #192
-	ldr	r3, [r7, #72]
-	eors	r2, r2, r4
-	str	r2, [r8, #188]
-	ldr	r2, [r7, #16]
-	adds	r3, r3, #3
-	str	r3, [r7, #72]
-	mov	r3, r8
-	adds	r3, r3, #192
-	str	r1, [r7, #76]
-	cmp	r2, r3
-	str	r3, [r7, #80]
-	bne	.L4
-	ldr	r3, [r7, #12]
-	ldr	r2, [r7, #4]
-	add	r3, r3, r2
-	str	r3, [r7, #12]
-.L2:
-	ldr	r1, [r7, #8]
-	movw	r2, #43691
-	movt	r2, 43690
-	umull	r2, r3, r1, r2
-	lsr	fp, r3, #7
-	lsl	r3, fp, #8
-	sub	fp, r3, fp, lsl #6
-	rsb	fp, fp, r1
-	lsrs	fp, fp, #6
-	beq	.L6
-	ldr	r5, [r7, #12]
-	ldr	r4, [r7, #16]
-	ldr	r6, [r7, #88]
-	ldr	lr, [r7, #84]
-	vldr	d30, .L94
-	vldr	d31, .L94+8
-	str	fp, [r7, #120]
-	str	fp, [r7, #124]
-.L8:
-	vmov	q2, q11  @ v4si
-	movs	r3, #10
-	vmov	q8, q14  @ v4si
-	vmov	q9, q13  @ v4si
-	vmov	q10, q12  @ v4si
-.L7:
-	vadd.i32	q10, q10, q9
-	subs	r3, r3, #1
-	veor	q3, q2, q10
-	vrev32.16	q3, q3
-	vadd.i32	q8, q8, q3
-	veor	q9, q8, q9
-	vshl.i32	q2, q9, #12
-	vsri.32	q2, q9, #20
-	vadd.i32	q10, q10, q2
-	veor	q3, q10, q3
-	vshl.i32	q9, q3, #8
-	vsri.32	q9, q3, #24
-	vadd.i32	q8, q8, q9
-	vext.32	q9, q9, q9, #3
-	veor	q2, q8, q2
-	vext.32	q8, q8, q8, #2
-	vshl.i32	q3, q2, #7
-	vsri.32	q3, q2, #25
-	vext.32	q3, q3, q3, #1
-	vadd.i32	q10, q10, q3
-	veor	q9, q10, q9
-	vrev32.16	q9, q9
-	vadd.i32	q8, q8, q9
-	veor	q3, q8, q3
-	vshl.i32	q2, q3, #12
-	vsri.32	q2, q3, #20
-	vadd.i32	q10, q10, q2
-	vmov	q3, q2  @ v4si
-	veor	q9, q10, q9
-	vshl.i32	q2, q9, #8
-	vsri.32	q2, q9, #24
-	vadd.i32	q8, q8, q2
-	vext.32	q2, q2, q2, #1
-	veor	q3, q8, q3
-	vext.32	q8, q8, q8, #2
-	vshl.i32	q9, q3, #7
-	vsri.32	q9, q3, #25
-	vext.32	q9, q9, q9, #3
-	bne	.L7
-	ldr	r0, [r5]	@ unaligned
-	vadd.i32	q1, q12, q10
-	ldr	r1, [r5, #4]	@ unaligned
-	mov	ip, lr
-	ldr	r2, [r5, #8]	@ unaligned
-	mov	r9, lr
-	ldr	r3, [r5, #12]	@ unaligned
-	mov	r10, r5
-	vadd.i32	q9, q13, q9
-	mov	r8, lr
-	vadd.i32	q8, q14, q8
-	stmia	ip!, {r0, r1, r2, r3}
-	mov	ip, lr
-	vldr	d20, [r6, #80]
-	vldr	d21, [r6, #88]
-	vadd.i32	q3, q11, q2
-	veor	q10, q10, q1
-	vadd.i32	q11, q11, q15
-	vstr	d20, [r6, #80]
-	vstr	d21, [r6, #88]
-	ldmia	r9!, {r0, r1, r2, r3}
-	mov	r9, r5
-	str	r0, [r4]	@ unaligned
-	str	r1, [r4, #4]	@ unaligned
-	str	r2, [r4, #8]	@ unaligned
-	str	r3, [r4, #12]	@ unaligned
-	ldr	r0, [r10, #16]!	@ unaligned
-	ldr	r1, [r10, #4]	@ unaligned
-	ldr	r2, [r10, #8]	@ unaligned
-	ldr	r3, [r10, #12]	@ unaligned
-	add	r10, r4, #48
-	adds	r4, r4, #64
-	stmia	r8!, {r0, r1, r2, r3}
-	mov	r8, lr
-	vldr	d20, [r6, #80]
-	vldr	d21, [r6, #88]
-	veor	q10, q10, q9
-	vstr	d20, [r6, #80]
-	vstr	d21, [r6, #88]
-	ldmia	ip!, {r0, r1, r2, r3}
-	mov	ip, lr
-	str	r0, [r4, #-48]	@ unaligned
-	str	r1, [r4, #-44]	@ unaligned
-	str	r2, [r4, #-40]	@ unaligned
-	str	r3, [r4, #-36]	@ unaligned
-	ldr	r0, [r9, #32]!	@ unaligned
-	ldr	r1, [r9, #4]	@ unaligned
-	ldr	r2, [r9, #8]	@ unaligned
-	ldr	r3, [r9, #12]	@ unaligned
-	mov	r9, r5
-	adds	r5, r5, #64
-	stmia	r8!, {r0, r1, r2, r3}
-	mov	r8, lr
-	vldr	d18, [r6, #80]
-	vldr	d19, [r6, #88]
-	veor	q9, q9, q8
-	vstr	d18, [r6, #80]
-	vstr	d19, [r6, #88]
-	ldmia	ip!, {r0, r1, r2, r3}
-	mov	ip, lr
-	str	r0, [r4, #-32]	@ unaligned
-	str	r1, [r4, #-28]	@ unaligned
-	str	r2, [r4, #-24]	@ unaligned
-	str	r3, [r4, #-20]	@ unaligned
-	ldr	r0, [r9, #48]!	@ unaligned
-	ldr	r1, [r9, #4]	@ unaligned
-	ldr	r2, [r9, #8]	@ unaligned
-	ldr	r3, [r9, #12]	@ unaligned
-	stmia	r8!, {r0, r1, r2, r3}
-	vldr	d16, [r6, #80]
-	vldr	d17, [r6, #88]
-	veor	q8, q8, q3
-	vstr	d16, [r6, #80]
-	vstr	d17, [r6, #88]
-	ldmia	ip!, {r0, r1, r2, r3}
-	str	r0, [r4, #-16]	@ unaligned
-	str	r1, [r4, #-12]	@ unaligned
-	str	r3, [r10, #12]	@ unaligned
-	ldr	r3, [r7, #124]
-	str	r2, [r10, #8]	@ unaligned
-	cmp	r3, #1
-	beq	.L87
-	movs	r3, #1
-	str	r3, [r7, #124]
-	b	.L8
-.L95:
-	.align	3
-.L94:
-	.word	1
-	.word	0
-	.word	0
-	.word	0
-.L87:
-	ldr	fp, [r7, #120]
-	ldr	r3, [r7, #12]
-	lsl	fp, fp, #6
-	add	r3, r3, fp
-	str	r3, [r7, #12]
-	ldr	r3, [r7, #16]
-	add	r3, r3, fp
-	str	r3, [r7, #16]
-.L6:
-	ldr	r3, [r7, #8]
-	ands	r9, r3, #63
-	beq	.L1
-	vmov	q3, q11  @ v4si
-	movs	r3, #10
-	vmov	q8, q14  @ v4si
-	mov	r5, r9
-	vmov	q15, q13  @ v4si
-	vmov	q10, q12  @ v4si
-.L10:
-	vadd.i32	q10, q10, q15
-	subs	r3, r3, #1
-	veor	q9, q3, q10
-	vrev32.16	q9, q9
-	vadd.i32	q8, q8, q9
-	veor	q15, q8, q15
-	vshl.i32	q3, q15, #12
-	vsri.32	q3, q15, #20
-	vadd.i32	q10, q10, q3
-	veor	q15, q10, q9
-	vshl.i32	q9, q15, #8
-	vsri.32	q9, q15, #24
-	vadd.i32	q8, q8, q9
-	vext.32	q9, q9, q9, #3
-	veor	q3, q8, q3
-	vext.32	q8, q8, q8, #2
-	vshl.i32	q15, q3, #7
-	vsri.32	q15, q3, #25
-	vext.32	q15, q15, q15, #1
-	vadd.i32	q10, q10, q15
-	veor	q9, q10, q9
-	vrev32.16	q9, q9
-	vadd.i32	q8, q8, q9
-	veor	q15, q8, q15
-	vshl.i32	q3, q15, #12
-	vsri.32	q3, q15, #20
-	vadd.i32	q10, q10, q3
-	vmov	q15, q3  @ v4si
-	veor	q9, q10, q9
-	vshl.i32	q3, q9, #8
-	vsri.32	q3, q9, #24
-	vadd.i32	q8, q8, q3
-	vext.32	q3, q3, q3, #1
-	veor	q9, q8, q15
-	vext.32	q8, q8, q8, #2
-	vshl.i32	q15, q9, #7
-	vsri.32	q15, q9, #25
-	vext.32	q15, q15, q15, #3
-	bne	.L10
-	cmp	r5, #15
-	mov	r9, r5
-	bhi	.L88
-	vadd.i32	q12, q12, q10
-	ldr	r3, [r7, #88]
-	vst1.64	{d24-d25}, [r3:128]
-.L14:
-	ldr	r3, [r7, #8]
-	and	r2, r3, #48
-	cmp	r9, r2
-	bls	.L1
-	ldr	r6, [r7, #16]
-	add	r3, r2, #16
-	ldr	r1, [r7, #12]
-	rsb	ip, r2, r9
-	adds	r0, r1, r2
-	mov	r4, r6
-	add	r1, r1, r3
-	add	r4, r4, r2
-	add	r3, r3, r6
-	cmp	r0, r3
-	it	cc
-	cmpcc	r4, r1
-	ite	cs
-	movcs	r3, #1
-	movcc	r3, #0
-	cmp	ip, #18
-	ite	ls
-	movls	r3, #0
-	andhi	r3, r3, #1
-	cmp	r3, #0
-	beq	.L16
-	and	r1, r0, #7
-	mov	r3, r2
-	negs	r1, r1
-	and	r1, r1, #15
-	cmp	r1, ip
-	it	cs
-	movcs	r1, ip
-	cmp	r1, #0
-	beq	.L17
-	ldr	r5, [r7, #88]
-	cmp	r1, #1
-	ldrb	r0, [r0]	@ zero_extendqisi2
-	add	r3, r2, #1
-	ldrb	lr, [r5, r2]	@ zero_extendqisi2
-	mov	r6, r5
-	eor	r0, lr, r0
-	strb	r0, [r4]
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #2
-	ldrb	r4, [r5, r3]	@ zero_extendqisi2
-	ldr	r5, [r7, #16]
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #2
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #3
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #3
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #4
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #4
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #5
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #5
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #6
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #6
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #7
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #7
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #8
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #8
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #9
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #9
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #10
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #10
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #11
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #11
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #12
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #12
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #13
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #13
-	beq	.L17
-	ldr	r0, [r7, #12]
-	cmp	r1, #15
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #14
-	bne	.L17
-	ldr	r0, [r7, #12]
-	ldrb	r4, [r6, r3]	@ zero_extendqisi2
-	ldrb	r0, [r0, r3]	@ zero_extendqisi2
-	eors	r0, r0, r4
-	strb	r0, [r5, r3]
-	add	r3, r2, #15
-.L17:
-	rsb	r4, r1, ip
-	add	r0, ip, #-1
-	sub	r6, r4, #16
-	subs	r0, r0, r1
-	cmp	r0, #14
-	lsr	r6, r6, #4
-	add	r6, r6, #1
-	lsl	lr, r6, #4
-	bls	.L19
-	add	r2, r2, r1
-	ldr	r1, [r7, #12]
-	ldr	r5, [r7, #16]
-	cmp	r6, #1
-	add	r0, r1, r2
-	ldr	r1, [r7, #88]
-	add	r1, r1, r2
-	vld1.64	{d18-d19}, [r0:64]
-	add	r2, r2, r5
-	vld1.8	{q8}, [r1]
-	veor	q8, q8, q9
-	vst1.8	{q8}, [r2]
-	beq	.L20
-	add	r8, r1, #16
-	add	ip, r2, #16
-	vldr	d18, [r0, #16]
-	vldr	d19, [r0, #24]
-	cmp	r6, #2
-	vld1.8	{q8}, [r8]
-	veor	q8, q8, q9
-	vst1.8	{q8}, [ip]
-	beq	.L20
-	add	r8, r1, #32
-	add	ip, r2, #32
-	vldr	d18, [r0, #32]
-	vldr	d19, [r0, #40]
-	cmp	r6, #3
-	vld1.8	{q8}, [r8]
-	veor	q8, q8, q9
-	vst1.8	{q8}, [ip]
-	beq	.L20
-	adds	r1, r1, #48
-	adds	r2, r2, #48
-	vldr	d18, [r0, #48]
-	vldr	d19, [r0, #56]
-	vld1.8	{q8}, [r1]
-	veor	q8, q8, q9
-	vst1.8	{q8}, [r2]
-.L20:
-	cmp	lr, r4
-	add	r3, r3, lr
-	beq	.L1
-.L19:
-	ldr	r4, [r7, #88]
-	adds	r2, r3, #1
-	ldr	r1, [r7, #12]
-	cmp	r2, r9
-	ldr	r5, [r7, #16]
-	ldrb	r0, [r4, r3]	@ zero_extendqisi2
-	ldrb	r1, [r1, r3]	@ zero_extendqisi2
-	eor	r1, r1, r0
-	strb	r1, [r5, r3]
-	bcs	.L1
-	ldr	r0, [r7, #12]
-	adds	r1, r3, #2
-	mov	r6, r4
-	cmp	r9, r1
-	ldrb	r4, [r4, r2]	@ zero_extendqisi2
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	adds	r2, r3, #3
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	adds	r1, r3, #4
-	ldrb	r4, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r1
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	adds	r2, r3, #5
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	adds	r1, r3, #6
-	ldrb	r4, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r1
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	adds	r2, r3, #7
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r1, r3, #8
-	ldrb	r4, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r1
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r2, r3, #9
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r1, r3, #10
-	ldrb	r4, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r1
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r2, r3, #11
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r1, r3, #12
-	ldrb	r4, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r1
-	ldrb	r0, [r0, r2]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r2]
-	bls	.L1
-	ldr	r0, [r7, #12]
-	add	r2, r3, #13
-	ldrb	r4, [r6, r1]	@ zero_extendqisi2
-	cmp	r9, r2
-	ldrb	r0, [r0, r1]	@ zero_extendqisi2
-	eor	r0, r0, r4
-	strb	r0, [r5, r1]
-	bls	.L1
-	ldr	r1, [r7, #12]
-	adds	r3, r3, #14
-	ldrb	r0, [r6, r2]	@ zero_extendqisi2
-	cmp	r9, r3
-	ldrb	r1, [r1, r2]	@ zero_extendqisi2
-	eor	r1, r1, r0
-	strb	r1, [r5, r2]
-	bls	.L1
-	ldr	r2, [r7, #88]
-	ldrb	r1, [r2, r3]	@ zero_extendqisi2
-	ldr	r2, [r7, #12]
-	ldrb	r2, [r2, r3]	@ zero_extendqisi2
-	eors	r2, r2, r1
-	ldr	r1, [r7, #16]
-	strb	r2, [r1, r3]
-.L1:
-	adds	r7, r7, #164
-	mov	sp, r7
-	@ sp needed
-	vldm	sp!, {d8-d15}
-	pop	{r4, r5, r6, r7, r8, r9, r10, fp, pc}
-.L88:
-	ldr	r5, [r7, #12]
-	vadd.i32	q12, q12, q10
-	ldr	r4, [r7, #84]
-	cmp	r9, #31
-	ldr	r0, [r5]	@ unaligned
-	ldr	r1, [r5, #4]	@ unaligned
-	mov	r6, r4
-	ldr	r2, [r5, #8]	@ unaligned
-	ldr	r3, [r5, #12]	@ unaligned
-	stmia	r6!, {r0, r1, r2, r3}
-	ldr	r2, [r7, #88]
-	ldr	r6, [r7, #16]
-	vldr	d18, [r2, #80]
-	vldr	d19, [r2, #88]
-	veor	q9, q9, q12
-	vstr	d18, [r2, #80]
-	vstr	d19, [r2, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	str	r1, [r6, #4]	@ unaligned
-	mov	r1, r6
-	str	r0, [r6]	@ unaligned
-	str	r2, [r6, #8]	@ unaligned
-	str	r3, [r6, #12]	@ unaligned
-	bhi	.L89
-	vadd.i32	q13, q13, q15
-	ldr	r3, [r7, #88]
-	vstr	d26, [r3, #16]
-	vstr	d27, [r3, #24]
-	b	.L14
-.L16:
-	subs	r3, r2, #1
-	ldr	r2, [r7, #12]
-	add	r2, r2, r9
-	mov	r5, r2
-	ldr	r2, [r7, #88]
-	add	r2, r2, r3
-	mov	r3, r2
-.L24:
-	ldrb	r1, [r0], #1	@ zero_extendqisi2
-	ldrb	r2, [r3, #1]!	@ zero_extendqisi2
-	cmp	r0, r5
-	eor	r2, r2, r1
-	strb	r2, [r4], #1
-	bne	.L24
-	adds	r7, r7, #164
-	mov	sp, r7
-	@ sp needed
-	vldm	sp!, {d8-d15}
-	pop	{r4, r5, r6, r7, r8, r9, r10, fp, pc}
-.L26:
-	ldr	r3, [r7, #80]
-	str	r3, [r7, #16]
-	b	.L2
-.L89:
-	mov	r3, r5
-	ldr	r4, [r7, #84]
-	ldr	r0, [r3, #16]!	@ unaligned
-	add	lr, r1, #16
-	mov	r5, r1
-	vadd.i32	q13, q13, q15
-	mov	r6, r4
-	cmp	r9, #47
-	ldr	r1, [r3, #4]	@ unaligned
-	ldr	r2, [r3, #8]	@ unaligned
-	ldr	r3, [r3, #12]	@ unaligned
-	stmia	r6!, {r0, r1, r2, r3}
-	ldr	r2, [r7, #88]
-	vldr	d18, [r2, #80]
-	vldr	d19, [r2, #88]
-	veor	q13, q9, q13
-	vstr	d26, [r2, #80]
-	vstr	d27, [r2, #88]
-	ldmia	r4!, {r0, r1, r2, r3}
-	str	r0, [r5, #16]	@ unaligned
-	str	r1, [lr, #4]	@ unaligned
-	str	r2, [lr, #8]	@ unaligned
-	str	r3, [lr, #12]	@ unaligned
-	bhi	.L90
-	vadd.i32	q8, q14, q8
-	ldr	r3, [r7, #88]
-	vstr	d16, [r3, #32]
-	vstr	d17, [r3, #40]
-	b	.L14
-.L90:
-	ldr	r3, [r7, #12]
-	add	lr, r5, #32
-	ldr	r4, [r7, #84]
-	vadd.i32	q8, q14, q8
-	ldr	r5, [r7, #88]
-	vadd.i32	q11, q11, q3
-	ldr	r0, [r3, #32]!	@ unaligned
-	mov	r6, r4
-	vstr	d22, [r5, #48]
-	vstr	d23, [r5, #56]
-	ldr	r1, [r3, #4]	@ unaligned
-	ldr	r2, [r3, #8]	@ unaligned
-	ldr	r3, [r3, #12]	@ unaligned
-	stmia	r4!, {r0, r1, r2, r3}
-	vldr	d18, [r5, #80]
-	vldr	d19, [r5, #88]
-	veor	q9, q9, q8
-	ldr	r4, [r7, #16]
-	vstr	d18, [r5, #80]
-	vstr	d19, [r5, #88]
-	ldmia	r6!, {r0, r1, r2, r3}
-	str	r0, [r4, #32]	@ unaligned
-	str	r1, [lr, #4]	@ unaligned
-	str	r2, [lr, #8]	@ unaligned
-	str	r3, [lr, #12]	@ unaligned
-	b	.L14
-	.size	CRYPTO_chacha_20_neon, .-CRYPTO_chacha_20_neon
-	.section	.rodata
-	.align	2
-.LANCHOR0 = . + 0
-.LC0:
-	.word	1634760805
-	.word	857760878
-	.word	2036477234
-	.word	1797285236
-	.ident	"GCC: (Linaro GCC 2014.11) 4.9.3 20141031 (prerelease)"
-	.section	.note.GNU-stack,"",%progbits
-
-#endif  /* __arm__ */
-#endif  /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/chacha/chacha_vec_arm_generate.go b/src/crypto/chacha/chacha_vec_arm_generate.go
deleted file mode 100644
index 82aa847..0000000
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2014, Google Inc.
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-// This package generates chacha_vec_arm.S from chacha_vec.c. Install the
-// arm-linux-gnueabihf-gcc compiler as described in BUILDING.md. Then:
-// `(cd crypto/chacha && go run chacha_vec_arm_generate.go)`.
-
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"os"
-	"os/exec"
-	"strings"
-)
-
-const defaultCompiler = "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
-
-func main() {
-	compiler := defaultCompiler
-	if len(os.Args) > 1 {
-		compiler = os.Args[1]
-	}
-
-	args := []string{
-		"-O3",
-		"-mcpu=cortex-a8",
-		"-mfpu=neon",
-		"-fpic",
-		"-DASM_GEN",
-		"-I", "../../include",
-		"-S", "chacha_vec.c",
-		"-o", "-",
-	}
-
-	output, err := os.OpenFile("chacha_vec_arm.S", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
-	if err != nil {
-		panic(err)
-	}
-	defer output.Close()
-
-	output.WriteString(preamble)
-	output.WriteString(compiler)
-	output.WriteString(" ")
-	output.WriteString(strings.Join(args, " "))
-	output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n")
-	output.WriteString("#if defined(__arm__)\n\n")
-
-	cmd := exec.Command(compiler, args...)
-	cmd.Stderr = os.Stderr
-	asm, err := cmd.StdoutPipe()
-	if err != nil {
-		panic(err)
-	}
-	if err := cmd.Start(); err != nil {
-		panic(err)
-	}
-
-	attr28 := []byte(".eabi_attribute 28,")
-	globalDirective := []byte(".global\t")
-	newLine := []byte("\n")
-	attr28Handled := false
-
-	scanner := bufio.NewScanner(asm)
-	for scanner.Scan() {
-		line := scanner.Bytes()
-
-		if bytes.Contains(line, attr28) {
-			output.WriteString(attr28Block)
-			attr28Handled = true
-			continue
-		}
-
-		output.Write(line)
-		output.Write(newLine)
-
-		if i := bytes.Index(line, globalDirective); i >= 0 {
-			output.Write(line[:i])
-			output.WriteString(".hidden\t")
-			output.Write(line[i+len(globalDirective):])
-			output.Write(newLine)
-		}
-	}
-
-	if err := scanner.Err(); err != nil {
-		panic(err)
-	}
-
-	if !attr28Handled {
-		panic("EABI attribute 28 not seen in processing")
-	}
-
-	if err := cmd.Wait(); err != nil {
-		panic(err)
-	}
-
-	output.WriteString(trailer)
-}
-
-const preamble = `# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-# This file contains a pre-compiled version of chacha_vec.c for ARM. This is
-# needed to support switching on NEON code at runtime. If the whole of OpenSSL
-# were to be compiled with the needed flags to build chacha_vec.c, then it
-# wouldn't be possible to run on non-NEON systems.
-#
-# This file was generated by chacha_vec_arm_generate.go using the following
-# compiler command:
-#
-#     `
-
-const attr28Block = `
-# EABI attribute 28 sets whether VFP register arguments were used to build this
-# file. If object files are inconsistent on this point, the linker will refuse
-# to link them. Thus we report whatever the compiler expects since we don't use
-# VFP arguments.
-
-#if defined(__ARM_PCS_VFP)
-	.eabi_attribute 28, 1
-#else
-	.eabi_attribute 28, 0
-#endif
-
-`
-
-const trailer = `
-#endif  /* __arm__ */
-#endif  /* !OPENSSL_NO_ASM */
-`
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index 79d7110..f21291e 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -192,37 +192,158 @@
   return 1;
 }
 
-struct AEADName {
+static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
+  const size_t key_len = EVP_AEAD_key_length(aead);
+  const size_t nonce_len = EVP_AEAD_nonce_length(aead);
+  const size_t max_overhead = EVP_AEAD_max_overhead(aead);
+
+  std::vector<uint8_t> key(key_len, 'a');
+  ScopedEVP_AEAD_CTX ctx;
+  if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key_len,
+                         EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
+    return false;
+  }
+
+  static const uint8_t kPlaintext[260] =
+      "testing123456testing123456testing123456testing123456testing123456testing"
+      "123456testing123456testing123456testing123456testing123456testing123456t"
+      "esting123456testing123456testing123456testing123456testing123456testing1"
+      "23456testing123456testing123456testing12345";
+  const std::vector<size_t> offsets = {
+      0,  1,  2,  8,  15, 16,  17,  31,  32,  33,  63,
+      64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+  };
+
+  std::vector<uint8_t> nonce(nonce_len, 'b');
+  std::vector<uint8_t> valid_encryption(sizeof(kPlaintext) + max_overhead);
+  size_t valid_encryption_len;
+  if (!EVP_AEAD_CTX_seal(
+          ctx.get(), valid_encryption.data(), &valid_encryption_len,
+          sizeof(kPlaintext) + max_overhead, nonce.data(), nonce_len,
+          kPlaintext, sizeof(kPlaintext), nullptr, 0)) {
+    fprintf(stderr, "EVP_AEAD_CTX_seal failed with disjoint buffers.\n");
+    return false;
+  }
+
+  // First test with out > in, which we expect to fail.
+  for (auto offset : offsets) {
+    if (offset == 0) {
+      // Will be tested in the next loop.
+      continue;
+    }
+
+    std::vector<uint8_t> buffer(offset + valid_encryption_len);
+    memcpy(buffer.data(), kPlaintext, sizeof(kPlaintext));
+    uint8_t *out = buffer.data() + offset;
+
+    size_t out_len;
+    if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
+                           sizeof(kPlaintext) + max_overhead, nonce.data(),
+                           nonce_len, buffer.data(), sizeof(kPlaintext),
+                           nullptr, 0)) {
+      // We expect offsets where the output is greater than the input to fail.
+      ERR_clear_error();
+    } else {
+      fprintf(stderr,
+              "EVP_AEAD_CTX_seal unexpectedly succeeded for offset %u.\n",
+              static_cast<unsigned>(offset));
+      return false;
+    }
+
+    memcpy(buffer.data(), valid_encryption.data(), valid_encryption_len);
+    if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len, valid_encryption_len,
+                           nonce.data(), nonce_len, buffer.data(),
+                           valid_encryption_len, nullptr, 0)) {
+      // We expect offsets where the output is greater than the input to fail.
+      ERR_clear_error();
+    } else {
+      fprintf(stderr,
+              "EVP_AEAD_CTX_open unexpectedly succeeded for offset %u.\n",
+              static_cast<unsigned>(offset));
+      ERR_print_errors_fp(stderr);
+      return false;
+    }
+  }
+
+  // Test with out <= in, which we expect to work.
+  for (auto offset : offsets) {
+    std::vector<uint8_t> buffer(offset + valid_encryption_len);
+    uint8_t *const out = buffer.data();
+    uint8_t *const in = buffer.data() + offset;
+    memcpy(in, kPlaintext, sizeof(kPlaintext));
+
+    size_t out_len;
+    if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
+                           sizeof(kPlaintext) + max_overhead, nonce.data(),
+                           nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
+      fprintf(stderr, "EVP_AEAD_CTX_seal failed for offset -%u.\n",
+              static_cast<unsigned>(offset));
+      return false;
+    }
+
+    if (out_len != valid_encryption_len ||
+        memcmp(out, valid_encryption.data(), out_len) != 0) {
+      fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output for offset -%u.\n",
+              static_cast<unsigned>(offset));
+      return false;
+    }
+
+    memcpy(in, valid_encryption.data(), valid_encryption_len);
+    if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len,
+                           offset + valid_encryption_len, nonce.data(),
+                           nonce_len, in, valid_encryption_len, nullptr, 0)) {
+      fprintf(stderr, "EVP_AEAD_CTX_open failed for offset -%u.\n",
+              static_cast<unsigned>(offset));
+      return false;
+    }
+
+    if (out_len != sizeof(kPlaintext) ||
+        memcmp(out, kPlaintext, out_len) != 0) {
+      fprintf(stderr, "EVP_AEAD_CTX_open produced bad output for offset -%u.\n",
+              static_cast<unsigned>(offset));
+      return false;
+    }
+  }
+
+  return true;
+}
+
+struct KnownAEAD {
   const char name[40];
   const EVP_AEAD *(*func)(void);
+  // limited_implementation indicates that tests that assume a generic AEAD
+  // interface should not be performed. For example, the key-wrap AEADs only
+  // handle inputs that are a multiple of eight bytes in length and the
+  // SSLv3/TLS AEADs have the concept of “direction”.
+  bool limited_implementation;
 };
 
-static const struct AEADName kAEADs[] = {
-  { "aes-128-gcm", EVP_aead_aes_128_gcm },
-  { "aes-256-gcm", EVP_aead_aes_256_gcm },
-  { "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
-  { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
-  { "rc4-md5-tls", EVP_aead_rc4_md5_tls },
-  { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
-  { "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls },
-  { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv },
-  { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls },
-  { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls },
-  { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv },
-  { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls },
-  { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls },
-  { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls },
-  { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv },
-  { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3 },
-  { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3 },
-  { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3 },
-  { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3 },
-  { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3 },
-  { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap },
-  { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap },
-  { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256 },
-  { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256 },
-  { "", NULL },
+static const struct KnownAEAD kAEADs[] = {
+  { "aes-128-gcm", EVP_aead_aes_128_gcm, false },
+  { "aes-256-gcm", EVP_aead_aes_256_gcm, false },
+  { "chacha20-poly1305", EVP_aead_chacha20_poly1305, false },
+  { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old, false },
+  { "rc4-md5-tls", EVP_aead_rc4_md5_tls, true },
+  { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls, true },
+  { "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls, true },
+  { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, true },
+  { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls, true },
+  { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls, true },
+  { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, true },
+  { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls, true },
+  { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls, true },
+  { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls, true },
+  { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, true },
+  { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3, true },
+  { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3, true },
+  { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true },
+  { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true },
+  { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true },
+  { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap, true },
+  { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap, true },
+  { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false },
+  { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false },
+  { "", NULL, false },
 };
 
 int main(int argc, char **argv) {
@@ -233,22 +354,28 @@
     return 1;
   }
 
-  const EVP_AEAD *aead;
+  const struct KnownAEAD *known_aead;
   for (unsigned i = 0;; i++) {
-    const struct AEADName &aead_name = kAEADs[i];
-    if (aead_name.func == NULL) {
+    known_aead = &kAEADs[i];
+    if (known_aead->func == NULL) {
       fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
       return 2;
     }
-    if (strcmp(aead_name.name, argv[1]) == 0) {
-      aead = aead_name.func();
+    if (strcmp(known_aead->name, argv[1]) == 0) {
       break;
     }
   }
 
+  const EVP_AEAD *const aead = known_aead->func();
+
   if (!TestCleanupAfterInitFailure(aead)) {
     return 1;
   }
 
+  if (!known_aead->limited_implementation && !TestWithAliasedBuffers(aead)) {
+    fprintf(stderr, "Aliased buffers test failed for %s.\n", known_aead->name);
+    return 1;
+  }
+
   return FileTestMain(TestAEAD, const_cast<EVP_AEAD*>(aead), argv[2]);
 }
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 4401867..341516a 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -61,7 +61,7 @@
 
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 1cbfae9..fa384c6 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -109,7 +109,7 @@
 static bool TestOperation(FileTest *t,
                           const EVP_CIPHER *cipher,
                           bool encrypt,
-                          bool streaming,
+                          size_t chunk_size,
                           const std::vector<uint8_t> &key,
                           const std::vector<uint8_t> &iv,
                           const std::vector<uint8_t> &plaintext,
@@ -138,7 +138,7 @@
                                iv.size(), 0)) {
         return false;
       }
-    } else if (iv.size() != (size_t)EVP_CIPHER_CTX_iv_length(ctx.get())) {
+    } else if (iv.size() != EVP_CIPHER_CTX_iv_length(ctx.get())) {
       t->PrintLine("Bad IV length.");
       return false;
     }
@@ -170,16 +170,21 @@
     t->PrintLine("Operation failed.");
     return false;
   }
-  if (streaming) {
-    for (size_t i = 0; i < in->size(); i++) {
-      uint8_t c = (*in)[i];
+  if (chunk_size != 0) {
+    for (size_t i = 0; i < in->size();) {
+      size_t todo = chunk_size;
+      if (i + todo > in->size()) {
+        todo = in->size() - i;
+      }
+
       int len;
-      if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len, &c,
-                            1)) {
+      if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len,
+                            in->data() + i, todo)) {
         t->PrintLine("Operation failed.");
         return false;
       }
       result_len1 += len;
+      i += todo;
     }
   } else if (!in->empty() &&
              !EVP_CipherUpdate(ctx.get(), result.data(), &result_len1,
@@ -258,20 +263,20 @@
     }
   }
 
-  // By default, both directions are run, unless overridden by the operation.
-  if (operation != kDecrypt) {
-    if (!TestOperation(t, cipher, true /* encrypt */, false /* single-shot */,
-                       key, iv, plaintext, ciphertext, aad, tag) ||
-        !TestOperation(t, cipher, true /* encrypt */, true /* streaming */, key,
-                       iv, plaintext, ciphertext, aad, tag)) {
+  const std::vector<size_t> chunk_sizes = {0,  1,  2,  5,  7,  8,  9,  15, 16,
+                                           17, 31, 32, 33, 63, 64, 65, 512};
+
+  for (size_t chunk_size : chunk_sizes) {
+    // By default, both directions are run, unless overridden by the operation.
+    if (operation != kDecrypt &&
+        !TestOperation(t, cipher, true /* encrypt */, chunk_size, key, iv,
+                       plaintext, ciphertext, aad, tag)) {
       return false;
     }
-  }
-  if (operation != kEncrypt) {
-    if (!TestOperation(t, cipher, false /* decrypt */, false /* single-shot */,
-                       key, iv, plaintext, ciphertext, aad, tag) ||
-        !TestOperation(t, cipher, false /* decrypt */, true /* streaming */,
-                       key, iv, plaintext, ciphertext, aad, tag)) {
+
+    if (operation != kEncrypt &&
+        !TestOperation(t, cipher, false /* decrypt */, chunk_size, key, iv,
+                       plaintext, ciphertext, aad, tag)) {
       return false;
     }
   }
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index e5104b4..d61d048 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -54,7 +54,7 @@
 #include <openssl/cpu.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 
@@ -67,6 +67,10 @@
 #endif
 
 
+#if defined(_MSC_VER)
+#pragma warning(disable: 4702) /* Unreachable code. */
+#endif
+
 typedef struct {
   union {
     double align;
@@ -252,22 +256,6 @@
 void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
                        const AES_KEY *key, uint8_t *ivec, int enc);
 
-void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
-                                const void *key, const uint8_t *ivec);
-
-#if defined(OPENSSL_X86_64)
-size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                         const void *key, uint8_t ivec[16], uint64_t *Xi);
-#define AES_gcm_encrypt aesni_gcm_encrypt
-size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
-                         const void *key, uint8_t ivec[16], uint64_t *Xi);
-#define AES_gcm_decrypt aesni_gcm_decrypt
-void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
-                   size_t len);
-#define AES_GCM_ASM(gctx) \
-  (gctx->ctr == aesni_ctr32_encrypt_blocks && gctx->gcm.ghash == gcm_ghash_avx)
-#endif  /* OPENSSL_X86_64 */
-
 #else
 
 /* On other platforms, aesni_capable() will always return false and so the
@@ -288,8 +276,7 @@
 #endif
 
 static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
-                        const uint8_t *iv, int enc)
-                        OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
+                        const uint8_t *iv, int enc) {
   int ret, mode;
   EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
 
@@ -384,17 +371,15 @@
 
 static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                           size_t len) {
-  unsigned int num = ctx->num;
   EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
 
   if (dat->stream.ctr) {
-    CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
-                                dat->stream.ctr);
+    CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf,
+                                &ctx->num, dat->stream.ctr);
   } else {
-    CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
+    CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num,
                           dat->block);
   }
-  ctx->num = (size_t)num;
   return 1;
 }
 
@@ -410,8 +395,7 @@
 
 static ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
                                 block128_f *out_block, const uint8_t *key,
-                                size_t key_len)
-                                OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
+                                size_t key_len) {
   if (aesni_capable()) {
     aesni_set_encrypt_key(key, key_len * 8, aes_key);
     if (gcm_ctx != NULL) {
@@ -651,57 +635,23 @@
       }
     } else if (ctx->encrypt) {
       if (gctx->ctr) {
-        size_t bulk = 0;
-#if defined(AES_GCM_ASM)
-        if (len >= 32 && AES_GCM_ASM(gctx)) {
-          size_t res = (16 - gctx->gcm.mres) % 16;
-
-          if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
-            return -1;
-          }
-
-          bulk = AES_gcm_encrypt(in + res, out + res, len - res, &gctx->ks.ks,
-                                 gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-          gctx->gcm.len.u[1] += bulk;
-          bulk += res;
-        }
-#endif
-        if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
-                                         out + bulk, len - bulk, gctx->ctr)) {
+        if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
+                                         gctx->ctr)) {
           return -1;
         }
       } else {
-        size_t bulk = 0;
-        if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
-                                   out + bulk, len - bulk)) {
+        if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
           return -1;
         }
       }
     } else {
       if (gctx->ctr) {
-        size_t bulk = 0;
-#if defined(AES_GCM_ASM)
-        if (len >= 16 && AES_GCM_ASM(gctx)) {
-          size_t res = (16 - gctx->gcm.mres) % 16;
-
-          if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
-            return -1;
-          }
-
-          bulk = AES_gcm_decrypt(in + res, out + res, len - res, &gctx->ks.ks,
-                                 gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-          gctx->gcm.len.u[1] += bulk;
-          bulk += res;
-        }
-#endif
-        if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
-                                         out + bulk, len - bulk, gctx->ctr)) {
+        if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
+                                         gctx->ctr)) {
           return -1;
         }
       } else {
-        size_t bulk = 0;
-        if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
-                                   out + bulk, len - bulk)) {
+        if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
           return -1;
         }
       }
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index f384950..852b2c6 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -23,6 +23,7 @@
 #include <openssl/poly1305.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 #define POLY1305_TAG_LEN 16
@@ -79,12 +80,6 @@
   CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
 }
 
-#if defined(__arm__)
-#define ALIGNED __attribute__((aligned(16)))
-#else
-#define ALIGNED
-#endif
-
 typedef void (*aead_poly1305_update)(poly1305_state *ctx, const uint8_t *ad,
                                      size_t ad_len, const uint8_t *ciphertext,
                                      size_t ciphertext_len);
@@ -98,7 +93,7 @@
                           const uint8_t nonce[12], const uint8_t *ad,
                           size_t ad_len, const uint8_t *ciphertext,
                           size_t ciphertext_len) {
-  uint8_t poly1305_key[32] ALIGNED;
+  alignas(16) uint8_t poly1305_key[32];
   memset(poly1305_key, 0, sizeof(poly1305_key));
   CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
                    c20_ctx->key, nonce, 0);
@@ -122,7 +117,7 @@
    * 32-bits and this produces a warning because it's always false.
    * Casting to uint64_t inside the conditional is not sufficient to stop
    * the warning. */
-  if (in_len_64 >= (1ull << 32) * 64 - 64) {
+  if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
@@ -139,7 +134,7 @@
 
   CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
 
-  uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+  alignas(16) uint8_t tag[POLY1305_TAG_LEN];
   aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, out, in_len);
 
   memcpy(out + in_len, tag, c20_ctx->tag_len);
@@ -167,13 +162,13 @@
    * 32-bits and this produces a warning because it's always false.
    * Casting to uint64_t inside the conditional is not sufficient to stop
    * the warning. */
-  if (in_len_64 >= (1ull << 32) * 64 - 64) {
+  if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   plaintext_len = in_len - c20_ctx->tag_len;
-  uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+  alignas(16) uint8_t tag[POLY1305_TAG_LEN];
   aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, in,
                 plaintext_len);
   if (CRYPTO_memcmp(tag, in + plaintext_len, c20_ctx->tag_len) != 0) {
@@ -249,10 +244,6 @@
   return &aead_chacha20_poly1305;
 }
 
-const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
-  return EVP_aead_chacha20_poly1305();
-}
-
 static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
                                 size_t ad_len, const uint8_t *ciphertext,
                                 size_t ciphertext_len) {
diff --git a/src/crypto/cipher/e_des.c b/src/crypto/cipher/e_des.c
index b1d312c..2ba2bed 100644
--- a/src/crypto/cipher/e_des.c
+++ b/src/crypto/cipher/e_des.c
@@ -56,7 +56,7 @@
 
 #include <openssl/cipher.h>
 #include <openssl/des.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
diff --git a/src/crypto/cipher/e_null.c b/src/crypto/cipher/e_null.c
index cfe1d1b..3d6a24c 100644
--- a/src/crypto/cipher/e_null.c
+++ b/src/crypto/cipher/e_null.c
@@ -58,7 +58,7 @@
 
 #include <string.h>
 
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index 8ca7bba..67418d5 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -55,7 +55,7 @@
  * [including the GNU Public Licence.] */
 
 #include <openssl/cipher.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 3a2c166..e7c2cca 100644
--- a/src/crypto/cipher/e_rc4.c
+++ b/src/crypto/cipher/e_rc4.c
@@ -58,7 +58,7 @@
 #include <string.h>
 
 #include <openssl/cipher.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rc4.h>
 
 
diff --git a/src/crypto/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index 21fffdb..0a940f1 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -264,6 +264,14 @@
 AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
 Tag = 619cc5aefffe0bfa462af43c1699d050
 
+Cipher = AES-128-GCM
+Key = 3de7b368783bd7287f2b9b731814c876
+IV = 90dedcfff100eb1f1db9d935
+Plaintext = 8d766795cadc0961c0f448c62df3827eef3a8664599b3adbaab0cfd63875bceb8f992b4f7447dca10ddd716aa0bc4fe925e1aa3e3fd1d5c430c650fe3546d6b9a24d576a857c5f04e8c0a3b149df277aa19cfa64ee235891d3b8ec0e840d268b1e70dd8a4bf97628a0c7aea38aa21eeb8fb1a8437f2abfee05e0d2c30659e312ec03d30da51b7c19073a2341c17df806e27e796d581143d39e4de8d3f8d46aa6d6fc1a98d94fa69b92dab751d930cc12de21fb1a7468af09e3c12ff6c3db3967d10cf140bc46f17a16e24b010b6cba5ebf777341c52042596ee53008389c48d9690ab9f5625795c3e588f72f7a1670b2b25a9f4eee1c8845ac90f1bf47ae4ea4b607a50aca88ed304cbb700d02d5486139b0bc81ec042e574abf986972fa008b83ef22dbfe720c2f2f6355c87c975932cec545ebed657e5e7570c503e9aa7f0b87d0b2648e421ed1d34749637c95d1e931af8925236387e50454f0ba2e22ed05f90450fad46f4eb7ddb08656511dd065c0f852a7e42f618a961a6c6bec42226c6b6043580b009ec9837cf99844cb74794a82c269ff648e0bae9ae50256a0ad98ad9f5a35057b3004ac96f469f9ee966dadc16dc47616586cf242706df96bb2f7ee43d3bd1c65d2eac7b82ef242e77ab509afb9639e5f3995380e926305729ca762c487f4411ec2a9c688b8347e5287216dbb38c3fe2281a89fcb47ee2ee7ddf79bfa3ab61cd56a00981019bbcea8aa0444eb75958e5fa56ea0036d2de4950a7db886f4a318b433bd41e00905ab158171e0ef13172293bdf70064b9dc7b243bf9dc927589bf9e99468d1cb330639dbff1850cc51929b8971b0b2ede9d06bc5f6ba39d4551b587f09bf6f8206e8f1524f55714612581d6aa45d8fb83425f84a736576deeecafdcbfbb8670d14cd2ab2a7f8b7f374c07881b7bac2605fd5ff7ff7cf43e30cf49910961a9079c0343b8601be8c3e9fe38f49fdab0b7e1a8c1536cf84e4d80d26ae5ec37570839b5cda02929221898d611525c3a88fc444167ffc532b256cdd0a8f31ff08097d75b629fab99c9e1062d1d9962b211e15ec8709934029c4934e64db8d7a2f32e23dc541be306e9a57a3419115994cbc3a8f8d5ea2a6f45b9ea9ac0e51ed0c6680fa029f4552a6c8665aab00ab77928342e7284c321e9500ad4774ef1fed0f596d5aea371fe1793271aef38cde55547f34701a525526e83a72673385a85f44db511bc87ce1f831fc6ccf8204ca4f4a20eac09897aae93684f14ede21bcaf40a09c08012b92600d6a839ebdf8bdca7b34192c6c50bad8796b3be3c375dbae6217815d2c75cc878d39b4e842d4eaa5f5df2242cf230e44a240e18e47827f089b18bf880fd41a2516eac8e6ba3fc2db64a4bc28789860d7b18d9edeae8b3059f4d945b15d0ee27b1f74842dd1df117fe83a8fdade23a47c93902eedc4d33f2dbfcd1996e6dc1458409fde2302830e8d44c58c5ae67486b9950dd938f14c38bc4c9484fdc4ded93a0f90875773453fc14d428cd6e7beb0c705d61229d2b3df09632ebb30b325fefe2aebbf2a7aa8e4ad46277ca4b8b078818b63d04e7652057f6cbbab7c43ac355537e0d3918b4a73c00dbe6b30a27ee7a6fa213d3347ae478e8edc323404b8322b9c7b0173ed61c38ed25f3576a675d527d22edd51d6dfa5767560d3a50a91226338e8c4e6436eedbcd3d2efe9dc1e686b15d2f57d553abcfda57dc316ca453a690f20148f0dfa20c1c4a58240aaf7195095fedfa56d839d0230d55ce9a8ca1b9d1acd6fe98d583148ba0f4a4e3413c76e6ec57ddb79428d3a90079f64d3321c791f60d501c3fd02c8403f0f5e6c6836bbc96430c1b48e83350c3a3cfd017f15bee3e4bb1295d821dc98b85ab3145555cce2c34a8142fe50f8db19918b514a165d12ff6301fb2296788760ac0b6d9e3a57770ad5111cde5d24b6321918cb0b0887a282b827a8749733171914b000e7d3c0edad1d42ca60da37f0698554bb2a1749f73b3120dbeaa32951f8217a781a200467d5b569d16f56fc9b7dff0ac524f03fee0617f4c692d94613b1e13b18075dc9f0d32811d4a8949a95f6b5fa46aeb83597adb409e68b2a0177c36dcc95dcb2e7dd4fb7337ff97c013364fe139e185014948fa698741d822044fa3f6978b16afd18138c845587c405ebf7a6cd1c28610ce67e992ed49e406658a0a202feed9709500d064b6f53eecfca57dd4b38363ce3aae9d59126d8ae7e140a373851188ae28c909181d0ac64770df70dd2475809350cb367825b59d521d5e457b4e36aea6dedd90a2266898b753b57fa359d43cd388e7d6c7ed90bc4c2af34ceafe88a3af6ac376fec35f1240f08af4f3eb30bc53dd68e5762e6d39e6b16f63003fbe0bee828d0d7adc58c41e857c2c44702215b202701fc696eae021af19c79e59c3e32627cd571f5db99b17f1772b5d746196befabb0b7446687827f3315b391d5dff069b1c39c00bb143218ef458e3b397e1c99640d57fc8db2e0083d3d22ed4111a8fc9e0e6f55fe6a56e946dbee43909bdd7d516fdf756ed8099ba80b1e17a5e279119345104379a36962ca9c8b2a53c414d79eb09fe79862ca749a9eabd9185ad1df57215945882f5894868a134bfc35c835e040e77ecf077d6a98a73ee022963d70b036be3fe5718280ae52c5d751211b22950c0597aaedd35af41f7dd5999e5f7ee34a37edcf97df54a46742b0252b196eaee454ff0c30685b15f8de087de208906be1d971f0fd89f7cdff2af0bdc96759d6889fba9ef092ad1c8deab0404562a7f3977d211c28dfd1573aebd5427a8773f03986101703fa19cd4ab96a381c76a747f63b63f7a9a3a08e251cdc593a024f63b443b76d17dd9e151809da3c582fbd334fa6dd0221b6d410c6a78ba95bb0154bb8999f619f2e084a6b9755ceee4ca3c7e0481a47776c8814f13054e627e37630d593bd09d5f10a049c66c9999f4b0b037e81ef70615d674c7c7975972994a053c069675fad3fae5ae3e779233b70254fb87f25d44c104afc3d5911b8b695173f9337130e39a02cf97356cb817f6cd23f55ef74dd06bd24ce5887a7001ef576262ffaa99f9bb5e3f55bda2aa0f199115909af48bb4d6b1a0a0847774515302cafebe75aad1f63362b1f38141e8721851c3ef1a247931b3b450581eb5d09027b9e3ba60ae9801d629b74991b7fd65520eac561d47115a85141d9a757bc75710bedff1630561ae05254ea541a7ff1846ed5e164834417556dd562c45543c88d8030bb56451fd5b3cbf10fb0164c5288789d2aac7e7a836e79bc3dd401a8e3e05aa6714ffb2dfddb3037c35fa1ebed62a073b2da42133f2620ae88de5e3f46cc69f2b9b3c9b88e39b8b108059ac6bd493be5f7a39f6b53ee825f4593b77ec9238f5ab804d533f48803e7d8187291ee25cfac4da5d8c9279517adfb09c422f6d704711726c73828a5082b4c7b3d85611b8f496d3e0f78c5c4f1dd1c722b1b11d55861f232beee6aaef8a00fd2eeeb45f182af191ca6de8eaa25ceda5451416fbf6d1abc0670b8c10e2815076f271044c690bdcb64856b91265bac202043a28f6bbeb807535aad4bd89e572a9427c826b170d3862f4cca70ddffb4769d6593a1cc6c42fd06cf68642835fe474a23e6f63df316f8361bab959b768d78e20c03c2a99913c162a9662bd9981eee55922f36792de0af68da04ab49dca72e3d9b0de79df828b433bcf6be073f851a36418c03a717d54d48c1014ccb793577c8393b7cb53cad6bc7060a54cc6363734f6ad388763519ca09b533078d3cfa61d7bdd4c4dd0ffe64d68d501b55903d3f4a1f310a3826ac2ca700de01d656188dcf577fd1b63e305614b8d13471f6f84a5d4b12c5e119870a63d1e3dbd39d3b5c26b09f9d80f8a59ce836b20bc933496923d278a022c00f3aac204d07d2e5075bbcef1e4820d633a3a2b35974f72a033484a91a1d6a9913239c93e5783b01833073c98f358e3465efd5087af37ad60b7285550e776d67ea7019e788776c5a456102358c32eb4e7c28096af88b9a20d8ce379ba3928a10ffd539c106f4927e7ac0f382c74017d6e4438fb128c660affd45e9bb68452de72b574eeffe3ce239d0718908c3800bc7e8ecd2fc7d9754171506017fd7868594c9373a96579fed475a28811649ce5dc8a3107bd0d8578748878ce4998684620931dc3981a2499568c2f61174c3b3fc46a7010468e8ff75c08cd43ac764d95e2ad1659f9db62e9554f811e0f43bb74779d923c8c243d12a5314d3c0c6ec84fe60e1d2b2e2b20d3e64054d62049ef9233ff55223a319c285e4e3f4c98dc95b2ca81230d7fed9bb99fd7d97430eb32c9c11647992bd85dcb47cfd58ea3e221d095bcf9374a6baa7c8333581f62b9e489282483023fdd18451f09bec764146b587209160b3d1d7a3d2e145fdb640c4bc382541e0d84255122d51a710887ebe1ccf29d41b4dd7fd7368d68ada250d3968d6f0971f0849c13c09abadb9db8b08960a18f84f0346ea0aa71227afa55b90cabc062d549b616400d36450b19adb67d7358e48c043fa1135abfca89374c906f8d1a6a845debf6b37f055d390b029c7f4524958bdf8d7e2755dde3b957f0926f9d3b8821ba96044d3cad2d637b973bfb657fcc06ff44c17965acf572ab7a0c87604c7dd1cfd136a0ad02b22e8ef320e101ea09772588e8c5b4d88f40fe1be18d27146a2b9559491949671700cebff9a709f297c2621ca9d5d1749623abc20a326ff5be55cb9435c03bf49b147b1e0a4a918bfdc3642df90b396a474f81d75c953d87b3f3b4e31fced630bd7c481c63acbb84dd31249101ac5277a36dcdfc80d8d9a2e928e9b2d65bb257bce97ccda83b187da8a7886dc96eab93d0864d88c358105f9cfe1ad0f0a8508b5b3985ff95de652e684da970b57669aa3fdfbe590a631522abe8246393639709a9a6cd549e78e3c2d1acf84643e9f554c5e076f75a5c1dce1be20a66722d0b896837b7036509ab8d473d5d2b7a8374d6a575f69d54afe3e7e18f4faf4e917be8a74e55c271b96d966e0c0b883f84b3ef2e4f278daeda2efd3ce770801d2c4bda5eb9b646deeab9fa55324e917e63e4eb6aeb4176cb4e43af3db61aea1546fbf16e76a12fcdbe726b565710e3f9866551023e5fbac0038678717e6ab4d3e92dcc53049e8cb65c00216d31a8869ff4d3539313fe2fd7ce0f53b255e3659e7dfc5f92b7627dd9ba42972f0ba72b888932d870ab97226040c4c0f4826be131fe1d2cdc21005ec2addd7796f0927501251ab26b0e5f3f9d2a1cb346a774e18bc233cc89aa69f5f70e3d5c17098eed350ec419c82837153b5c7f5813bf5918defc8df143063f3fe45125deded2b15892d5cebce589b60f2ada0f9d608983e8d107d8e6482b5f542c6650b014445e8c055aac142f16cfc59229fc9626f7aaa40cefacef777e494e13dfa93d27c201788ca9f60e572af8d65ffb513473dade5fe494cbf7377bd1ed03db2571d65af3be4b0bf27c1f069797bfb67ef0bd8a88c6286af6712c106df9c418d88054e3b46c88296a2e63894d6bee0dda8833c373d6a1b27637e1510fea3eb2fb34ae27354571369653a282a8d19f2c34f9e5ec34555b4ed24327dc5d246df13736bd41021697104f80c85bd0ae920e9aeb4e628fb8aec269d55858df149af298b06d61250b043c8a14a15f0646d0aaa18109d031c449e66dd7336044dbdec912b1bb615fae2a3df480bd64cbed74be65c8f1acac247e80bbaeb6f9dab38c6addf4f3b094d5934ef5c9749053b9159e280034e601731a12d6688ff27ee3581ae289de424d16676fb750d2ccd5b3f964dd77bdefc15bb204e2350632822384cc194cf9130f1ee81bfc3887d3366ec0b48cbbe0fe674281ae7445f03791887873659825680448f162452cef57d783821a73047078a8cf94c416850092ac772ef0b2e48517ef101ee0681b5259aa27fd56edf3c01e6dba6298ccc91b09bb304b637eccf8c673b816e74bd7f8ceffa6b17ab03df7ee9ca4098d24d044015a07df782a309cb6761528272632a6e1323c4e18284b463dfcabed708e4fc95cef133865cdbec8bfdde100621c65a92762cc3141ff37b66dea8fa6e3aad61dcbf3b512467c4773d36e58989e12a636389c1678c191137a5f7f59668c8a527dddcdd0c3fbb14cf48b8f3ea306850a5eda76c57aad06312d7bbfc18969d7b611f512358a7bdf959cc2f41de1c408133ef02b1fb2cdf8efe9973c27536434e56fc1bb4880db7fe901087b53ef3c0de18aafa47c25f1cd62c362f2e5da41c2dbff0e13adaba26c1e0829f027dc0320442e851eaed9507b70ac17180725349f6ea7b59bf39c095a9d10790e87221c7c2d24b8bca184ee95a3ef7449aad6c1d905f688498ae7a0cd1b01f76dabc342fb2be0295ca1484bece3c9b8a1b91e53de2d2587f3607a7f348f5cbefaa7a6dcf61bbbcae9444e2d25a77b016cbd1508c8cd319e9812b43b0bbca52df155d418dacb6ab1360a9e605fb53c6e20588a10bef42d884989e836b2ff16fbcdd2c1704f75dc8c1ac2cc6aeb92726f5d46e4784c70e1e249c102be6da506e5e3c2cef6a8bc4a60dac7adf3cacca8679f8f792ddc27613e44a70fd849b7617e042da46d65a3e6cf425f59b83cbae5b6e911142abd13a0a8cdf06d041435ee20e2ca417e905d2dc49c15b863ae5920ff7f9380a86bb0c86b69a000c157cd35245bf71f9dfdefbd1760af90ec3e554ebc511aebf650633221ca9157226f613f41406872765f8d7b916ff3877266f017b8d840dca0697ec3dffce7912ea9eafb62cc2f2d0a112c9bc0727444b47b62766bddf5b5f26d391f653b6894b069069979d0cf8cc7fc4143626a8420bc0a3866db3860096cc128d620ceff059d1614487004adbdf6b0c4428ac8897dcf16e6b11a692a6b465a92b40010f3480b444d4d2e24b0af8467666905c2a6233bdd6502521b621d3cdd4a5e1f268d65bf6a1879608ffd3abf635c5f0948f3cec7e087485c72b00258ba69783cfe7d611bc41c27814ef5674185791dbe626e1f276cf2c399a4eb264f19c77ee95d94252f546528f629188318e9ede65a927aafd2f2af56ff32c0ef39862d2f92268bc9400afa8ddeff591f3ef99681263a33b873bd9e01a59c8b281da30875245cbffee5268563c7f6f20b9e22d998934131dd219624d3cef6df2f3d2d6401833f72c619d6f763837141dbf93179d0f01375581ebe227185166aa7988eb9fd453d510ca6616cc013d551d23a33a4241e85aac3201284344977d496d768f5d920c5670b1d8bb608efc1b99abd261afb0a4ebe191605cc5c2e20523a13b3b94dd1fb24a27009d9a5b6329336f3516a327642386ba64c8769da1324a8a3d1f304cf0700df2b3e38215a954523e1d40ae96d0046e2929a815bf70785e94bc9b89246ab6aded60d65170eeb49b0ee0a57ee2e57db92409105c25f2d0c1a17b5556d06511bd0991a426258372c7f2b402dd533a75aa175524eb5d6b9575300b81fdb2258bd74429add8aa477bd1182db57107d411d16147defc3582861c68f5ce82e0a0316edd5d0f3cf36825a2c79a33e376cce2e63274b3b41bcbdd755845ad9ed2a3bdacb6fa3fa9484b7b60edeb1d9ef84772e78e39adca14c9fa0bb3ad1f1c17fb9449270e9b4c97b5b320839947fc73853fc58304ee9c9e86f3775f5469554d5006eb7ce9d02d5f900c771806c275ee7022e2b55d111338dd93ad51d14008df4c13d8c03fd9bb3689607e5cbdd499c3a372b487af74cb140f6300cd2dc2acda07277ea3dab57ecf09f1a8f2d6abf7c44fcdaa6dcb1f6e791164004b20b3b4c860f409c1483c7044b6fa445f7224606894e386ba08057a387b48920d4de203b1acc4dbe2b0b4cbdc3f7d7bbb097abbf81e01db09e120eab83def925a059cdb513efe6bc93f0579ebf75638df3c3d7f9eba3c36a169e9d88495c452888853640d93ee70f254f86e2d2d3fbb5e8883b36fbd2da105cf3a75cfe998068203186bb37f1d1ebead8ce1f9383b816f1da2fd0a9e01377b6ebfed4f05bec08b4ff9b90e385736fd13a3af7980c21b0dab58decea8e9545af5d0fb11bb51aeda2c8616960e8f6f84e6c2fc4f50d7e413afe030f75475509fbcf49cbe14445d267994fd3f38f41a1339f2895c0b2969a9bf9c59b85e629486c7bb5107c7a6b069793be7690f7a7c96c93b09a9d610594a156ab27a32d5557a5b1ec8920761cd2f559ad808dff3da64717ea5f10fba87b8ff2712ce322eb3c288939e0007f779a3920f45fdd533369f6f85a8cce21f91552fe03702ef81a926af0e402b418fbb25a6a3dad0ec18ec663126b3f48c341e2725abfeae865352d5ad275a9e3ca20393c64d118968023daac84bdc724a3c522d97a5878ed788cf8e44f80f8803d57584d8c8688cff24dd8c0e881b62d16ea30104d62007a4bec051da7fdc95d1df8556ebdf607383a0825ae503e24661ceb8ba773b793360c3f4ed3b761bd372570cb17e7c2030f07b0b45a7974e45ee6fcf5bd7ae9e9abde5421b42cff6af0c6eb7fc73f4deb67bb4e0b3dc9b4008da30c67071243cda649091a14b89bdacf2ae98dd230e932d9b277d6968c65e0006a8ff63f283f2cd9c21615dfd82e0b24af6ff559c97922a3d112ff0ef4af9d6583bec1f84d1aa8bbae705b9bcf458f5d93059b90fc2217ab27d0072a38aec3229d13266beb3015ac2389a06dec3120c6c04e540886091597919da293a4a8c0812d6cd336d5c5faeb64162ec0459e252d219bed78c4b6bb61c1213939bb3cca12a625ce5a45001d7408f6d40fa9466377caa43afe961b5c1602679220258fae72a8de2ac69c0dc97c90c270e306dbd8eb681ba9c092896b19a8d42665b94ff4d5b8b188f19f7c44abc8f88d4ad7b5df1cce3465de377072c70dd20dbd6779336f05ce328ad741d1e4606dce7065347df111c7d3282c8a3fa4a9458561c04d1056cd53ec5a8ddd6bd4434ac910c69cea0443fd09ee32d1256da44ab7896867a0c97fe4faa4a53b6db5cbfe3812a6667f04cd318f3da127a0dd46170cfbaadfcca863e0d4240ebec1cb2a5952881fe89804892d36dc5bd6484cc78db41bed868ed1b321a680a293bc29c420cffb5305d15fba05c76c2138b986f799b6a3d061658e498204c2b641f2f2ba73d633538eef6b5a01117951eedb7611742c120ff24261bea605e94d21e452ddb9ad27af08ed972b7d5e1eae010ec5d83e4505f6a2b7d9a0bb32a1fbba32a2a8c7823e736a69f516b781fb5354be4b0a67343c009a09b8f656c34ab895f9213531fdeee911d677d1cbc5e72c0fd1ad1f3b4b8bc735e14c3f75f1828ea28c90cda40e0cbdc40dec37031ff3d50305d5a8bba1d53d2f176895e53faa3067129a5c97505799967e55e4e9d87faf5920d71055009fd060ad06691b78583f63881b566d4a06b639c55796b23531ea79c6de24092c0e6fb4d3dc739f6d82ee3ee39f229de4c844aba36432d6119be0d2f02e5f72ef1d95fb2494522a7221e18e92cf22e00010ffd93b89fe60b6895a37fca91aa2fefa8debdae3147fe4f01a6adbfa0a59a5203516b2cc7de5faf821a2e72d43beafa30ac379791ad1e5da3286abecfc7a546b80191b7b892cdd01c25e95506471f5eb74568257439aea03300e80699909cc06db2fd607f3279651f7392f80bf4fc61d66f0dfed7b7db09744139d7374d3cdd18d153dede2a65f26130506acc51d5c721a7989485a145dac9565ef6d3cc938c5a51f31ccc88bb0739920ef8f0a01145f4ddccc74790a22a3099a4b57e31b3a01b4118c9e6c393c1304cc51ca1784db5633eb96ccdc88f8b732815b92c9072dbeb61a2cc1e6b2e7098d883e6174f5af7bd4f129389250926e041ba94d1ac543aab6525f151294060791fd26b668d09302c3482c78e5f3271c0150c437b4e78b1cff6f2b8660dc310965f2df14a1f2ad45cd2759433c4f3952402fefd79fff00dd309c3f09a58600223441c11693cdeeaf0a6100d38d612a759a8e01f753982803af30c7470f7bfd1ccf2c08aa0b187382d25868a9fdf729da10bb0aa0e1cd9c6e695eb2c80c6b6ce62737c3e655246edbce5b8f7ae21c473762db0969dc216a93d4db239f67dea74a1de21d50336793d1ae45e931d975bc706ea718a2ab10d66a59d9d23f76969d870ac279611246ed3aab0f79e11611b312624d78b88a9d1a49dc68d6968f7428c33f0a7a65675826422f7ac058101d2f85663de331345b3a25cf76b7c8fe0988a13278be9599b8e4708526b44a70bc31ac5c278ab739e3e6f0927b72507f34b0034e7fdf43364c466bb75b559e03d4d18c864714eb6061f83a6331b3f59dd62f39bfc2529d5cc68bb6ce63db1075105cbd7d7c4d4ab68c9e65a32092e34e76c3178382a965f49386bd4aae307128242a2ffe3022fd7dc1a824b330b9f032d55573c2f004a6905178a2479ba8a2d5b3140ed5f3e10d986265d8b4cf262295658f301b4d36281611d9c61624928da9abc51ff9a6eb481310511772fcb1c1786203d25295e4a319b9c6d65ccc966b4c5795e6e30b2b3ae8246c38b4a911d1904145de63dbd4470fac47f8ee3eeb3f58b5e665c26a316362382ccc6bf8db7699fa3334cb2ce61c746a7d3af24d8030df6759835f5890b7dd1de538cac1dfe843ad06eba2e887f08d9a49b39246fb26eff5cacc937d63c8d0136f7a8ed2af4cf473f3f0d9064f97fb4fe9938d631f7cea3c617c38771553eddd606ab80bf792f34b44111933796fe1fb8bb104223a4de9e16e17321ea7f8de3306e75a2bc79aa5e9c0ec8dde9b3dd1f2ae42a6a278410afa8fb62c16282f1e3dc1e2f8c28d4538a75b5da7645101253dd43aaa150b273f73e505d490490314606264c737bb344b616a80a4931825043a740ea4f75847e98cc99c6880d3085787903e54c63e90b60f03192234ab20cb41c70c6e82b00e0575a1bb0b0f435831c9ceb9dacd1fab8a7328eb3e28533d5bfbeace430e21758cac204631bf033752f947f78ac2bbd9423c2baf4dea22fcc65c96c332ece9abb20fed504643e82f3ba0fff213635910789a2fe1f2cedef68799fcf4a86d63ab0ccd395d6d4f393f7ee8905eb77df32d97592fb34ac86dcf20cbe5afbf9e9cff37bc34d75af046a09a1781cbf51ee2e0b0f40096d85413a30de974c4d1d16ec06c0fad00716c4e10f8dae46ef3cf27ccde74502b657d3dd26b5481d9787f5c6034083ff88807896da55fd2c951a28f15c8c9e6c86ab50c369e5ba4f6311de505c07c7b85573b5a539785820c672557cee4b58dcda948fb51c95674c23f1275b423ee5bf3a646df19bb5dfa22747857fb5c605669f334d116710bd9f1495e242bf47d6b607c1c9d9c706ee770808484ba552c978ef64daabb642a7caddf5a55facba474b8a63577ac817dc57e48ab072bc6a2cc5f5ae96edc45af41c896cecd8acfc36604db3b7fed9d2d17d429f94bd2542b194a3d3405f46c1021ecf6bb907fdfb4b53fe445d5adb18501aa772c9ba75619214384260306ab68a5ab59161b
+Ciphertext = 66c03198b3422cf3fd8291080f6fb3ebd9ad863e41cdff169becde726946a342ffa0ee547a27bae28cc782d95a90b0a618f717e3beb577354bd91e00a7a57485588265ad2dd0ab946926fea7c754c42751ec7247ee84c17262c0ed092186ec57d6044f0ac9deb21da6714ec7452e441e687e138ff144ea95636286263685419afd35f002830765d810b6f60e8dee0e6879995e9272c798b067d5f99f49e460b86d67c641f48240b61a16dc7cc27b048e8b8e8e80016470ecd2fc4225e29bb127ab48dfe7e7d5a65542176dd7ad40c07ac8b92891d595bbd7afb63fb6f9e1c2aa2fc659aa101f9b6a5c346625acec86fccf17f0d45809f3b9ee81572e5627f1afeed4ba96c6d3ed7e9232358dec01a1231ae7b94ad4675239f3b456adccec439b3cdd45504c5475bbc77dfd242e5e9671d103ba71a4601a7322e0e295357f335fa8d5651d528dda66575d106308338993e615b1c5bd7e95bf3f755ff726b4ac6dd5a43ef061ac9783f8f2804c68f66486f5844969103a36278ee0d10798bf8a802d3fee3a31294bf00ee74f087749ab3325c027d42b55b197469a5312bdc5c9b316b20093154e66605941d58f4db8d46a815c06f209c1dce2363771b5a794dd8d17e93a2fa7b194c6a0b79793c06f002638e5e3052365221232cc4b30adf161cc6e7865cf02911e2ac9b0a75f000e7ef3aa4f3c7438433513da7246d421f208b179763651f18e22a793961e5976a74744696912f22915244fcfbefdc472baee0be1e591d6503f2d9511ee1eededd9f5547c95eb94de134d0c2186109935207a23b2b8420a5858d831ed78202be855cc6b98d6663c1c52e1a0022ed7ebe0eea6b107da4cf50c1c7fced9744a914a66d4604a081587ce4b7e0f96ed408b8a9a2964314b1334a123d5184889958e6467a6d16e7615e5364e09aab75994e2758345511113321a3436db79351c63a282095ec6b99b6d775a5c09ea3f3225716e39e14df260bdefb2ecfe9a65c73ab4b3712ec842e43ccdfb535e3685fa39b4912719e67bbe195e5f0fe6c3aaada2d81b669c4565921f6c183d708b50c3f7172ba841815e9351fe5fbfe2fb1fabeb7cec9bd1dcf2d6332372f1b972b5144aa7ed6c5a985132f9a54469097e2e981b9e75a7df48fa79d0736c6f8a201c7c7d0ac8ac6512a7089514bf58442dbae0529135a7f2455e0ee5716c6610bd7600b3159197bcb20ca055695a36597bf7d3b18ecd08031b4ce3a643951e231c7ad15481e32ed7a3edd2b379c8e96d3288d5b93b562972a04f1b7e0abcc5090cb8655422cf5e9dac0b49678138faec81c78f113255eaa6110e95406a7e7417a6e221a8ec7fb9d55643bd589ace2da70fcb41722e66e0efce932cd7a34218375b6dfa3df1747953b24a41f94e50b84bad4d130d5dab4194665338e06f102f46badc5dad7aa06edb01f8a31244dceebe5e2006d6ab4a31582ff46731b19071c08ad1db79ba018687f3e6afbe703b1de26c11bc8b62fd6b2fa3219fa7190379504820abc97ff6c034f7850e2c7fd335462725db6748fe45920c213c539356b691f22eb490faca24e99f0a044a9f727d0786566ad00635983692ef324bbf1f80c42b269e9d5a8df3249873c51521c81400c729ed7a5e73995928abe94d189cddf2774f1735bc2060bb2240e558699c365dee45fa68801e6a1745e03736ced1b89fc2755565e3b36c2102594d43c451122d94f4a263664bd26b2fb5bc7700319f6b08796864f92d0fdb41710910bbc13aa9cc7baac3b48a24e4f3573f315448c317c149ddb433d9ddd2a2f0cfc81c22d3dab31f184975355b41e4b36fd8f22e8efa01d61a5cbb0e4fcdd273cdf68ac73fee745faff44d44d93c5a111aefe4a5ca8e8e7c075ffdb738cc5b6466dff78ddd837c72c54941707b04d60bc126a3a2fae9540ec2e4672ae13de0d927a7bd363f8abb5a56364d6d564df90a46df9fd59e2c54d5bcb8280415257a6976d8fb24c33330af32600cd1559e0eb05d55b34be456d434bca98252fa531486ce2a24c8bdea1d57d93a550ec586920903a39ca61cbfbce79b8f3a5b1653794872b2c614458177e748f8dfd43840e5bb0d608c26389347673fd0b005f60f52c56731ee5faec6c8d0617fb53d5f2415c2e7906ea0e6d0066354b213b3e94f4dfc311e4ec6afa7e8d1c69a63cccf8326741456a5e0bd0a359b7a37c117f7892969ad7b70cba9bea0a975ada7cf67e0d7255be8d2c6e7b8788b9ff14c5d1449d6173e07b5f9d94560d46f474ab2a67056fe9f4a9fd617a617d23143adb4e7ea35f2d5cc1398fb9ed43ddcd10f28debb27eb13533110005e6c78ca4a874db68c65081ecb8bff1b64eb1e2d7b76a1da3b375dce8a92d32a6277ed847879345717b9649f27e846a701549311c7e69a96d61df616157a114bdf1663ad93a26c28e1a62ee4a7c72bccb9785639eaf1e569decf777bb0548ad9ee36788cfa1150eee3ca3c96f09052ba2300cfb7526b9424b6f7418c27a1e9bc13e4d9868e5c330c051c3885e44714bddf7cb090fbd0f36b826aacbe191dc8c35c219e19fe736198c29dc4fa1a98b5fb1805dc29ecd02f74d4510a3928448b5ee61b5991e46644850a4885bb1ee272883faf27962430de1922d0883e7e80215cf5fe7e8f3fd0e2a49bd50727af793cb7e5b40860e80a1fbb9d5b5696bdf2f741909ab5a713de47716332df6c4f78288edcd6ea130d895fdb2f29f94635bbf2061de55f1801bd6a24294aa199d78021a1ba771c651de4bc08f032fe6ad7a5caf6a6afc6de649b901f783a0ee0fea9b803beeb0f431400d0707f159d7dc29c0c334a918fa08a653137a4a8bc86066c8800e1d171f1dbddf1fab8a3eff6b5023da96f002e7e217e826fa378b15dc8a376db30228f5d6b629f331a162d63e53e5b5bd7ff9ec098b4314285908281930ff0a8aa86a6d89411e6b5bc6b9c9e931623ccca6741fd6d36311e6a8e323a37ad40b7a2797b84694e736d9c135e52d149c760e727598726378cd674b0f4df1c361de0a12a2b8232e611d789bfbea699e8e77b99f3449609caff3d6ef7233df8cfc624376c905eea46c6f77c0b01d288868a19db77e227dbb5bfea5cc3f49d219c7477f7f2b3447b0b8efe08eab8f69579d727555e547c13ec7ae13b83386f2adf634140c311b6e2759cfb9c8aca1c32bb7c002d0f46ecc526916589a29e328ded9679c2163838f071b5b85b35e5e7d99c3c45d25bb9d37d7bafb8350ad4695a6e0cb7ea7d93868c30bb54e301e21147696b7dda156226a5ef8c62121e6b2cad0c4e192116192012468eaad46bea69a140aa3cb9056dec87c911636a1e55695b9e5a27c63cd8c03f31570d4b7507d13731ea31f082b33c6db8dd6e22282f9790be41350a96abfc4dc3de78e0a698930f540dbda3fee923a463a4c4a66bf00bb2cdd6d22b62a47af96b78b1f0f0a174e4ec5b785b3820f47d3c8cc1691d4751ce4e4ab78a4551956158a36717dc35488e890d0631241906db565603205e054815aaaaf17945c3372dfc7193369871e2e88fb84c15a2b9071101e1208177fc18397e6af17b5843e1fa75392d8d3ed214975d50f2b19c24e83f010f8c394ec1edbb1cb912e61627d2760b0e630b986bba2ae113b8f3b51ba00ddc495520274a85e6f6fa7573ac4ec6e2a86a1da9199ceb007aa6f132e5ab8ab8fdca7c829f452ff17524fec475b8f485b29fc6f0d972eea4ce98e242b5d58f6ddc1b3a71256de1c584c9914a3cf1e469f0033165d934fae68a7559011dac7a4e0c72e3b398fab8f8cc2fb67963b0f9220f410e5ba13026a27288a1d49edfaa51e8f220503fb5ec476147cbea975994fffde3ddc51bb189c470078978d238f5287fb2629d23989875d74b006a4122f6a342c996d4a244e8c5e4b804a44c301ac4d6054181a07964b279e0a44c158364395a2ead40053d2f3350ea0529a57552ed835513f533ee0c4b94ef674f31851616a4fa2d0302d13cd4aabf5f96ce28219c0b5bc0e5410fe0fa387ba1009a6f2280f9e7bbe20c33be5eb411a5f6327714b3443b4152cbc54c4012473237dd98b0490fc4228ded74afc81be2a58a22e03ca987faef5310e474f4f5a183f6b7ebede5a8df8a0f94a87a41852826b29466fd761f40b416ad0f263dd34e5497867766a361af1654c3fcd6ee7e6bb3f72d64cc980f04305b63bd574f116d1aa35b4bd642cab0cde6a29139aaa163805c6c40384313d4ec6027c891023083988c1b0d2edbdd9b1afe102fbda285a6f897efff72a0d7fc19a3cb6756cfaa2371e13be3cd167cddb90d525cba7da69608b9995cef92a6424a14df6b860ef0f09830fd7189497a432347680de0f463c0aff82df8098cc4f7753f7680c8c7374d01046b05c63be73f3a1623be778fdb0bdb90d4fb4b458af2890d15f108b0927304c91c8d62cb148c35cc93797db3ef9bba1014d89859a91da0c0a971f330600d71565d30e9c9ea8c07e7f629e1a6d578da04d37e597261cae8ab7d9a952bbf71573f1bf70e064f36c032cc624e3c980e5ea46d36232d61a57fa598347b7fb6b28401e34628b051d6ca3dea190d1d3c343fcc83175f70f77a8fc5e8791b9788989df1e37cc4881648f4fc673772003079adae55c83cf02a894b98561e4a6e4416bea3df18d6f702ad5c4f40faedec6b53cfdb5b3a52d7d43b97ee23ccfa2d30c7264ec555b15f1d9e7e19cd9890a7e8e01ff21d3b8b451e50932f189a420d18e7c7e2f103332c78c84600e5e8fdedd84f055a8b39be9a52782d47c6205c0de41644b09c0931f2da269a7e58e669f3b61ebda28ab8e3f9b83ff3d2bce37864af494860b2f01b000abeb737fbeaf8f9fa6378366606dcd0fc33031b94f9a7a0e562c08ea720a671ff92520047f69b138b4e032c3828874ec4c29e49aab302089956566372b20c0216b601c3958ed9691bbd89f1df45c6613d469e3b9758a70c860fddf768b10a6bf70237a454a2c0b70dd5d02da612a91fc5731513012a4a6fbc16d01550bdfdccaeca22bba104ccf6aeb19f21d4cdd3da231af8ec5bf2a726ee9cc7c85b8ed46d2f6fa4f1b010b2561fb69690d5a9df76d729450a6e139962bdaa2bec0254c5a252b97e7ce7eab1817f454c6121130952b8c40628065dc9b77b0f953552f5aa3ff983b6a51a51dd87c2b51a18e14adb8c80e002d0b47c61cb357babbbe3ed51d371941a8f111837ecf0e45020cb941de170c4a1b5e61bb928b1b11a8d902febd2ba016771f171b8a7ae825fcc4642d95649d53675d0027822e4ff79ffd302bfab1a0ff26f3648c7ab00c10f8d95f21e40ca2b40691bd4be79bb9ccc0bf760a05be4728bbc0a64e585207d1d09393a80d5f574442d6a933966777ab05f699c4e84aabbf753059287e7261d972745906a4fd8967bfc80ae9b6ec2ee1b22a81775f4f24999987365ae2dfb6739902ed51b9a4394fdf29f216c34567102d9db301661b09b728a79e377cf4bdfcf5c83b110a2e267abf6d40947e643ae2ff0c244af168c9f33e7685474ac30611ef95f218e0dd280899a92a41e7a759d03ce3709c2a140ebd35e199f1dbb96f7351cbe1f3de8da8c49758a49b9e724ebd3220ed6f51112944f70c0d1e9178f68a2c9476a913de00abbd1f5bcffa646f926da77a9e9fbdf81cdeaf7f9b13e843afefbca81c93614f8f1675325965b5836b8a77620a5ff162e25366718d8da7781e1a7e01fe2e9e56cf958c6273473abf5c2c8c7fb209307544e1c0726d5571e521621b18b6da3064b473423536b1b76ed75b21b4ee205d7ab5f081bada63062706bd155672dccf84614210d72660095437c6bc2213d9c904a4ba1bfda14d350fa3dce7141e817a50859b1a74aa64560b2ebc67add9f945b6e85577589817078c8ae54a9fc311593d2cbdb6692b089ee6264cebcc7719753f80e30dbe48b64fcfd1037fb9ddab69a5ff9e5898bd8aa947d9ad827c26df67c6786edcacb3478a20bded1ad8c48018ae0d439bb5afad5d39bb8fbaf22d72ffd759c4fa2e94a5a89f41358ebdc4c3aea5110f1965a049fdadff9cf703eabe9628e2680fa4e70320d304ecaed13f513f27220db1916ca1500f1c2e091671fb71329dec0bd6e310c83e67af61b8ab60ee1a8d559a508d174648b1bca451ef0ab0ee2ef74f4fcfaad1cc5ea6cadb8f1bffcb1f2c05122011ebbf6abc16838e452fc47653821589da4cb5bbac10deeea3ba0e0a6241338e64cc78d7a923d018e8b5b51c4442070e5b0e6f1e8c2b83791e930899c5897a602c401c1b85827962ff56d19c06f5af033059bc7fb1bd29b65f66aa5b4397834e846935e523b16438a42c1f990ebe4f83182163ca5fc60a4c6d77fc182e81fcda943a962e9e7f00f6399728b48bbe38d8178fae3582c8d9998e49df5f28e32d541636df3cdc8ac00df45db12da2e5e76f366c1ea8667ba5f3542d21f58ead7c55d06a4b35251b8f77dd34d3de262947379107a06d2f4891ffa0ad3a3e5bb2bbbb978af4953310d4cbe5525ab344ebb98ed24d003600de8f3af36ff3d0a7efeada963845d573685bec2221403b994f97b1e714fd7dccc300b62c2a516e9c6780983062eddde0178e93fcbb2ed4f06f60767356a11d22ca37078fda1ddb3cb907d1020f62ba85d09044574ba28aa3df36988eb8a41e4305e5b0687abe43a90e4f68f0374b6b05049aff5b065d7688cbbfb0e96ab03df38903bfa1c269f43a114085eb4596aec87ced88701b42f0b7426389727308bf10aee9d8f15ebdc411ce1e764a290a12faa2d7c1126dc7b5076f219b826ac8d380b69af7f95d69fc3929a97f5c7da1db6270e9ee1f2a5f7fa3a1b6bfcca00463655121f681d3a627d03efdf0b5fd045fb153bc4488a9a8b7264373c710ebfdb1c267fdca37723b21d5c3eaef48e784bd76e27c133cbc24d114f610c79f2a1f2c30d87ddba395887030b65097ca5566eb0361e70615b46d4b86c2759f1cc2efa3915b4cebdf51a745fb3c6cec69a1fda2ec5e884dce228e30af362815d2d8b59a14f89606bc77439042109369a9648db7d71024ed6df06c8ebd22e8623f48feea77f48b5e88827fafa84b0564151a5997b7f29c4d3d18068e34f2690a293d54003d0ea8f3bab9387ca72212cedb5f4602ad047dbffae2ab3a4cd2865bf896cd96f78b90e4017eb7e3c7092320c0a37f81dd65a5c4817a4e7053e6d2bcb23b11e09f681587f3a9361e974ad54b88c72c296629b1ab754d25be15e87c414cff975fafb3d7cb68167b21f1889685a48966705222b525fa47143b00041df94817c275d93c2550fdd82471cb3cc1b5644338060b767e807bca902c180b3e535c77be2651b3962287b6d1f6403033de4e0aa3a20615ab59d290f4b167325959c1524ef216dda2ffce86b50cb6b56b62a20a043d9d78c704479c22340151df5a1907670f8d4f8c90d93f7b5d94d04a4d383914867aa3c0e5ac85fc299a4d2801a3f80f4b0f046fb62c1c8c539a83b21c7549df0afe200537b52c80ebdbad8a438e430cf876cbbfee9ceb1bc5270577c27d53b40ac153cab377a565b1a9fbdee8bf8e94839c0fc04f7f664383bc90d56ccd1cc01b465c250b158b5e6f321c20db245602d10aab80c553d52f17282b095b5e2234c6c689a84b096112100359816cef7e92029fdfc048058f847cd2f2369ceec9fd171a0487bd7acfed6b0319832df6d59affbfd460ce8d12e4171da0f094e872a2888fe74925c5ef0621c4edad337f7006086748913b24d4d48ce36e662fefbe672b6d476456b1fbac6d80030ab93da93acb4a7e10f955547e7e20a0abcdbf909f05a2ee2e0b7485fa16be652b9d9fbfbf01f082488a81022bdb69af9e6fbe753e9eb92a1762afbb4df49f83ffc0cf03db563aa96fc5ba1af6d4d7eede6067749e8ecec79b63e09742e29e99e1c960dfb0688b0222c49ed919379ac66e3fa1c72645122d1664721e78fefdd1224c0b886f6e214e37d268ca9acab76ab3adc9f5549e5dcdbb3d31ac34ac472894d004eed71f88ca2377fcfa48d3ae43805dc612891dadd06c263ed8617194f890bcbb964f010d277ddce1f6682e661577ecd51a4d5421f00935a5b24fef0ea1809fa5c4fe9cf8c453046f61136ec8872915d2462157d73a205d56d77bb83cf16b88cadf6430c0e5397fae1f91a6a11b177bf04b065a2e55df81d5c086ec8dc8a0a660eed37d41fe4d8b3e3f22238e2a63b6e4feee1fe9a140ed37b2be4193f75c2d038aac7f6b7dad2a3b37e5b9b660615ec1db77a9b7ab416f43e66c872b71cb67c9245c757dc87723ab3b9544fdd8a16c9486e8ec3c4a44cefd98535d6e5683426c1cc8c888b8e0c2e7528bd7eb89b80d9e00969efd2f0a0fb09845426edf0d1d9a0809648e7e46ea0a8c9988bf9df475be12a72c7326c1f2bf01afafb190cf6f649133c7dc14ecf9b8c971135bd303c8894bac637e08257d45e1b68edf550d896c41682c002396e8f1eb7c1e2f4e0ed9b8b7010fc7847e6fb1c5907c17b2d2b7cd24c96f47406bd04cfcb2099d82dc2902d6f91e2f8f3a05bc62019af536309e7847fc06c10dbf7272a1509079fd16bb16a85ae2e078f97f9ce66bba66d6329c7ee70f9688f6d91aa38b25c7f4884658a72ad8cbf96d7d7a9652673273ee1b3d4d17780dfe9ca865416e318bdcbe9efd8e071fcb15ceb0743df5af4f7d598b31e38677e65af61c1109fdbb11fb11e3952e6c3ae8abc3f894ccdf205ae55dafce1dd05dca6b899877f57d712223dde4e7fdec7e0ed4f0a29ad359e318eb36ddb42fb205adca400f5b2615947c4f0ede95788093a1152d88acbbbb272750823151e245354e658452a95f21fef05bbfd98a10c1c975ad1a08c59fa3efa9fc73588407a83d0b26a53f1b4115f83780bc70ee2619d7374ca45b9e200055df1b93977e17aca89a009110a6e74caec7f86114f91975bc6e8bcdc7267ed2920cf12cd7137840628e1b8a0ea181dfef18dc5f74e752f842ea91bdce4b420ee709bca72c4514e92bcff55902e5529d77fd95f5837c8f4fffce80c813630550a0dde24092a25f65eba90790a06f4d4c3e739aaa8194a147fb32e81c71d3e8def79251c33637661b0a621a2a6b302dea00d34a9dbe9b621c1dabd0464e85241aa6712d90b4287cb23c17bf1e4d0e6dbed372e6b49c4a843305b3b0e5cab0b0964a93ad0bbc99ee711afa7f2d0a296a375fdb3176c65a957ddd9b88e9d57df736acdeb02a71b924cc2e972f51ba68a597215678573bede9ca5b3a0a2461b2d3b9ea57a5af8c91d40779bf917ded32f14a66d96e28e1415fea1e9306654c6b84d8a64243a5271c1f11590423c718961aecf5f659b49f67efa78e02ef2524d0966ebcc446d73d49ab7ec31f0c009069d14ccd63f926169291b83a3e37610054b0b964741e2ed8771d20bfa225eac0280b4d5af0c09d3218bd497a035536f5af0816884d606f1a872b8161a266466b56e0be8b80a7bde65ac706eea8cacf1749e5e71ff9fa3e69ce878427a0728d44e666eff977026abfe18cf3ad156a943b917e72ad65725a9a8d60b7b5740494fa63143a7f2a94fe6d8b319be55d6fe1a988244deb798f345f30dcafdb6af9e9cee9e35733274bdf3896750897371563ed2516c4ca6c3c3c994b48cc94b67e8129d234a0e19dabe39e500214c0ed5f0e5d61b2f58d7355d147102d93b2689bc5185dd4c0a18efd11a307b887d4d0fa84fd992731b3a80dbd027dd36cd6933766c537e8e9e27d35d5187e8276b0f59fbe7b6d629d3416b782e7981d85e1e890853c3aa94a93c1667a55044ae42badefab979fe7d525c6a180307c5ee3a9c3933038028c3e1d15d1e78fbf53b6ea61ac5e02db0161719398a31570c55f73cb47ddec8f99e3e14af5adb8d5cd179f4204d080331e75bd391b19d38eb81f148c36af3e8a3ebe76209bb75c9741a89b5d0708bb0fbb0945fc6fcd6ce142d19faf0947c338dbc8d976963281866b5216421c00cbd77c0907d1e16f5e925319cf6c62f8c6e8eff0c2f831c504e7a1c0df09a54e2af708ceef39ed7d0f63d83429e9b0920c03cf85c2244f2fbac3958847113bed577dbde8992cd91be5833c75faedd5e2005d4f7b66fab8fa9305927406f863d1795dfe04028940b765bd79de6972dc7094fe1c2503a73d7b50208835216c23aab3e47094587549fdd74bb50ae21cd1354daab632fd0907e63f4c2b2d39d7fdc4fc216bfa742b4608238623cb7fa01bd851c1e7ad5ef5215173a71f363fbb7dae8092486f4a1549e32ae53b14c1343ff7fb5e2b1487d9c594a1b56e22625d275e41535534d225b7b2c9deeb0d30dba7188cf75d680d4545ed05044a0661c690a37fa14a73ba8c68357e2c948e290b5d9a4b51822824614ef2938d19ea4b650041f59f3b548f0a305b86f55e69760f37f09dfdad62651aa5fd84eef28a4431136b34a49c9bf1f2891364f86b0aae70b0414e821e3db1533b0f1db5fd232308bf118f858aab5ae974c10583f61b283a3870eb82aaa8ea3c4e2ee3c3a3d7169aa8e975ddee7f620f6c5bcf3eaaef0101b62cd54495cb8809052c9e3151690cff7c1efcc4f63b22472111a7c5d9d7d2a2be951510f60dec8c426f14700c8630f8a14dfd359addf5d9b7ae031a745ecb4e17321b385799c90f924c4780287ac187530a40b064064b9036cc46e3f87c4d23aeeed1bc22a5411c7c503594d5d1261eb9fc4da242493beee9f671485a978a32e965faf9b0e2c13f78e31e1630b72d35b4be691e90b3798e18223c1b514b39a8e1eeb7897c22fdee1e33fc76e2b2f9298ad4fd89f44163aaab23d754d98c7890e58708b81b3832aee31aeca85e76416133710aeba0e5d9f17695e607d09ae3f94be191553bc39c6df03cefb4ee05516fc02d66c9866e4eb0d89a662e309379a347159db2e070abceee226f2b8b62847ef7c51d69c5f12eb567fa13af4b4f90b3f3d9d4b6a3f68bc4dd77075081e2e99833c18b154d0d6ac360141de2a25af61d551f10a34e03e1419a37409b4c177c51a8d248157b411868eb607c34d2daaa453a0954fade5eac45d5f21f50efba8bbc9c87ff0435c70f064b42cb2d158384fe0a4d9c90030ace7723af0a6c8faecd8f97f9850e2a489a94ebcc655301e2e14711de9eb08726638a9ddb57160c5545c152a26860a17dd18172bfac138a300f60431fc49eff18c93f71400e887f878f4dd637cf5df8c1e2b12c0f87e31ba2754ac1748479eda0c4184b528554106128320dcce349939e5e6cd3434f86dc7adfee28c008a21ddf9d0dbc87ceb14cc3afbef1e06fb3f9908a4b14f5e6c43b23ba783b75a6cbfa2ebac6533661b8c1143a34e8e2a9723389c4b7087dc07701c53b169894551084aedbb423bcce2f470881fdc7240c26b3b76fd6cfeebf8eb2828b4741e5e8698b19fa0a44703cb4e4c8ed6a7e4d6063f5fab724e08a159f4f04a2f351dcfb6335ae6697dbeca25c76b55e6ec9045eaaa8706902df492b8c8cfbf68c4cc1be5d1e5a173262e38bde051656ea85ffe35d97f1b25f6a47381bc327a946f7cbf6210adfd957b2921
+AAD = 85ddde4720659e80e25168585a354eb1e021c0b5d2ee289f2314dd5aae52bdf1fd44755bb56a6e659111a1d4b4da73315bde01c7d2c15a4f7114aefd68c141049fac27acfdca24e65c51fb1c27d307cd948e13af2963166bbc9411401d124f1ddf20f890db5611385257f52aa05c09b467e3ae886decf5744ec3749e5879f2a60017f601bbee11a66604d5f3d521d2c48cea1794f77366f29c7bd12a8aa51d34a4f3fb52809561b527016bc6badf9d136156c330e1d69d1aab98c7caa9cb46e782a898b4c66e4ee3e2445fbfacaadf9a8f73c4cbcb2a1ceb604ba5637b51337fcbe0fc366da98e805ceeb29feaf05420113b16e1005079c0e88af33f5970b3d7a8b51d0d9f5120a0795063db508171b75ed07705ac6d6bfe4ecc59243091d48865536515e036860affa880bfc91aae2fd1700de15994792aefc4a176e5d49d0f9135c7d670f3cb8798bfbe83fe73de7427e0f3e6a2df561cfa15ffe6ae80d5016096c8875b0beac8cee8fb530fb421b9a8ada4d551a528d0a0b521086f5a2db371a3bf12a2ef861f831fcb44cb2baede907a9306d3e5a3af796e0a50ba2c8dd61fb03727df5f0654d837dabee2fd90eecb7b2e8f303b0d57f97dc6a52d8281574d8457c89c6a9f5d80e0bd86c90ed39b1db4253affee614e8cf1ff05166c66e7d2a2aa2fe8a81c4741339683debe189c126e7f553a5f2dc16fc16672f74aebf94c7e3041c758fbc6d0c7f71c192cfd0fb2ec52d0a0705b05815d567f3d19f9b5d553a2adce9a79159b0e38980851bf64e97f896c028a6df8363cf1f13f4654265a7b0c0b24198efcf4418c32772bafd3980dbc689fab12e85b3ef4a491e2e5ffaa2fadaaf3deb392105a42380797d3b41ef61303a6016b269ec9a9f6e3f26070ff33cb467435ecb325dc7e18728a5c2e882e720c8f876fef10f5bffd5a925cdc9689d934272019e90e3a3bbf63a295f207faa5c014e1517c7d5c18c3ed70e92304d51944dcd3604c999d4aa8d8dbf2a4c69cbbc08635c968a20dcb80f438d43c57851c4cafec0b9568dd6c19932fd3f1294afd16f019f20e40ec87f6f5dffc7717470614b2de6e9000969e6b7e561cf91c06dd379a09c6c25c7841330dc78fc5be1d9b86581a81f55c0289531128638441fc98a1ad9472d74e2be2f874aff2fcf9c941502f59f716185a4c39289ca368c6dbf5257b5dc5e57a420792c26e602e4ecbc4f17c8787004eb88ea091d6b6ddc3c85dc110b5d1f46f6e1d872723176f4c73664ecb4219258fedce19ae22360354fa4894fe51d69434c2e58e1ec665b5cc33bb295053c591b474b6ae178c8834667bef971604279440170ebf3e739a4ff19704e5886767f81edce95a3dd93d1147995e7eb6c794b7be136658ed23cec7c374705ec0d8479dfb44cc7213076668e5fbe6a508537a9157815c6e5187b89f
+Tag = 469e3ef168a64945f76d7a2013f27b68
+
 Cipher = AES-256-GCM
 Key = 0000000000000000000000000000000000000000000000000000000000000000
 IV = 000000000000000000000000
@@ -384,6 +392,14 @@
 Tag = 32893832a8d609224d77c2e56a922282
 AAD =
 
+Cipher = AES-256-GCM
+Key = 53a6f0d9b8a81818f2fd7525acd65acbaac82684cda4fd357b1ceb6146b31ee4
+IV = 05d8a92b5a510c3a3dacbbc0
+Plaintext = ac0ae17d3d0ee5935e18675c36d9e43967f6da38dddec14c7ec574ff8473e11ae5019e638232323c175b7672a7462df6709f5014bbe12a1370a1ffb570177927106f995dc8f35bd6e6228de7c16acb71e583c87477dcc7b17a908ce01543496c2cab8a14a21c43b18fab52d8a882dd1d999b4275db34c7f32bcba624d128580d7566a2da4bcfcc4136d58816c437d21e90456fc86381b946b8955f0448e83564165a629cb2edb978e5941010ee9153b054ee429b315058334ad7899aacedbc0bf423de69f57c633b56033c6531dde29258694045c46a797987471ae6af8fee8ad0c1be4149605064aaebafd1c5592e61beca9b5c7771410a276c3ae517490735ddd6af499ff705b9fa68d50650e60c19f5ae2c88dbb6d612afc7be28a5f55556a2163b6f66609f7d9ba7e97c074ea39a618727421fbfbb6453ffeefa643decf11404764515d28fce8ba66b8c85d077c47a54125a38bcb6b0adf6d248ba0a9ea129c887c66ef537c45e9fd3c17ce352e3936cf139e13a5946a7dc9dcb6423ca6a051bf560cfc572ef366940e71c81aa302cb9701f9a5206e9eacfe9835bdacb6425d058022a27fe73e5edeeba98c7a3edb761578ab2ad5a442c2dc1cb3c143c6f18dbe525fedd2a9cee0ada3b2c116465c5cca9a7e5d4374b29aa4ad8adaff8d6b0d1ac3990685240ce022faaa07241f9ff445566b9e0463350792cadcafd5fdf5c37706c0025b3c627185b356d39dcb2244b15566e6e3f8942f730fd6d855daa1456fe294f9156c4b5131e5bde7f2d938ceb6c7f5deb0f847a98b7fd11a3f5d0163eef9bbeb83cfc96dd8eedd447901ff4d3a35c0ea1f691b01385eb39fd265f756bbd77bb61b1741db0502947b4b985382a08a5916da809a8afd3fb1d78d9e16f8e37f51aba100d031d9da8613e9cd2cc621025b47150b3e76775ab23412d74334bcd79746cf601407481310a923047ac68a4e6a7f7b96bcd85bb6f24e38f03c80ad41a0a581b4246ea4715ee561cdc5384a51a6fc9ed8569ba6b12bcd95e6202ecf834dd9062ec539cc8cc4ed64ab9ff85998da0e63161e7391b14de47dfde41523b6c614618bf2fd1edd68a5de1c03c4181569b6c361d955c637abbf4efdb5dbf2f0dd2544329c44b77081a48f53231fa9d4cf6f2186427e469d0cfbcd698f7e7cf773240dd2b807a2fe699f0ceb4a2339e9cde01114b2aa5c3591a82a3a27b308e1e7f092af8ad97bbe7b28d78ecd80c0c0a28372193d66bdbadc0b58e4d5408acace53bd5e12101fcb25754f8c545340fbbd1328287044a29d18f40a24b4084febebe228b67cefd970df6d44ffdc033a50534e5977bda660c589c6e3c3a28b4c500b29ff4a1c3eaefb068784a29914ecab7868a43999833b0b37ae79afe58875a0425262e0ec7e10ee8a6bc1c97d332bc2a6195de239a166486a3c1ad8de3a026e5b1757f9a778a511024a260c9809ae3b22d78f18ac483281a796b1ccbfe7a9b9f357d12d340e20bdf2037e8bb91ef858cdf2eb9d7161a756d8c244c55524f8f5be2e4f18641bc4c2409c14816846c4655be716276d8356e516640da49e8412fcfc7ac0e084a079129b23e54952d8030e1f8ceaafcd322dfb4bd189bb5d940ac83231de0585783387d0642a245183f7a251779bdb12c63e9edbf3d0c94281140598fea9e73e951ce650c984cfb1398f8813abf8f8827af5eb64a65dfd1305bccc45086438ac439a9265790fb225c509ce3c9d39e25d2276d7f3c06d7cc28d33b2c21bb38b50dca5b10afc09da83ba12ee878e0f6054e8d3e78d731671de4f9d5a7b97298b01f37c7e78e5fcf5188554bcf5d42559d3b15153bb3cd5a0d1cc4a96d02ae8b1b115d1ff617b6ad894ce0585f46a2a5f4cc1b83065c1d7b5d2f25f3f4bf9966b4c7d7156931861d5edd199c126f1ee4ff6345023419d0a4c87f3388fcfbecbb6c1e2f4745922b88085d21d4551e4c127eb423db87a51c9f9a140f8a7415dbd70c4b0173e687a40f895404f2203e14ccd61e0e5b0d5aa3fbd1c8affb5807d787d840916ece24c56c50d3d9ed9f19d73f2c80c461b5b3c07dedcdb41402c3826a958d74be48382dc741dcf3e0eb8955397da33941fc47288147736d778914a57effbafccd4cf293e6ed1c7d19b55433bc0363e41546b3638a4c630eb35dc6a074f90185cb9daaa6eab54825a4daf76f49ad918e90e5777a826d6d5d52f32f7ceaf818f87251ab4d1b5406ae94e41cc97fe022b144f26335829d9c81725b3daead621a0df71313d18214ff8dc687a7ab86b8eec3070ee1ca9f62005a0cc15ca6e2f4fd893de8fd91f6210f6c96a576024678535c962a2dab06f56be377dfa74bca089adb7327abd05c3ad7646b5e9e6fc2f29916b34c8642f3c0caedb53b8f30c2a77d1757103b7ed156cdc703911366b02cde87ce7343886987f7a8c028921a7b87c5c0aca7ada34970a6d0d32eb1b177ed8e64c1fc6839b9d08acec19560bf4a815ca6187635f0cabb8bf062e8216d3b09b7abd99e956734129e16a7c4f3beb850fe2b1548729355f9015c9bba336d3e26a27b3d75d75722f7a8170d15ebf77f325c97778a5a9d7c76d3e101eeae354e54e6fa60b58cbdd900751854ede326b58fa5caca073c630f3719d6f52afe675f10d464e8b58e5fde75a4f225063ca48d76efd1b645e4bc89d98215beae765601f635a3bc8cfc08d74722f3d95ccb4cb4e3ea977d0c534a4abb866fb9a31771222cfd998231c30bd16b6844ef71038b67d72c910cca40db7260dff0b74162449a9e2cf15d7dfbfb3a685080e6c83ff4341c95819c0317502ed49af7ae688b52c9866518f74d69b4144500ab9d5a0829b9287d5fb67b78801119ddae7a76e80be8c4dbcec7866ffa7d081406e51cf617be061530b539cca7e1ef9118cc06e8eb2a01425b45947a1d2332e360acd0654bba8f1fa43ece68467690d36f6802a32f03f9ea056e57fd548dd4a3225ad5006c6c931aef1990639498dc88a23895ff1f75520a8009dbde4debc20ecc546e378eb7ed5ea3740d2244036588471d96e4751390b6b76b39816d853944cb5677b493b36de9736ba0fa404ad4b3a7d7c54d0c15072c040064b871401b25b88559d059a9519c7e2446b0d110a4aba9c12555e5f620680d1fea2359bc85cd15b5c0bfd6b3715d647514118cd60483dbc9c83e285192108f4ea6bcbee1f0935044610c68d052ccaba23258d09465d5521e2664d59358621ebbb8f28a4627362c8397f0a9852e5d8daf53a961d4ee66299e2b54d8adf5134ceedef57011f810aea76262422236c3e1a478a759584c7880fb3f32389c4bd4b637caad7b2bd6fd295aefb150754799434e99e0fd45c1cc4698ab14d1f63eeb06e53797cbdddd45e7f87e85b45a3dd0df6335c3b1addee87ba953bde29ed98042d745c1465a967ef922993798966e1c8b96ad6f68404136be0caa2264e24d8d93aa1b99da9316c7780904753d4e0b45cf282b43a0c91bc9ff83cb25cacea2ea72563b2e759b69cabbb6a50d6a0a5ba545622e5ce576cc301ba35afadbfd1e26668782e1d741feed8aae894b564a425141442fb8470b325cf7c8e1552973463bf4e67a2ad58d15417e418bb91d2df4b1310a0a70ac744bbb4245efd2ae642609079a44cbf6be19809a5ff7ad6847432368c9749cfb336ddcc0e6f52a699b910cd24671f38af5dc39268a3c87771f07d53bf220b7c2d5058cc7b0bcd492abfedf9bb295ec304107130f0e98dacaac6dab998b511f176d48daeb81db53643ad194690b6e28c5ed2927e09a1e959c494b90db401681f67bf1e23fe9ef4c903f666ef39332a91a25c63efe9bc518e9aff61842007dda72dcc0264aa47543c0a8b1f0d25749ddfbed487282241140d4c64def1831c4d75ca975fdb03258ddd013445e08bfb479a516b011fe3a12e4bfca439407c0022889e46914cd41a4d92a25eaa57a55bc7337e5fbbd11584dca34adb5643105c8171e53cf04b1412c3107e72330ebf1b52f524b4e72570cfdc0ab179991f3782d05091ea57b1a233048bf062e88939cfeefb61e8beaa90395faf61c4d974b23723a4a5cd39d70f92620f8f4f27bc99ca67bed7fb6e594913991ca3025480ad791bc94a0def36fca491a206440ec31e32bb85850c3606c875708309be63c2b4f5c477521aa08e1d059cedaafe4fbef5523b79f88b57d0c81bbdd09202095f10f13e2609e833ff41b862b2214c22e8f2b04a363b38d26bf95c07b184b9f909ad3a92122e158d3566d2204b22d4f2f3ce11a65544ccecb01a4a5ef62bc969fddcb648224a5c7bd94f8da9a7d4df393d880f537a377888874c19dad357a0564d303a5c1485c1451ea55d68779dc0c11c7c38025660684ba3f70cbbab00d15b34c0f2342207ad548eacb32ebad95292e85211a8669b586d05b0d0b9f278a35ea4d78e97fd5dafca6b72d8e1fbf3e704a60a8ec60befe2e3e4d3d37f9d33a0feb88add59f0171ddeba0b79a52feb9a1f4a7a6ee7c6927bd10968fba788a807409346a0fccd4f7daac3c8591fc689aed881829d479e8d360cdb5819d5eac718a6f860f2d9ef6a0d36ef6e10efbb37819bb7b03ab7649173447b2cd47f3433a2422b1611dff91cee0b10c6d060d4e84a9e3f4dc194514cb67f1e3985be05c845fc92b41955d0f61aeba6268789998bbf341a8b37af48f07b13a676a11d27330529cabcd52365842be559857cbc2a63a4ea1c77fa8619040e79705c5b51f473e13b73fc09c28598e070dbbb63ce884c2843ec365d4c5bebbf815ee3314dde0bab6b0a71a398e2d9ee8ba2f832863fae7eb0c18adcdd17f1dee0df29a8409acabf516c8e6dfea5a264c1c6657f774c86a14cf96eecac18a41b1650a9e652c6c9264b03aa2fd30e333a9f24cd6b0313358e3c00943a1de63ca970b7da2cb8a0fd1109cefbf12176f5dfb59457480428b194e88449bffd8b8d87d05d30f9ffe9ac3a7442b0df3418acf9165b14242489a54b6b47ea543fed5de74a00f61ab2af553b60d8d21c76c42052c72e4841bd94cf88185c39287c04d05f6336ae581cf7528a59b2874795caca79f5600ac64ad5820a91c711ae5a1c3762028242c5c8a9aae89177ec4db5785cd07402d45805a2e2e970059e4e6483074df1bcc01f57470fb66f45ab475ebb5343b727168e355a6c25d42384e39802d7b4a8c54ac94d82de12f8de13630ec8c19f008f98c505dbbfb21b363472e23d0147d1ac555f0981e2bfd07c62d097acf930094dcf239a40699421b207ac2575b7edf9b1d772ab066362820c182c2c5097a47d1dd25ca9e0dd9c3ae94e9a8f0dece74cdeeec3a17803d5e11f037820ea20364234079286a7c291f3424292b0eec3e956513cc6b078a76a3b8ab42c5fb5efdcea1d438f7ae08507275b48f9588a15be763ad094885269efa7330f6fc9d4746997c98d9f5feeb6dff2734d75afc6a11196b35bb9fd0c0af428cacef0df2c5ad4e5fb4559f0f93af2fafad6fb77f453238f409ec71a912350d7b62952e4858927f620d31569242615345265ff1cbbd7fdfaff35a45732628da663bfff3d3af3d7b537337754554458a2d1af0e16aa8ad9436096f42e243109cad32fac1adc58d714cd3d0d8483c783006991f3da263ef5ae1ff2ea06584e45849d64a07170675c29f0b2abcf1eedbb63b6f5d9dba600996c7d5edce9ac69448d05c0704fb9f84e831b60c376b8a5d33ea22030e2dd3dd421d8e0a810a77c085a3861fcba214a8baf592d624d673fb34f906581d923d80b06186db8ce5fbef2bb750166f7556adfe93d4951a825d55b0bf92c9f25776df784f6aec808ae221cc98d05ce988fe6a13ff96083dba15500e149409b54345274e3633fa8f6685d6fed40c20a5c5705f8b37099a5949846ca15def5a6a427eb4eec72747f116366adcb9b74d3de0b125bdee23ca98ee6312f41fa3d9bba43a8d343552c969c41f766ab4341a42ec4cd6f4d1d4c4b1f16979e5389fea36a150580418d95520506fe0cb1a1d861e09d21c57d88c46e10a3c5ad1aedc8f2743f5c06f10d6da9b2bb3ec783c6f5788ce9400795022cdcec197f9dd3ee4cd26531e7f057b6d9418a0c52ecdb35a24a2a079b3d396017feca8b31aa55e3d5ef79c9ea9ccc7e3d0b47f28f273276666fa1763b3a452672fedc94557d984c3353344a8bc9fc833dee685e33d63540d0801d8068cf66cc48ddcb0d42cec881eae36fc2614f96ad67fceb5c98ec33fbade0e3049178d503c13c2d5d71f32f4582d1cb0f47a2ace578b903796768a906998bed2995798251d7eb92faacc19255bf12c0024a94971c185841113faa288beb7e58d4a98289630fb3d230f936eb1b9d9c7b94b5ac9d3a211c0b454a26e29bdffb522548a65e8dde3730918fdf0575245e71ba013ce08f6e698342a61a81b1355d2483e97c06462cae1cdc7787f4bcee4396a08dac9c14981f2a8f4614a31b019c83782d5d8370acf9db467d9d95e8efbe44274fefde5860c2333cf81593a2ada9f5bb6c2362ba97fd7c3e5bc836c327c66b57c0f023efc0c0ff6feae0e625df2f4e21057060170c844c86412700d7d337b1f7835a0dafee5206cbd76104c5a36623c7783213f8dd457b5e69a86b74030a27b3c30074242b1d97e65a233885a681ec5a8532bce9dca1998dc32c6b40dd997b99a6ed6288e0b9b09447e356bc5345b2133571e65d47db2c736a391970879103d4137cab6c0724b8e67064167cd5521f32135fb6ca43c1e118adcded8227c9dbfdc18cdce154108eba5d8c60e5362e8fffc5c9ae6ac2572188617e4ce0f432e2476c74a4227af64b58e0ebafaf0b1ce01723ecd36a2a4167b7991e28b6a9e81992fcaf7b4b906d0361add02104db83914f28baea26b50561faa46293ba5247e8263ac0347509c36405747866d2fa2beef44f366108f6a4047e282a477c28654511075ddfaad9b9844e18e67320a831e647d923b2720d65ddd9ece165c222231d3c3e7f0001d15e3c690e9831ceb369a8edf183133814bfd20dd25d50973bda58ad03c4cbda8008556fc653ef401ff76ee858c1f79a0b09b4232768e72dd06e42078923d5647cb310bb644feb24d6b7e9d1167c3676cd96f79965a066aca314089db60bdc40c2be4b69c569ec76b3bb74a43fe731bc869c9222ab5404304a513d4f7d2ec5af278f7c3d664fcde579bba7bd472bdc00a1eb4c46ff69fb7e45e5712919e8656a8887afa28cadd66461fc57f53d574c92105818a89f210d7e8aee6de2e78228b2cb03b850a6e77627f70f51bb919bddf61837a978dd4cec2db138c657214ac07b67134bd53b071e2bffa3608a0b0bac88b0ddcfc1ba4dea17191c9ad76ab8de72118893256a7e13e15a3bf98bb5757a78c58328cc4b380f3786f22c6be81884d213ec3cc2784583a47a4003a59ebea08bd06e290a892c937448e664dac672942b068b839593c442f6e1d22875e01859cd24c17d108696a3196ea4794ddfdf25721d3dd3e754d1ea884e5086479819452991403a39014297fcc734e56f8daae4d49d5c47016fc3ead550783df895542229ff3b034b5b722ae2a2b04ba70e42c174e9ddb89ffa60024aa16f297ac9383b2ccad53de4bbe4ea2fa3fe3d059d16b4b4fe9959ba3c4e58922e7fa2673f50be5b636ee7c79b445471ddf5b851ec3ac505980bb184c8fe44c7776ae9aab4e66ce31fe1bc00efced390a82f96b4866e31ba3ff832a25b1e1d00ec44bf525ae523b7102ba60c1d3a2e2bed004524afc90a064b325a258eb36315b1496c748f5407e922914787acb8b47bdc495e521518e0637eac4b1b4fe1adede145181ec7ef038d48c473d6f296b349d7cf874d329c71f272883eb7e77ff303957e159fd417d5055d82687448950dd149e1074a1785518ebaf7ac167e07f1f559893a20d133b59aa294efebdae1e19a30ec9a3e257203eb9a854096395825ef4d1e4ecf1f8daeadfa049ea6c435c50d67fd21c6f6b11a8be46502f0dda1715f5349df5330454316498660b7996432e679c73f1af33e529ac669496bde538890cc093122842e3e2e4bff937708dd4b1b1d3fc066a63824266461e4af9245032d690aac0ea5636c29606473820ee57b112e2bd68c0ce1936b7e76a7873cad678b26b560d7bb10a7dcad3f69bbf226faf2f572c105741a121fa1c55ff30b2d0b7339ed9aa4c9a3671e6e4b572800afcbc8764b16f0a61c4c1ff24c3b64992cd84f39d1a4d5532a7dbd9f7bc847258a33c509a945e53236cbc46b61fc6fad662c523eef0c1eaa4bc0a49610c8d09659e7bdfa858d2494dc3da0a54fcce229951d366fd17f4120f27ac77e5e6b777693641a853eacec09cc4dc08ff6ba22295acec61c5e6215eaf2a3a012461eaade8faa9cba630c5ce2bee6f1a4676d54b4a38b7b5cfb6c98106a4882ed88153a4f0bad3e0f3d04dc1ae5318e3b8f4ab1d122a548eed47f70edad1a164a9c5c3eb10fdecb24b0b68005b2e958980481834c4f673478d3f47d07836d3c1c513dd920042381f70f1a68671acee2fdd453a7552eba497af27127999a13a33104f0086390e01635d1a0b79d92dd43211c74047804e82d9ab26f97ee88e664871dab52a2a79443e39f06a6e8ac9d5e986252529b389d9ed0b2f55fb16ca65f6e90cc9a149065f499630f973996c1e2b6c53f2ab391b7d78cc6926b1684d066a3a74b86b3b633baaf3730acd28deaf18fb926e1ec9c1f8a2345103cc4cbec05345db57c5adcf062412f289607f5fa41194f69bc2f426a30c7a6f8d1027ee8dc96c9957e90fbd9b16475b82dfd8698195159bd7b4860004beb1fa85e6843eca1acbbb0b8c7ec0b865ed108e297a2d5f915304167e18d01e51497e6e3ea76ae99bcb849f7595fa74c2a6263e2bef65f1063bce05483980ed51eac5289307117f17e99d761337e9b1fb625a1b900e6179f3b02de57a0b5f52352298c8a2d2c816182ec169d2b9c0490097ad98e2edc99c6df683a4b5b6eb73ccee0aaf07e8cf8f2f632381ac407c5c578bc1c5a8d0915dc231b01b92dbd25c2bfd412995780582793736572f1e23ef690bfe6872c2572285cd737a4be91f4dcafef09232de77b315d73f5beb23d03625e031d2438081222b063c343f52565ae314ac47a4fe518b45d0c12f2ceabc5e05c20f607b97035afbe0e29249e47961d9cf9b385c065966b0c7ea91cfa9ed1b55a58b9aaa9de080ca05c6405fdf15bcef74177226eb225a47d532bcbc82a5ffed7fd86c2609b146d86f566d0b84f638d46d6eb696bfbbc62c4fc981a94c1d6ccb9f3f7ed7976ea7e8ff1d2a2d79986fb27f1401f25d5a83f64844fa9e839fc8855007b417b261d325b6e7cb124b27ede8ad18d2b6da8bfc4d4f50c3960d5a1c82e4557b16d05471602d2a31462e4bac9535c9a57389ae0613a674815c2ec10c19f529c9274896dfe49ab06889da517d482145ed8f57ba4b7c0434ce24090ef2459682a4f6342ecc382b4cd3409c3415bcb7f1bbaadfb7ec308eea8b6cb2912469b707c99a55c1754db0650616754735b85a41433a30b28e3946754f90caeb03c7579fc9982e6ec5501d6f23e0f2b6392acc435907d79ea11eb6955723a81c4f02bfc78e2eeb1d0408f8f06b4d2f6d20d90f7698c4e58bcfa993884424f8fcb602ef35d23737fb6aff220927e28c19043ae708fd9755256a8a1660d9c5827bab1b836a10aa23aea9c92fa3b25428b3791c5d25f3f1b63befd5480ac4192c966350edceea8938ecc608e0f063d16d427049ad62625f5177470e7a0d811e8d4273aea8f7377d51db07fc34d9f18497a0c2b5c0bc5e8778e06bf7460f0487eed54d661d74346eeada9090957159b86f8b68183e33d0c3fc134d87e068badd8789d4c7adb829fe08e4558bada5ef3f526afb2c7b6184244af0d07aa5cb525c519ed32298bb6241d900ead0532b0b1fc77a6577963e7a44627ed326741af254ab957ca0298a74323d2ee4f1bca70e20ff796491424e108e03c20f2eed7374c0aa2474a91f3ced6f46165c886a510734d606ceaa08822bfced69def33cea3662512fb42ecefee341d1b499b826ad882542374b032e907a7e6a4dddc4620a5d1002b5aee25711fd2dd6e9d4e90ee350f2889d6c1f4328e4b711fc919ef3c655311637b83b4eff39c157e0510807ec61714b843bc9eb22a0f4dac7e5cc07b8e9ed587b701d9aca2a239e76ac9a16338b74d50578956e06b1ac35ee3b822ca779922d89de7d915afd7d80831e8534b8f8a2eaed252fd862abc99aadde62d4520d9a7c3c3da86081fc36927de60e3479096a2b5025b9a789da01da969cfb0ab2f252c82db9e6663dce3888146b365080f649cf94f991312817147d8f0d1774d8d44ba4afd846060df2de1d1043659c3b94b1eff51fff84e5a81a0c635aedcf677285e0d722e3335449fd0f49a41264fb963ea5bba31dae469c789047812071d8853291fd8003cc31a8968ce7acb68a6e0172ba6ee0e9dedbebeb62143047336c5a91c77085afb01fc075938b306d7e36383ecdfda55b9b5dfdab53aa34000289c398f617a146c4a06404737600484d8d4ea960061ec2cb575dc485f65f275540d0ce7550da08417632b6f0f7d044f6f719ff839aa3e5c9db94d45225a1cf0bdb0c5bffa781572ad605ad37aa988240858c9493dee9f00ed281e93532d89aba5e9e59ec430cdd5edfdfc2ef65e094eeab71cc40b59c997943a0e0dbbc80f1e11834bf3b53153ba1c1f0ccf63b3c802439b2ef1430be6994300d9b2efe4b84e25bd3bf8a566d4851e7fff57cada544d722438e8980a31563ef0558fdd8db9bdd6f1a3e34f06104b680f63c1f80a08ec6ed74bca69bb1023fe63d24c7e7a14ce85db6e21173f2ddf14f233f3787a37e4b347e4d64907fc0a23c3da017c81c27df9fafd4695886d0ddec8c47982912eceef886ab5680a130bfacbf3c67bb4f0cc118274bdfed43bbc2ba56f048d6a390e48932469b30ac84fdfc2e812f32d00a85349bb22f2d8091e64282fca1b40811db756059de5d03861d6a22cfc6289097d23c26c5e3f000f9b34a0e1b28a1269d8673d09107b29ccaa1adc8939bdca312c69ae4a238f45410d8f1b27392d594ceea2a6b42899ee5c5857965b29bea1bc413da618899b1894f2adff3b3a7b05a626e50e42379f5d0e0a148ded33d815f59d1401b197a85656466eaf88ed30d1ad4a87985570291efbb3a2c6f22c0b111e65c843ca3c6179e94335f0f91d4696e1a31107948a042f55f264c32a35e719668483957c9c8e13fd01e5f751870a509f5f06ba41ad63cbd5f706f25b1e598f6c9709ee6bab627211bc38494962e930779ed4ea2a8471d309c4c4f0603238959cb13476b673489696c87ad9da5fef0d6467145a77ae0b1089c8626988278a85be3292680d9d7e4c6866f19b78595d611f15f9a5e37b3d145d5aff4a5b58a3286bd25a862904817afe8e9b9105584af15f54554ca5e7dceaa0fbd1111aae126d74f68bb6f0ce98094dc9a59a31d9526729efa171beda9ac5b7db9118aa94b9b5ad58dc20ae1c328e31269244d636139
+Ciphertext = d248b9e47c303f735b0d29f6111a742d93509ae051466688d56b587104a74fab1b259da64475fc0d2c3e28d87ca4edfeaa5715c23dc0e5281eb0c0c14e22182bb02f9f7d3c24555cd6a3ff766c774e67730a920db5f85d47dc23bbbee460f0922cd7ddba81ccbe727b4b489e79a19db2d012dad2a732273dafabc0fbded3c47dbe5b6b585570c39eb62850dc47f4aa0c29bf5fadf334041fdd4658fa6cc29a81192a53dcf47c03ddca9d03b33b06e5b3808be77925b7e7d8cf51fa939e023161d969f92430917d73f3aa10b83d5b7402410280561a27c376ce0b5151a51be2ef4eb9057eed25a0715436233615dcad1559fdbd81042544441857cdf46d72f5f50ee552cfd3bf166c530e57fd97f34e2e71bff8a90b30b4c4cc3e843b0f06e4eb2ff82675e428f5303aa9141dbeb615cf6aca5540fd7cb756fe5f9b08a4abdc6eb90b2eaef51c21eb9ae79a0e44b0755b3ed48f5e6e57f3148ce02501528dd3dd2b0bbec2650710a183e38510990002ce6498dc5ce7bf33d699dd18b66c0f8031d958b11d678674c355a635f4b5e8d863785f5dc2f99eba9ce74595493c017697344b651dcc2a0b1d5386b73abd8bb2dc77a2d92173d3688d0d704da9e44a6385af9fb3a81db68822b1eac9ab284f0155c20f6bc34af85d8518d0dfd32fdaece1379abca339a00e1326b624b3e4050be5db8dced5e6c4b88b82b6ee2a48c373d236ea3565ecc072e953ffe01b624c6ecbf534678aad9c3f8a07d7dd7232134b6b397d0c96ab5f795f9e3af65b96e7a765283d8081dab9f953113abe06e8d150bf9a8416d8932fac17b032dc346be43736dbf066ed239328803510f6f62bc8abc92f6df9a82c02cbf85de91739bc8d7805d392341be99798079419540dc952fa0d3ceca4b806ab1db3b717f0d720038343465a8bc0da8e8964e58634e8a2d6c99230af2ac7c89acd3f86a22075dc40818028f3c632b36a39c0e064e3ca2a078c617a3e73aaea56ef11114f9efaac90a3ec8f8d9b18921a80d74b09ada83efee127f41179dc6c19c7965f3e7f43e22f636534b123e9246172f9920f253d2a2652a5e8c337ff93b2d479bef5e96e972a9b9cd8af057c750bd711010d59ce065ad50fdd487b5dde616301d0ae6373b6f9efae99d8972f242dd7a6bc61caee70201869be202fd384a992478dfc133b84171f013244c5d17585934aed3b43b818926246227d255bf832ff481f5f8d074ab159a11d6d17ed0ac50f727b870db966e0373bd3b1eecbf9ed66aa66caf33ac57cffe4ac6df3cf7b0e54ac54be4f3d50f61b33557c2990c908a710c85000ef6fa62716960daf918ae3d81ee60b3813e65673bd911ce468510bd230b9c2d215afe86ec12e49e0ae87e4235baf3df237188f5e0af2e61c22a4bf77190dd5dc804b4cc330b360c3dc093ef208c37d299ea0cd2ba906084011e16ac5f4fc9646538d5b538a99546d34a4599c8529c1524fc4b394d6a9cd762855905233ed92e72c8b538372ffe2f0df7085eb074616c7e695d7de40779e384d5fdb49fe02385424ea991dc05c6ae813f76c673eb45d6105bcdcfdbf04dcdd20caa6e30efcf3537bcf72947e1ac37d1e8c600ba9238569a4b3afa590d61acceb2572da85885146a142c8f8c60afe4d53ee4d61f33c47e5a99da9a346bcfbd013754ef39a4d7f16c4c5fbfa53d7f180c16e2b64f97dcfd65349939b5fc167c7a78926f638f1893fe9a81e897beea3258a4175d14f41dc123ddd846e45a87f35154db8a5ac27c7a0fc95d3b3113cfa9e7c828f83a1f0d91ab7789c33be5f55ecbb8eb0c81bcc0fccc880011b21000e2f10773388b198ce79c5d694472d3ef6b2e55c342b29c70e4f33fe59e2e0bd3f9ef617733dd3329a0e426338d9c007bcdd382522cb96e59b223825a39b01b52809f5e8518f64b81c99022d8215b5c435d87cc1a57bd440b31a19b197b277b2072968595ccd64c135ae1b218046e27a7f2685d013ce3173efd07586dc72a28ac4792e804d44f9efd785ef005213df928560a20daa4c24ab07f081479270a0dcee3c26331c48a164e4b9d79a7c30c77ab06b00e9b72c190d35fb873bc095d5e6231a89b52a0737a99532079bcc72ee221b48f0d0d9ba9105f981beb4225f6efc1230d6da10fd2b58a65112a98e4bbbe1accd6e8589eb6d9c771bb911cccf42aa6cbc68d1976f0da7eff1e70277e8c5f83734ec1efb2b00708fef08e986bd6519a0fa4b5772e585ac8e37fd2a2af07aa382579498b3b75863fe792461492b8e71c4a1a2f4421705696a96601317cfff1632784b5d75fc2036ed3fa650354620781b9fcfd53f1927223fa045edf4abe7b2144512f3e3aee99f7ac3e46028bc2427aeb18e9cb40db57b696ea884658abc9b7bae0d8117f93074a3ef903528f8b55c7687cf9f0119a1f246cc9e993219c6384359e7e5e639bb294b264048060224ae168d7b9f1f795c07eaafcddb10b61ac2be3ab3e1fddf75c1f47559f38d24f0c773d0e8bc5fa85d7d33e3aa8d0f15583b8c1e7aab6f5d0e085b7175678bf11cfee8eb069b78220377819e3f4d28eb833d3d21efff543d5c6357fffb4a8fdd6ce399fca42e2d71c53c50f6b20bcbaa1650b57ff483837c39a37d5e978393c332b43021508b8ef27773164d69d0af3c0dfdc125cf30a7c49a7d8e5320d68a35e80cdfd62a0b7ce6a412f08c8062e35265fad5d1f226d590e9b068d09e48772711d7dbd786a38c0325b3d5665c2ff45ad0a20c174dc5739896ac727b34f11c7af299d36d30c69bbdc35770138cf891cfdd8123489fdef2dfaffa9c2548ebd60b0f0bcedff44691979b4e92b364753120364dc2e3b895095da828e8659575a85cca587ba05ca625480f977a6fe10181ab6ce005defbcd8894f8c71811909cd6b56eb7ffe327f46793a9e98bd7fe8951400276bb9c7607f8ba1e633034b73d7f0d040197c3f346394eba68c8accccefe05f59cb7ea9ab1ae2e172d8f466ee21c6531cec2c9dfeebc477a6d98195c28bccc1d5e23ae50e3a1ddd7de189e36ffe0e387df7be43427b194b16e18b42eacd517bba78edc9f56a2c7e89e6f13513718869da7c8c529bc337217a69e14e35cf97ff7db2c23700347f0a33ad25a299fc52b35f63949735ad864aa127053797541864b07168f89ffb7ba5c9a8bfbcb4248383a95f45461a7aee9c658c5679205f47144ba4a06175e746037b8cb6556f06405e0d537d0f2bcd898dd5fb987d96dbce33001a50abff5b9cb0161dbfe30f5df5a161ddd8a750b0cb33898c110415881fc81239f2e25440bca41a5bc46fbd3787e6c8fe8a463415cd9a82be368a02566da740dca8e40e686e1213d9c15de2d3556a1e1180b298ba3074b4ab93e469dd9a39ac0c8a173b04a5ad913e72e4d7b5ff520f108e1a1747c11b6b2fcfaa89b3ef7e669f8ad9620364b4f4f0f9ab274e76bdd631df033357a24723653e427324d907a9eceb3c375c43ee36cdeb046a6374be19ab04922da93d4dc07c5914df06fee97dd813f5fd501ca75e3c5ad53574837f2e51ba6a257134e8ee0f4127c59840ba8b1bb13592dcbe47aea50e453c7837e91bb12ad1c74fd0f149479bc0334c511a822145690a3a408caa32671ed05c2dd219ea360c67727c1fe6a6cd842301761e94bedc73f93de7091b8b6d2783a788313b2fa12595904bf5d1167a5ddc4ee151b1522de60b7293b72a62c4d08b396ed682b6a6262a212ddc8c70dbec1a972cedc09f593e21d843279561884f9759a593da7b17a147db7559f19d5d6f43ea98012872f974306037dc0d344c55403b35a5903f766359341bee5bccb696fc0fd1c7aa8803e4c2f9e6e23d386d3a202027c5792e355592efab9330af330392a7c91e3cacc4e645359edafd78b77829374cd4b644817322b7650696fa763a0cc7143f9ec7e2f6ab3c9ec2443b0c0b0a31e9eeafb7bb8c375232357f08256959a10a6d4bc98d6cd9314a2ce7feaa8c0eb1eeb15047f715d6ae9ebd64238d648ed6bc50617a360d8ff9a01aa0ce0e29338d34bb9612751445372ac6d74837c7d2d67729760216ee33476cce1a154086ec31d986cc5a14e86561c6929554fb280646164bb03e8e52588a1b947960a77d61c2d2499212a742e1a5b78805b5b64fed141d3c4834301b8a8bef31ce65edb539fd9469b590a6980d0d1bd29e34a09f87438059a09b1ea234d1bb29882e67599fc1e417db9d86332077cfb05fe440ad1243e26a67a0ea30e63cdee8850a543d76e810140547412fb1400ac87a10e3bc77d3918750a5cc3e7a0efbd736c7ed4139cd5855ddba47143362bf40b91fcbf27222017c1552360466483e67ed125745724cc713c713dcf7ef6ea3081d65d8d78b903382717848bee7410431e1040ec92373f75a1bf229816f55dcfffb6e6da33ed8e1e8b05f9348cdcd6938f053eb9f93e0de639e922627bf61a6688f9649bb9cdfce6236a176db8b9b53ce4b5f9eb9c0680c92128bd327aa7f04a745025faaf117a18d5664027ab0e3f5898b834e1a75cd4b4087637733416f8bac1ccd67cb4457005945676d03f76fd0453fdb9968643fec98d28da7c8cd7070a803b14a2459f073ea075fd023a896d3306fdabc54416e95907103cd2fb642e301c71cc48e8eabedaae356582761a14e0b3b0ef1de06002c2acf594c85820ae3a094e5b4680566b592221543c1dc5192d6b208e86b5aca91d4e3454564eedb3b8208169ce97e1632b864f1d9d4c4c4c0fd4bcc5206e8f6d64c7cdf212d718cb5b7c7ee21593ada3f33f5952e12bba4f46cb99044978fe75349c6ca735db35891351d7e5f02a93354bc45a9ec756453f053cb87430b3e9211807f81ad99b6fceb8ef1b2d655910e1f5fd22f2ee90e42abab230f8f39a8345eed6ad294a0d32416a253f829093ecae209bc1dbfadae04a373080f9ea8394a28ddfe1134309bb53ae571d2019ff2bd4be94f8176d90987fcebad323f0b2921b85b2610852973f383a2ff4a5fa82a77b13cfd50a33f29164a9ff409422cc4cbd772132856cbd08470b220ace957a6b8e02c8003d750539a38a8df19a5b662907b72e3098d77c2fc3ece0693b47ff19ce911a93b6adce75653d48ace6af10b8f1141437f9206658707b16794e349db3f1a02606ea167d0213ce3644f64ced64de3799b1729210fc31ba1811b0c226306f2466b230ae35e6d8fa11c8f932e27da8cb1bd311919bf9178ef08bb7a2b4ca2d2e6e9585ee9f916991cfcd4862f5de9fbbc63bee6edbdcfcec9173a252eb59fc6d6e58258ca8b2a4475acfc1e09a0c9566d23d92e9ada97de51895bfb0867c42025c8d089c65bba67f4dd84d7c5155a930329345cdf3b1d6e910e730df273e183190beb900344bbce8c3bdb13a7e4ecbe967a61d47921aa55bac2bbb24e3e03d386ddbfafb3b32235b5ed922ed6ac2c89ded1316b69079b826507d708a6cca14ce2244a67be90fb91ddcb0c97432703729bceb432bc856f5eb9d2f169800a04283b080f0e053670a21468df9414fda9f4153eaf1669a19ede7925f832280800f0063ceee34b9d3b0f8da2012525fa7927e76bda71954714d5f51405b920391eca2ad71160acef4091878b907974573b4cf1b377baca0340ab0e4ec546fcaa6130603ad633c3ef980e88d8f44ec5de743cdc6cd9e0e4cbdb97a5c076be9ada8f26bc54d711facec16a2401292cc167bb98cdd320ec9321414bd97498f6d9b54dbb45ffe4b3e3f88260657ee23e19de48a93595c8e3a289a02d76a27ceead05d591633464709aca117c26aa49b64667f2a3b6371984f813d7098fae7a6ba1841775b52314a06c80b4c994ef8100e233ab3115ba2c39b97f2d5082a145720ad0b12b8a7cb275ba848b3fae14fc0c82bf0353195c056b302e508982f73a8519cca722892482b9d9e6a58bfb4d862fa393eabe6aedeae1be5ed772ea3c94a0df1d9684a131c35246c68b32e46aaf89f3649e58b2e99bd6bb3923d3ab43cbf73b6b3d19fe3b62bef178f46c79ba85e23ee4b25bc561e8fa97f51605bc0b210b02aa28242e81dae9489076d259f17d25b93b0e8a2010584d907314e3bd55482f0fa43d37ae9535629d28d6f837360bb35ec869d2a959789dc49b9c8c515942a1e03650566b736551a5180a60279bdb0ff9c387beebeb9e59ed930b3746464a010a6f7ef1de3c7d76fc6899b1e5ed98213813ffb333d969ad72fd8537ef4e12ca7b78d35c24f44ac82da4a7116492ca2efd86ee6a4474014e72a5cfeee7f729b77cfdd1a5d10a03f3cf28f1d314fca36d31ef2ecb3cfccecbcdfd22367b0a0e04435654286ae3d4fee13f56bb7cdab40b4e1dd01f9ef857f94a67c1e237e24819949935ff3bd73b0461ee9020fd0a2db2cc6312ace97e4a8a33c295271453a12822db8d1438f22ed0d466150990dcb39ed042424eef7a1210c83224c856923e3251484a81a15cddb4d7ada8bb7968dcc8f85e39ca99ece8ce2ed7753fcee6900cc9b7b5691f2d67ef9be13f70d195bbd0047908025df01b4f4d581fd59239836578627d9d585ebe9b053d807e9d3ba25405029a148938a746636decdade02b1afb5ccbf2f0e14a27c98a1e130d9208bbf7da4bb4e572927eb348568921d4a3309a2c24f367c935c2a8e1524c3024ff350ac7da8d2849586817bc9d46a08a21aef035a6151e608ed93b1556a484e455819f9ac2fb155020738962e7255a82a0854b31fe20cdd351c10a33eb693c9be1a51a932e04d0364ced41ee1bf800d0c12ab5eb37fe52563666e52827720e856d4f24eb06e0aba446910aabbe36513f2274362fedba4c19398433029495284ccb499bb559a9cdbc94a0d1b733136969a743945a04e1d2d4e77fed21550af35f22651c7de802eab7a3942d7ec55a3a5002bde8d5cccc1d4ac4bb7f4926615fcece543fe5d9092d2c4f50d94fd9868775a072f4a5bcf2e5fd10795f7f172a3341ce33505ba68e7ebedc9c1e9165864244ed31bbe5c308dceff858cc42010ad8c281a24689cf2dee8a549b1abab9981d70a912174944b403ce664d8608b2f723150f5c12164e4caf28676e7a25c3928ca2a4dbe96355ef8f282e57888d40715df07bd8b5895549ad957e758abf868def1c1f5e260d26498616e2ac962bcaa33b879874569f198a91ce4e50fc50da77fea1df9f9ea900c834dcdd462d338efcf8e612aedebf254fac596507d175d30a90543627cfcef6852c7cda8b430e255c4d6d417de31eb5dba123e3ce9e2269867d9a94fdcd8ccac40a9451953085109f5ae0c3e04daadb4a2a47b0e176917660eb3c9f1aae0ec6b00635fa387e056623947c0621f0a12e86fac1881ed1dc1b9f523388d6b6596a152b3e732c561972879dcd3f0232ef0773a4fb195a90c3186c4688ea58967ce7f18386b80bd38e90cfd4cb899337ab27cba8db6523e979b4c449645bb2f320ccd28578bc7ec38f47225273fa61a2e5df97c4d76c556fbe2b0fd30e615f5fc82c3de7194caed9f5946c151c22b7a0c48f4a7cf78aa153414f2913c5eb95e3dbcea7ca544272cd13a1c52fa87759aeb430aab144fab418c835344605df3a044825965ca15de6ba0e59b2080f5844b2d110d71587e19acf14264cec2de5b8c77d18893215d1c1da0a940e7c2ee429a99e2633c216aecb7675a2314a09044951ca5a8eac798f8878fb5ea65f4ddccac53ee0c786e597169079fb6e8ceb37a71580b0904a97450909ca454a690821e249aebb75449e582fe1b30f1fa9f6464bdef654daa5ede6d4f223f4589ea25a25f4672cfbe974d51008bce296628556f55d26646e40b59f40e3149273760b40806ace3b5171e0b79865c6adb53513da2f24c4115de243150cec76107b48ca8da19117f00b5870e67eb8357e43c1b7b593c9875795d46ede26a109e05406b69fda988947e49ab195f22454c3c743c2ec51b91370b4df8d38653b353e51bb83215d122bcfa591009c007bbb6124bc590fed3f9c5699180b3b1424ad02f7c90a149b77d22dea5c996aba675c2a1a20e206d9c25d9446247d495a26486c0d0bfb09d0b5a1a177a09fa749dc36cee73af0116a6b779c2b827512a04ff0f60b483edbcdb33d2a18339463c498ae67ffa9da0aa3f3beb6bc99212f9e6961afde89045520b1f3f2e2761666a333d76030f443f53322f099035584a60978ef8b49f46d7d4d8c5c758ea52a04b59c1a3a1c2f9df3f3b6f5c45cf4b3547043b18c1d615a2c965c3918d090cc72946e8fd0b938e60e03464f4bc71fb719a1d173b0931930e58bf7f6d4403971d36b40f83be6b57244a7029e1d41dc908764d57a5442557218b509faeda4e9fcf31debbc54ae671ef636871233f29e0013c0e33933543f4b59df1978ec89b109c3977b0cf938b7f6166d6c93be5e87684a703c8b7b5fe1a8bfe153a179b55575ff05e599b39e32ed10d958699a1ffe07136081f0719b18c69dc74f66f211103e9c544f3c81a88ba9f66a9bc7017d9ca9e2cd97634052694a598476b99daf1cdfb6122869375ca5873d32d5c1e07d9b5b380b4f09dbe04478cfb1a13853eafacfed70c8abcd444ed095f78d07c0e8b4093be95c3aa24b2e5b6bfe3a06e9d2d9fedfcfeac4cea2490627e6da6a5cca383351952f654ce2b0ad359c0f7f4ad3f8d1d4a030a947d4a2e417bb79102729115cc8b6558c3362b1d805fb48ce4858deff97677e60375ed13e150a12ee7dcc8ccc64d9710c7f516555c1f7a1a08f0d7c6fd21f864fcf28c8f748c40494e01fc32006f977a5100577f86a484d11b82c90cfe6b4d6b1902fef486cc6f3e033904e150e67283e49a5382961dabd244412ca9657b48796e476a82443167e277d5a65c0c563a6abca77d316e5d3ab639a1ecfb1110af2d29f146508bd9874486dbb56328d6f59479e2766692821660462aa60b6bc8a710707ceeb0ea6429e5113e03c9f41ce0d69c7589deb547527673e8a9f9a9a74e9e4bbcabf2e306b35504c1da99730ae86e94cd047b2e6ea5e97e63a492430d37ec446434fb3b066adde08b17d7d903ad194a4a863d6cfe181a45c8c97b5062bf7c4e44d69c0d1a7e1f5029b805b7c21d1b5e56e697999a32557870ebaae8d87dcb5ca5eea2c5547a16b3f30ef9df8df821028c106f86e091050ff8b6ea4171e59dc2592d405073bea53f8ea62edf112dfbc7ca69809db8005783d63557d3d90d123a944be395c1dc3b5e1476dff188346327769fea65f3cf9363e88ed67335870ec8ef13eb9d9ff5317c4e24dfce9d11699e5f47b4233cc8f9d1b915e716a5730a5898ee65d30b1628b484a5e82eda95a590964a8d8bc89dd3c5cf6c4f9137b8c6ee9d6a692e0c0d1d858dd5b3c12de48badade4d01bff312c56ce3ddb34b0fdde3b0c2706fc292b9fac7e1a0dcd0b6534c968117f7de15eba84d2754e4bcb8093a5440297605598659f686075e2b1b464b6b3ec68abb13cde263b1c607545c45746338b9b207b5c381da690f653b35e363e1249551ad938b9fd7b0a944151cda07127bf9ba76958e926472f4aa1de8512ce834cfcae5414b226f23acdb1fe5cf685d2201b78167ad35fc1da282744c2a43cc49d49242f968f7e06de14455e7ef5adedc5b33184346018114e2d1fc7a5349e378da9b2af5b328c213888652aca9f1145363809eca7c1fd8e64a5cc3255418736e048a731f3053db77971f67014e6121a8e464833e5dbd02ea6caf385e43e9f378bfba657986bf852b32adb55e35a2675bfc8d70d43a902032a61f59f57dad2dd7d7963322136233200cb9a90c952074e9ba0fc0654f1b6fd6f7f0eb77c0fa6d8143213ce6e8b0c178f73e17a7c64839f9bebca2fc955ea8ae406a13b80a9045fa8d129fd859faa46fd27c48bde7b890f98ee938c0d78889f84181ae2f5711304fe554d4251bbc6437ced59d577a2a1f26da736193c3674adb13cef9f4cb4aa6585c4d6874b0309ecde300493b1642c595746f09e03977c8902f3a4a877db1153b248f295a0ca2f1e437d15fcab8fd77c5f967304efb5c4920b990674ae61b954af40be17a8559dc377c591b68067fdcaf2d27bd9a22041b981a84be3de50d5962b58f8c4a22fa05192c5ac99a0a9423284fe62a3a59f085136cec72cda2a53af106a2eb5bda28b6e02c299118cd91714c2e7d045346c78d9ed1b41c73231a21e42c298949f70122277f4134ed5c56639edbf3c3e717310e3d1f03dc5a94e64c4ce148bc5c6bde64eb80b17d5979892786a31225eb89bf9f5a582bcf65b83ff7aa361ccd9238d144f6a22a3f77dd8a01382df4ee90a2057dd310a6b0c4b81dfc92a2cc0c606d3be8b18fbe64ddfdf2004eeabea892be2f914edd1edd8e8829dc7704d71bbaaf08c41824dd0f4b34c9eedead9e10e53bfc6fc0bd37417de0c5c71cff0754d672f29c262d8e27b524427e12bc4e4705ab311d3bedcb1ddd09a3ca0c268c05c64951b7d724a9dafe4d249aaabda91d68633aaab845bf78f9a22d467c7e0c5fc70fc9a318b01d7492efea7fffd329d70692e76647ae665c62b280da0d62f870a52e4dc4cd92c9150c96aab16f8c23475e3152d4debb41b6756f000c3d8aceef18b49e295be7a71da1eeadf4eb96509d45d7cc42af4b7013d8bb445f577e8d4cff92770b8ba0e451f3e24c6d981efdb68c7f2dfafee40b8a425955796e369f0d4da3e998c1626ae0fa583334475f1fdde68ca211c3f2e9afb003f553191702e11f8b731c89ea26059ea4466f2bd0a1a5601025ca9417006bca5c9a57dfdba44c603ef9ad38922623b40feda036d84425c47fa42973e348a180a7570e1215044c375313ab08d6f521052dda415707ebb74d6c4774e039bb04cadc2799224bde1802e2ee2a018032e3a341700c0fa2aa28bf93cc479231efe7da0e9f68e572415348c08cf648117e9b6d1267fef6617f5927252c86cc087775db3e30180feb5ce7e1ac9c3761161e07a4853aa6d97e525aa88302954cf9390fde81f8e11d97a11c79e3bad261364c18890dd1f8fc71127edefe3571518a42be611a46a0426a33221aa25a0ae6514daaf96038cb59aaba898de49e3b215a4464e0af614e638c2d9b6e676ec427fc906bc516331a18121f306a5246d179e2d3d0f38ab8393f7ea5a2d24585e7cca649637b9983924a15483c167e8780f8dd7aa1154cbf731745a8d8d54a8c4f8d854371bb8172303f9ba3c8c7cfe8c378ee56bc35c6376aafe907d3294ee9a8786281b7deff78ff125761f1a31d0e8fffe04a52a7574eeb8679670ca3bfb740167a559488d4337819613d32752d8a89013622f6a8d70f3c64b84a4215f4b7bb282a2d17c36a326167e3270757b8f1d9a0137bfc5ec278e8ca35a69e49779cfc25b95a89cc18732b5b9d1986b18878c57e118506909207207ad0b4edf32fb2b35b6e70546f45d0849bd139ffff9d8ae547787e7b51403b54f110e2ac65468cd0910d80a4e321deafd46e9af19609bee1efa41b762b8ace989dd681503539e7d9948664cf7a73ffac9ce2a34b514253c4f21bbccd38057a6d68732930dcdfc9a32219b53339d100db0037a8bbd101e71f5054f3
+AAD = 7b3b9c07148fcd897f657ecfcc87e530191536b8e77f9309e8d7323888b3b21477f2ab7c885c105d9c29ac96aed23b366f9fde4177401b7038c6770c7bd2ee8b4335105cc0eab9e367f0cea90d6f1ae3fa76cd21ceb9f3500ce7fb4b2a3f9e90f900a231ec693aeced7afb6821391d1f5b1b957895777aa7a2b71d9571c00336f26d54d756392cdb74bfb67d5a621d517db20441f74d0940180baf613b09452f64224f8af7bbc864ab4a8434ff624d0c0646ee07132fd376506951899bde975df8c836ab4ed9cc084f1f6d500ad56345d2f250a0d6991b9e458c62b6023191f341c8659e8a38c878cfac12b032674503df9c9bb01c4340c709eb6dd7c74907d769a317f4dd7317843c47bdb4c5e1f07f2380d464b0c47269389cc8a43a09adba86f6aa8f44c8fe514e73b5fe8d344769c1aa20a4538ecfbf47562ca79fa497b0f02f103f75522db9ead50d56dbe86997d6085f1b5aa7a4cab9e51a1247ce4f724a14983b6bafd17369fac973c6be268e20d800de870928e100990ebb0d3bedfceda36c64be3a729b603bce677a49e8caf282c9159b6e3e1e775129bd30dc3f5c9849535d86a27474be03bb5749b4c0115e2614f8feaa7405cc69b1de479b3b57e551f876a9c8c57ab9879cc68bb2ea110b2e77e59dd6a65eaa67cc4d4b2f4d6e646b2a298d3c80fb43969275d4414734e74726145dab06124c040656c39a94846e8fd58d326f4f9eafe5b95d85254765a21993f55070fcb9e85db5d42ab6b9464ce66de3f236dd2a0a26c4e5535dbdcd6eb350209a65aee785c6647ad4103d092a8ac932470880eb314f7c98cdff34fdf35ee2d36f09bd443b5defad7a5acb9df55965421fd043def6f4771e1bb27385b30ba22c0d8972aead6b654085a7dd3b60c4004a0dae22e25100e54e0badd0cadf909799329ddff699de8066dd6c3822d80c73c52d87e6fcbdb2dbbf852e37804b1256e23e76dbe43f30be4a577bc23c7941a3d708d1e1f579e9c6eebc219c74768168f6790a41f883790e08cd1e88ad09a544eb97b3d1d5af67eea666b9c027e5c7c976921189b955a9e605f6cc9c012c1c2e197c5b02504cb9ffbcb0f3ed778d540d5194fdf5d38dba6340c93da7c5501a082689616f337d8b59c2a92c25e777515726e1d7f6cc9552693cc7c30f1294b37f97d49814250d6c1e3eb335c5d214ef3641739d508b87106eaaf367902433a148ca962ec694409acb82d7749e1c88938ad382d0ca6e6cbe8255746832fe737c3e71dae8397f260c98d4a292a126ec21935c24096d2f91ae114194af659455d8a4206197495a28474dd2809debf5f550d77ffac2b0db521559910c352f23472d7aa9f4dbbdb158f40aa36912cbd918ae4c642e76d78d57ade1075c4fe1086ddee3d554353b4693bbcef1cfa87e49890838c36156af0edf384b0413d6d7aa
+Tag = 51cbcf4a2fd82f221de1bfebf86a8c24
+
 # OFB tests from OpenSSL upstream.
 
 # OFB-AES128.Encrypt
diff --git a/src/crypto/cipher/tls_cbc.c b/src/crypto/cipher/tls_cbc.c
index c541db3..510b4c7 100644
--- a/src/crypto/cipher/tls_cbc.c
+++ b/src/crypto/cipher/tls_cbc.c
@@ -54,10 +54,11 @@
 #include <string.h>
 
 #include <openssl/digest.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/sha.h>
 
 #include "../internal.h"
+#include "internal.h"
 
 
 /* TODO(davidben): unsigned should be size_t. The various constant_time
@@ -146,7 +147,6 @@
    * the MAC's position can only vary by 255 bytes. */
   unsigned scan_start = 0;
   unsigned i, j;
-  unsigned div_spoiler;
   unsigned rotate_offset;
 
   assert(orig_len >= in_len);
@@ -161,16 +161,46 @@
   if (orig_len > md_size + 255 + 1) {
     scan_start = orig_len - (md_size + 255 + 1);
   }
-  /* div_spoiler contains a multiple of md_size that is used to cause the
-   * modulo operation to be constant time. Without this, the time varies
-   * based on the amount of padding when running on Intel chips at least.
+
+  /* Ideally the next statement would be:
    *
-   * The aim of right-shifting md_size is so that the compiler doesn't
-   * figure out that it can remove div_spoiler as that would require it
-   * to prove that md_size is always even, which I hope is beyond it. */
-  div_spoiler = md_size >> 1;
-  div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
-  rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+   *   rotate_offset = (mac_start - scan_start) % md_size;
+   *
+   * However, division is not a constant-time operation (at least on Intel
+   * chips). Thus we enumerate the possible values of md_size and handle each
+   * separately. The value of |md_size| is public information (it's determined
+   * by the cipher suite in the ServerHello) so our timing can vary based on
+   * its value. */
+
+  rotate_offset = mac_start - scan_start;
+  /* rotate_offset can be, at most, 255 (bytes of padding) + 1 (padding length)
+   * + md_size = 256 + 48 (since SHA-384 is the largest hash) = 304. */
+  assert(rotate_offset <= 304);
+
+  if (md_size == 16) {
+    rotate_offset &= 15;
+  } else if (md_size == 20) {
+    /* 1/20 is approximated as 25/512 and then Barrett reduction is used.
+     * Analytically, this is correct for 0 <= rotate_offset <= 853. */
+    unsigned q = (rotate_offset * 25) >> 9;
+    rotate_offset -= q * 20;
+    rotate_offset -=
+        constant_time_select(constant_time_ge(rotate_offset, 20), 20, 0);
+  } else if (md_size == 32) {
+    rotate_offset &= 31;
+  } else if (md_size == 48) {
+    /* 1/48 is approximated as 10/512 and then Barrett reduction is used.
+     * Analytically, this is correct for 0 <= rotate_offset <= 768. */
+    unsigned q = (rotate_offset * 10) >> 9;
+    rotate_offset -= q * 48;
+    rotate_offset -=
+        constant_time_select(constant_time_ge(rotate_offset, 48), 48, 0);
+  } else {
+    /* This should be impossible therefore this path doesn't run in constant
+     * time. */
+    assert(0);
+    rotate_offset = rotate_offset % md_size;
+  }
 
   memset(rotated_mac, 0, md_size);
   for (i = scan_start, j = 0; i < orig_len; i++) {
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 53f45d1..2496f2a 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -44,7 +44,7 @@
   }
 
   ScopedCMAC_CTX ctx(CMAC_CTX_new());
-  if (!CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
+  if (!ctx || !CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
     fprintf(stderr, "%s: CMAC_Init failed.\n", name);
     return 0;
   }
diff --git a/src/crypto/conf/conf.c b/src/crypto/conf/conf.c
index e098a2c..e4fc428 100644
--- a/src/crypto/conf/conf.c
+++ b/src/crypto/conf/conf.c
@@ -65,6 +65,7 @@
 #include <openssl/mem.h>
 
 #include "conf_def.h"
+#include "internal.h"
 
 
 static uint32_t conf_value_hash(const CONF_VALUE *v) {
@@ -152,7 +153,7 @@
   OPENSSL_free(conf);
 }
 
-CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
+static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
   STACK_OF(CONF_VALUE) *sk = NULL;
   int ok = 0;
   CONF_VALUE *v = NULL, *old_value;
@@ -776,3 +777,12 @@
     lstart = p + 1;
   }
 }
+
+int CONF_modules_load_file(CONF_MUST_BE_NULL *filename, const char *appname,
+                           unsigned long flags) {
+  return 1;
+}
+
+void CONF_modules_free(void) {}
+
+void OPENSSL_config(CONF_MUST_BE_NULL *config_name) {}
diff --git a/src/crypto/cpu-aarch64-linux.c b/src/crypto/cpu-aarch64-linux.c
new file mode 100644
index 0000000..1b0f395
--- /dev/null
+++ b/src/crypto/cpu-aarch64-linux.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/cpu.h>
+
+#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_STATIC_ARMCAP)
+
+#include <sys/auxv.h>
+
+#include <openssl/arm_arch.h>
+
+#include "internal.h"
+
+
+extern uint32_t OPENSSL_armcap_P;
+
+void OPENSSL_cpuid_setup(void) {
+  unsigned long hwcap = getauxval(AT_HWCAP);
+
+  /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of
+   * these values. */
+  static const unsigned long kNEON = 1 << 1;
+  static const unsigned long kAES = 1 << 3;
+  static const unsigned long kPMULL = 1 << 4;
+  static const unsigned long kSHA1 = 1 << 5;
+  static const unsigned long kSHA256 = 1 << 6;
+
+  if ((hwcap & kNEON) == 0) {
+    /* Matching OpenSSL, if NEON is missing, don't report other features
+     * either. */
+    return;
+  }
+
+  OPENSSL_armcap_P |= ARMV7_NEON;
+
+  if (hwcap & kAES) {
+    OPENSSL_armcap_P |= ARMV8_AES;
+  }
+  if (hwcap & kPMULL) {
+    OPENSSL_armcap_P |= ARMV8_PMULL;
+  }
+  if (hwcap & kSHA1) {
+    OPENSSL_armcap_P |= ARMV8_SHA1;
+  }
+  if (hwcap & kSHA256) {
+    OPENSSL_armcap_P |= ARMV8_SHA256;
+  }
+}
+
+#endif /* OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP */
diff --git a/src/crypto/cpu-arm-asm.S b/src/crypto/cpu-arm-asm.S
deleted file mode 100644
index faf3ad8..0000000
--- a/src/crypto/cpu-arm-asm.S
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-#if !defined(OPENSSL_NO_ASM) && defined(__arm__)
-
-.syntax unified
-.cpu cortex-a8
-.fpu neon
-.text
-.thumb
-.align 2
-.global CRYPTO_arm_neon_probe
-.hidden CRYPTO_arm_neon_probe
-.type CRYPTO_arm_neon_probe, %function
-.thumb_func
-CRYPTO_arm_neon_probe:
-  vorr q1, q1, q1
-  bx lr
-.section .note.GNU-stack,"",%progbits
-
-#endif  /* !OPENSSL_NO_ASM && __arm__ */
diff --git a/src/crypto/cpu-arm-linux.c b/src/crypto/cpu-arm-linux.c
new file mode 100644
index 0000000..73c38ec
--- /dev/null
+++ b/src/crypto/cpu-arm-linux.c
@@ -0,0 +1,360 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/cpu.h>
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP)
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <openssl/arm_arch.h>
+#include <openssl/buf.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+
+#define HWCAP_NEON (1 << 12)
+
+/* See /usr/include/asm/hwcap.h on an ARM installation for the source of
+ * these values. */
+#define HWCAP2_AES (1 << 0)
+#define HWCAP2_PMULL (1 << 1)
+#define HWCAP2_SHA1 (1 << 2)
+#define HWCAP2_SHA2 (1 << 3)
+
+/* |getauxval| is not available on Android until API level 20. Link it as a weak
+ * symbol and use other methods as fallback. */
+unsigned long getauxval(unsigned long type) __attribute__((weak));
+
+static int open_eintr(const char *path, int flags) {
+  int ret;
+  do {
+    ret = open(path, flags);
+  } while (ret < 0 && errno == EINTR);
+  return ret;
+}
+
+static ssize_t read_eintr(int fd, void *out, size_t len) {
+  ssize_t ret;
+  do {
+    ret = read(fd, out, len);
+  } while (ret < 0 && errno == EINTR);
+  return ret;
+}
+
+/* read_full reads exactly |len| bytes from |fd| to |out|. On error or end of
+ * file, it returns zero. */
+static int read_full(int fd, void *out, size_t len) {
+  char *outp = out;
+  while (len > 0) {
+    ssize_t ret = read_eintr(fd, outp, len);
+    if (ret <= 0) {
+      return 0;
+    }
+    outp += ret;
+    len -= ret;
+  }
+  return 1;
+}
+
+/* read_file opens |path| and reads until end-of-file. On success, it returns
+ * one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the
+ * contents. Otherwise, it returns zero. */
+static int read_file(char **out_ptr, size_t *out_len, const char *path) {
+  int fd = open_eintr(path, O_RDONLY);
+  if (fd < 0) {
+    return 0;
+  }
+
+  static const size_t kReadSize = 1024;
+  int ret = 0;
+  size_t cap = kReadSize, len = 0;
+  char *buf = OPENSSL_malloc(cap);
+  if (buf == NULL) {
+    goto err;
+  }
+
+  for (;;) {
+    if (cap - len < kReadSize) {
+      size_t new_cap = cap * 2;
+      if (new_cap < cap) {
+        goto err;
+      }
+      char *new_buf = OPENSSL_realloc(buf, new_cap);
+      if (new_buf == NULL) {
+        goto err;
+      }
+      buf = new_buf;
+      cap = new_cap;
+    }
+
+    ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize);
+    if (bytes_read < 0) {
+      goto err;
+    }
+    if (bytes_read == 0) {
+      break;
+    }
+    len += bytes_read;
+  }
+
+  *out_ptr = buf;
+  *out_len = len;
+  ret = 1;
+  buf = NULL;
+
+err:
+  OPENSSL_free(buf);
+  close(fd);
+  return ret;
+}
+
+/* getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. */
+static unsigned long getauxval_proc(unsigned long type) {
+  int fd = open_eintr("/proc/self/auxv", O_RDONLY);
+  if (fd < 0) {
+    return 0;
+  }
+
+  struct {
+    unsigned long tag;
+    unsigned long value;
+  } entry;
+
+  for (;;) {
+    if (!read_full(fd, &entry, sizeof(entry)) ||
+        (entry.tag == 0 && entry.value == 0)) {
+      break;
+    }
+    if (entry.tag == type) {
+      close(fd);
+      return entry.value;
+    }
+  }
+  close(fd);
+  return 0;
+}
+
+typedef struct {
+  const char *data;
+  size_t len;
+} STRING_PIECE;
+
+static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) {
+  size_t b_len = strlen(b);
+  return a->len == b_len && memcmp(a->data, b, b_len) == 0;
+}
+
+/* STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found,
+ * sets |*out_left| and |*out_right| to |in| split before and after it. It
+ * returns one if |sep| was found and zero otherwise. */
+static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right,
+                              const STRING_PIECE *in, char sep) {
+  const char *p = memchr(in->data, sep, in->len);
+  if (p == NULL) {
+    return 0;
+  }
+  /* |out_left| or |out_right| may alias |in|, so make a copy. */
+  STRING_PIECE in_copy = *in;
+  out_left->data = in_copy.data;
+  out_left->len = p - in_copy.data;
+  out_right->data = in_copy.data + out_left->len + 1;
+  out_right->len = in_copy.len - out_left->len - 1;
+  return 1;
+}
+
+/* STRING_PIECE_trim removes leading and trailing whitespace from |s|. */
+static void STRING_PIECE_trim(STRING_PIECE *s) {
+  while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) {
+    s->data++;
+    s->len--;
+  }
+  while (s->len != 0 &&
+         (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) {
+    s->len--;
+  }
+}
+
+/* extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from
+ * |in|.  If found, it sets |*out| to the value and returns one. Otherwise, it
+ * returns zero. */
+static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in,
+                                 const char *field) {
+  /* Process |in| one line at a time. */
+  STRING_PIECE remaining = *in, line;
+  while (STRING_PIECE_split(&line, &remaining, &remaining, '\n')) {
+    STRING_PIECE key, value;
+    if (!STRING_PIECE_split(&key, &value, &line, ':')) {
+      continue;
+    }
+    STRING_PIECE_trim(&key);
+    if (STRING_PIECE_equals(&key, field)) {
+      STRING_PIECE_trim(&value);
+      *out = value;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field,
+                                const char *value) {
+  STRING_PIECE extracted;
+  return extract_cpuinfo_field(&extracted, cpuinfo, field) &&
+         STRING_PIECE_equals(&extracted, value);
+}
+
+/* has_list_item treats |list| as a space-separated list of items and returns
+ * one if |item| is contained in |list| and zero otherwise. */
+static int has_list_item(const STRING_PIECE *list, const char *item) {
+  STRING_PIECE remaining = *list, feature;
+  while (STRING_PIECE_split(&feature, &remaining, &remaining, ' ')) {
+    if (STRING_PIECE_equals(&feature, item)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) {
+  if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) {
+    /* This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always
+     * available on ARMv8. Linux omits required features, so reading the
+     * "Features" line does not work. (For simplicity, use strict equality. We
+     * assume everything running on future ARM architectures will have a
+     * working |getauxval|.) */
+    return HWCAP_NEON;
+  }
+
+  STRING_PIECE features;
+  if (extract_cpuinfo_field(&features, cpuinfo, "Features") &&
+      has_list_item(&features, "neon")) {
+    return HWCAP_NEON;
+  }
+  return 0;
+}
+
+static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) {
+  STRING_PIECE features;
+  if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) {
+    return 0;
+  }
+
+  unsigned long ret = 0;
+  if (has_list_item(&features, "aes")) {
+    ret |= HWCAP2_AES;
+  }
+  if (has_list_item(&features, "pmull")) {
+    ret |= HWCAP2_PMULL;
+  }
+  if (has_list_item(&features, "sha1")) {
+    ret |= HWCAP2_SHA1;
+  }
+  if (has_list_item(&features, "sha2")) {
+    ret |= HWCAP2_SHA2;
+  }
+  return ret;
+}
+
+/* has_broken_neon returns one if |in| matches a CPU known to have a broken
+ * NEON unit. See https://crbug.com/341598. */
+static int has_broken_neon(const STRING_PIECE *cpuinfo) {
+  return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") &&
+         cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") &&
+         cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") &&
+         cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") &&
+         cpuinfo_field_equals(cpuinfo, "CPU revision", "0");
+}
+
+extern uint32_t OPENSSL_armcap_P;
+
+static int g_has_broken_neon;
+
+void OPENSSL_cpuid_setup(void) {
+  char *cpuinfo_data;
+  size_t cpuinfo_len;
+  if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) {
+    return;
+  }
+  STRING_PIECE cpuinfo;
+  cpuinfo.data = cpuinfo_data;
+  cpuinfo.len = cpuinfo_len;
+
+  /* |getauxval| is not available on Android until API level 20. If it is
+   * unavailable, read from /proc/self/auxv as a fallback. This is unreadable
+   * on some versions of Android, so further fall back to /proc/cpuinfo.
+   *
+   * See
+   * https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2
+   * and b/13679666 (Google-internal) for details. */
+  unsigned long hwcap = 0;
+  if (getauxval != NULL) {
+    hwcap = getauxval(AT_HWCAP);
+  }
+  if (hwcap == 0) {
+    hwcap = getauxval_proc(AT_HWCAP);
+  }
+  if (hwcap == 0) {
+    hwcap = get_hwcap_cpuinfo(&cpuinfo);
+  }
+
+  /* Clear NEON support if known broken. */
+  g_has_broken_neon = has_broken_neon(&cpuinfo);
+  if (g_has_broken_neon) {
+    hwcap &= ~HWCAP_NEON;
+  }
+
+  /* Matching OpenSSL, only report other features if NEON is present. */
+  if (hwcap & HWCAP_NEON) {
+    OPENSSL_armcap_P |= ARMV7_NEON;
+
+    /* Some ARMv8 Android devices don't expose AT_HWCAP2. Fall back to
+     * /proc/cpuinfo. See https://crbug.com/596156. */
+    unsigned long hwcap2 = 0;
+    if (getauxval != NULL) {
+      hwcap2 = getauxval(AT_HWCAP2);
+    }
+    if (hwcap2 == 0) {
+      hwcap2 = get_hwcap2_cpuinfo(&cpuinfo);
+    }
+
+    if (hwcap2 & HWCAP2_AES) {
+      OPENSSL_armcap_P |= ARMV8_AES;
+    }
+    if (hwcap2 & HWCAP2_PMULL) {
+      OPENSSL_armcap_P |= ARMV8_PMULL;
+    }
+    if (hwcap2 & HWCAP2_SHA1) {
+      OPENSSL_armcap_P |= ARMV8_SHA1;
+    }
+    if (hwcap2 & HWCAP2_SHA2) {
+      OPENSSL_armcap_P |= ARMV8_SHA256;
+    }
+  }
+
+  OPENSSL_free(cpuinfo_data);
+}
+
+int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; }
+
+#endif /* OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP */
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 675d174..ef395ea 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -17,52 +17,15 @@
 #if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
     !defined(OPENSSL_STATIC_ARMCAP)
 
-#include <inttypes.h>
-#include <string.h>
-
-#include <setjmp.h>
-#include <signal.h>
-
 #include <openssl/arm_arch.h>
 
 
-/* We can't include <sys/auxv.h> because the Android SDK version against which
- * Chromium builds is too old to have it. Instead we define all the constants
- * that we need and have a weak pointer to getauxval. */
-
-unsigned long getauxval(unsigned long type) __attribute__((weak));
-
 extern uint32_t OPENSSL_armcap_P;
 
 char CRYPTO_is_NEON_capable_at_runtime(void) {
   return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
 }
 
-static char g_set_neon_called = 0;
-
-void CRYPTO_set_NEON_capable(char neon_capable) {
-  g_set_neon_called = 1;
-
-  if (neon_capable) {
-    OPENSSL_armcap_P |= ARMV7_NEON;
-  } else {
-    OPENSSL_armcap_P &= ~ARMV7_NEON;
-  }
-}
-
-char CRYPTO_is_NEON_functional(void) {
-  static const uint32_t kWantFlags = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
-  return (OPENSSL_armcap_P & kWantFlags) == kWantFlags;
-}
-
-void CRYPTO_set_NEON_functional(char neon_functional) {
-  if (neon_functional) {
-    OPENSSL_armcap_P |= ARMV7_NEON_FUNCTIONAL;
-  } else {
-    OPENSSL_armcap_P &= ~ARMV7_NEON_FUNCTIONAL;
-  }
-}
-
 int CRYPTO_is_ARMv8_AES_capable(void) {
   return (OPENSSL_armcap_P & ARMV8_AES) != 0;
 }
@@ -71,129 +34,5 @@
   return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
 }
 
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
-
-static sigjmp_buf sigill_jmp;
-
-static void sigill_handler(int signal) {
-  siglongjmp(sigill_jmp, signal);
-}
-
-void CRYPTO_arm_neon_probe(void);
-
-// probe_for_NEON returns 1 if a NEON instruction runs successfully. Because
-// getauxval doesn't exist on Android until Jelly Bean, supporting NEON on
-// older devices requires this.
-static int probe_for_NEON(void) {
-  int supported = 0;
-
-  sigset_t sigmask;
-  sigfillset(&sigmask);
-  sigdelset(&sigmask, SIGILL);
-  sigdelset(&sigmask, SIGTRAP);
-  sigdelset(&sigmask, SIGFPE);
-  sigdelset(&sigmask, SIGBUS);
-  sigdelset(&sigmask, SIGSEGV);
-
-  struct sigaction sigill_original_action, sigill_action;
-  memset(&sigill_action, 0, sizeof(sigill_action));
-  sigill_action.sa_handler = sigill_handler;
-  sigill_action.sa_mask = sigmask;
-
-  sigset_t original_sigmask;
-  sigprocmask(SIG_SETMASK, &sigmask, &original_sigmask);
-
-  if (sigsetjmp(sigill_jmp, 1 /* save signals */) == 0) {
-    sigaction(SIGILL, &sigill_action, &sigill_original_action);
-
-    // This function cannot be inline asm because GCC will refuse to compile
-    // inline NEON instructions unless building with -mfpu=neon, which would
-    // defeat the point of probing for support at runtime.
-    CRYPTO_arm_neon_probe();
-    supported = 1;
-  }
-  // Note that Android up to and including Lollipop doesn't restore the signal
-  // mask correctly after returning from a sigsetjmp. So that would need to be
-  // set again here if more probes were added.
-  // See https://android-review.googlesource.com/#/c/127624/
-
-  sigaction(SIGILL, &sigill_original_action, NULL);
-  sigprocmask(SIG_SETMASK, &original_sigmask, NULL);
-
-  return supported;
-}
-
-#else
-
-static int probe_for_NEON(void) {
-  return 0;
-}
-
-#endif  /* !OPENSSL_NO_ASM && OPENSSL_ARM */
-
-void OPENSSL_cpuid_setup(void) {
-  if (getauxval == NULL) {
-    // On ARM, but not AArch64, try a NEON instruction and see whether it works
-    // in order to probe for NEON support.
-    //
-    // Note that |CRYPTO_is_NEON_capable| can be true even if
-    // |CRYPTO_set_NEON_capable| has never been called if the code was compiled
-    // with NEON support enabled (e.g. -mfpu=neon).
-    if (!g_set_neon_called && !CRYPTO_is_NEON_capable() && probe_for_NEON()) {
-      OPENSSL_armcap_P |= ARMV7_NEON;
-    }
-    return;
-  }
-
-  static const unsigned long AT_HWCAP = 16;
-  unsigned long hwcap = getauxval(AT_HWCAP);
-
-#if defined(OPENSSL_ARM)
-  static const unsigned long kNEON = 1 << 12;
-  if ((hwcap & kNEON) == 0) {
-    return;
-  }
-
-  /* In 32-bit mode, the ARMv8 feature bits are in a different aux vector
-   * value. */
-  static const unsigned long AT_HWCAP2 = 26;
-  hwcap = getauxval(AT_HWCAP2);
-
-  /* See /usr/include/asm/hwcap.h on an ARM installation for the source of
-   * these values. */
-  static const unsigned long kAES = 1 << 0;
-  static const unsigned long kPMULL = 1 << 1;
-  static const unsigned long kSHA1 = 1 << 2;
-  static const unsigned long kSHA256 = 1 << 3;
-#elif defined(OPENSSL_AARCH64)
-  /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of
-   * these values. */
-  static const unsigned long kNEON = 1 << 1;
-  static const unsigned long kAES = 1 << 3;
-  static const unsigned long kPMULL = 1 << 4;
-  static const unsigned long kSHA1 = 1 << 5;
-  static const unsigned long kSHA256 = 1 << 6;
-
-  if ((hwcap & kNEON) == 0) {
-    return;
-  }
-#endif
-
-  OPENSSL_armcap_P |= ARMV7_NEON;
-
-  if (hwcap & kAES) {
-    OPENSSL_armcap_P |= ARMV8_AES;
-  }
-  if (hwcap & kPMULL) {
-    OPENSSL_armcap_P |= ARMV8_PMULL;
-  }
-  if (hwcap & kSHA1) {
-    OPENSSL_armcap_P |= ARMV8_SHA1;
-  }
-  if (hwcap & kSHA256) {
-    OPENSSL_armcap_P |= ARMV8_SHA256;
-  }
-}
-
 #endif  /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) &&
            !defined(OPENSSL_STATIC_ARMCAP) */
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index 924bab0..431e1e1 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -64,8 +64,8 @@
 #if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
 
 #include <inttypes.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #if defined(OPENSSL_WINDOWS)
@@ -75,6 +75,8 @@
 #pragma warning(pop)
 #endif
 
+#include "internal.h"
+
 
 /* OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX
  * is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through
@@ -127,7 +129,7 @@
   const int invert = in[0] == '~';
   uint64_t v;
 
-  if (!sscanf(in + invert, "%" PRIi64, &v)) {
+  if (!sscanf(in + invert, "%" PRIu64, &v)) {
     return;
   }
 
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index ace1c82..89b0bd1 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -63,7 +63,7 @@
 
 uint32_t OPENSSL_armcap_P =
 #if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
-    ARMV7_NEON | ARMV7_NEON_FUNCTIONAL |
+    ARMV7_NEON |
 #endif
 #if defined(OPENSSL_STATIC_ARMCAP_AES)
     ARMV8_AES |
@@ -79,10 +79,8 @@
 #endif
     0;
 
-#elif defined(__ARM_NEON__)
-uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
 #else
-uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
+uint32_t OPENSSL_armcap_P = 0;
 #endif
 
 #endif
@@ -138,3 +136,7 @@
 }
 
 void ENGINE_load_builtin_engines(void) {}
+
+void OPENSSL_load_builtin_modules(void) {}
+
+int FIPS_mode(void) { return 0; }
diff --git a/src/crypto/curve25519/CMakeLists.txt b/src/crypto/curve25519/CMakeLists.txt
index a2ef3bb..195b1e6 100644
--- a/src/crypto/curve25519/CMakeLists.txt
+++ b/src/crypto/curve25519/CMakeLists.txt
@@ -22,6 +22,7 @@
   OBJECT
 
   curve25519.c
+  spake25519.c
   x25519-x86_64.c
 
   ${CURVE25519_ARCH_SOURCES}
@@ -45,3 +46,12 @@
 
 target_link_libraries(x25519_test crypto)
 add_dependencies(all_tests x25519_test)
+
+add_executable(
+  spake25519_test
+
+  spake25519_test.cc
+)
+
+target_link_libraries(spake25519_test crypto)
+add_dependencies(all_tests spake25519_test)
diff --git a/src/crypto/curve25519/asm/x25519-asm-arm.S b/src/crypto/curve25519/asm/x25519-asm-arm.S
index 60d08dd..3af1dba 100644
--- a/src/crypto/curve25519/asm/x25519-asm-arm.S
+++ b/src/crypto/curve25519/asm/x25519-asm-arm.S
@@ -17,6 +17,9 @@
  * domain licensed but the standard ISC license is included above to keep
  * licensing simple. */
 
+#if !defined(OPENSSL_NO_ASM)
+#if defined(__arm__)
+
 .fpu neon
 .text
 .align 4
@@ -2116,3 +2119,6 @@
 mov sp,r12
 vpop {q4,q5,q6,q7}
 bx lr
+
+#endif  /* __arm__ */
+#endif  /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/curve25519/asm/x25519-asm-x86_64.S b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
index 7e86a23..531ac16 100644
--- a/src/crypto/curve25519/asm/x25519-asm-x86_64.S
+++ b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
@@ -17,6 +17,9 @@
  * domain licensed but the standard ISC license is included above to keep
  * licensing simple. */
 
+#if !defined(OPENSSL_NO_ASM)
+#if defined(__x86_64__)
+
 .data
 .p2align 4
 
@@ -1929,3 +1932,6 @@
 mov %rdi,%rax
 mov %rsi,%rdx
 ret
+
+#endif  /* __x86_64__ */
+#endif  /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/curve25519/curve25519.c b/src/crypto/curve25519/curve25519.c
index 272db6c..1dd1b3e 100644
--- a/src/crypto/curve25519/curve25519.c
+++ b/src/crypto/curve25519/curve25519.c
@@ -31,11 +31,10 @@
 #include "internal.h"
 
 
-/* fe means field element. Here the field is \Z/(2^255-19). An element t,
- * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
- * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
- * context.  */
-typedef int32_t fe[10];
+static const int64_t kBottom25Bits = INT64_C(0x1ffffff);
+static const int64_t kBottom26Bits = INT64_C(0x3ffffff);
+static const int64_t kTop39Bits = INT64_C(0xfffffffffe000000);
+static const int64_t kTop38Bits = INT64_C(0xfffffffffc000000);
 
 static uint64_t load_3(const uint8_t *in) {
   uint64_t result;
@@ -77,17 +76,17 @@
   int64_t carry8;
   int64_t carry9;
 
-  carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
-  carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
-  carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
-  carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
 
   h[0] = h0;
   h[1] = h1;
@@ -135,16 +134,6 @@
   int32_t h8 = h[8];
   int32_t h9 = h[9];
   int32_t q;
-  int32_t carry0;
-  int32_t carry1;
-  int32_t carry2;
-  int32_t carry3;
-  int32_t carry4;
-  int32_t carry5;
-  int32_t carry6;
-  int32_t carry7;
-  int32_t carry8;
-  int32_t carry9;
 
   q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
   q = (h0 + q) >> 26;
@@ -162,16 +151,16 @@
   h0 += 19 * q;
   /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
 
-  carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
-  carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
-  carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
-  carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
-  carry9 = h9 >> 25;               h9 -= carry9 << 25;
+  h1 += h0 >> 26; h0 &= kBottom26Bits;
+  h2 += h1 >> 25; h1 &= kBottom25Bits;
+  h3 += h2 >> 26; h2 &= kBottom26Bits;
+  h4 += h3 >> 25; h3 &= kBottom25Bits;
+  h5 += h4 >> 26; h4 &= kBottom26Bits;
+  h6 += h5 >> 25; h5 &= kBottom25Bits;
+  h7 += h6 >> 26; h6 &= kBottom26Bits;
+  h8 += h7 >> 25; h7 &= kBottom25Bits;
+  h9 += h8 >> 26; h8 &= kBottom26Bits;
+                  h9 &= kBottom25Bits;
                   /* h10 = carry9 */
 
   /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
@@ -182,32 +171,32 @@
   s[0] = h0 >> 0;
   s[1] = h0 >> 8;
   s[2] = h0 >> 16;
-  s[3] = (h0 >> 24) | (h1 << 2);
+  s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
   s[4] = h1 >> 6;
   s[5] = h1 >> 14;
-  s[6] = (h1 >> 22) | (h2 << 3);
+  s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
   s[7] = h2 >> 5;
   s[8] = h2 >> 13;
-  s[9] = (h2 >> 21) | (h3 << 5);
+  s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
   s[10] = h3 >> 3;
   s[11] = h3 >> 11;
-  s[12] = (h3 >> 19) | (h4 << 6);
+  s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6);
   s[13] = h4 >> 2;
   s[14] = h4 >> 10;
   s[15] = h4 >> 18;
   s[16] = h5 >> 0;
   s[17] = h5 >> 8;
   s[18] = h5 >> 16;
-  s[19] = (h5 >> 24) | (h6 << 1);
+  s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
   s[20] = h6 >> 7;
   s[21] = h6 >> 15;
-  s[22] = (h6 >> 23) | (h7 << 3);
+  s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
   s[23] = h7 >> 5;
   s[24] = h7 >> 13;
-  s[25] = (h7 >> 21) | (h8 << 4);
+  s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
   s[26] = h8 >> 4;
   s[27] = h8 >> 12;
-  s[28] = (h8 >> 20) | (h9 << 6);
+  s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
   s[29] = h9 >> 2;
   s[30] = h9 >> 10;
   s[31] = h9 >> 18;
@@ -447,46 +436,46 @@
    * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
    *   i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
   /* |h0| <= 2^25 */
   /* |h4| <= 2^25 */
   /* |h1| <= 1.71*2^59 */
   /* |h5| <= 1.71*2^59 */
 
-  carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
   /* |h1| <= 2^24; from now on fits into int32 */
   /* |h5| <= 2^24; from now on fits into int32 */
   /* |h2| <= 1.41*2^60 */
   /* |h6| <= 1.41*2^60 */
 
-  carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
   /* |h2| <= 2^25; from now on fits into int32 unchanged */
   /* |h6| <= 2^25; from now on fits into int32 unchanged */
   /* |h3| <= 1.71*2^59 */
   /* |h7| <= 1.71*2^59 */
 
-  carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
   /* |h3| <= 2^24; from now on fits into int32 unchanged */
   /* |h7| <= 2^24; from now on fits into int32 unchanged */
   /* |h4| <= 1.72*2^34 */
   /* |h8| <= 1.41*2^60 */
 
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
   /* |h4| <= 2^25; from now on fits into int32 unchanged */
   /* |h8| <= 2^25; from now on fits into int32 unchanged */
   /* |h5| <= 1.01*2^24 */
   /* |h9| <= 1.71*2^59 */
 
-  carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
   /* |h9| <= 2^24; from now on fits into int32 unchanged */
   /* |h0| <= 1.1*2^39 */
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
   /* |h0| <= 2^25; from now on fits into int32 unchanged */
   /* |h1| <= 1.01*2^24 */
 
@@ -612,24 +601,24 @@
   int64_t carry8;
   int64_t carry9;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
 
-  carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
 
-  carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
 
-  carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
 
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
 
-  carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
 
   h[0] = h0;
   h[1] = h1;
@@ -880,24 +869,24 @@
   h8 += h8;
   h9 += h9;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
 
-  carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
 
-  carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
 
-  carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
 
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
 
-  carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
 
   h[0] = h0;
   h[1] = h1;
@@ -974,52 +963,7 @@
   fe_mul(out, t0, z);
 }
 
-/* ge means group element.
-
- * Here the group is the set of pairs (x,y) of field elements (see fe.h)
- * satisfying -x^2 + y^2 = 1 + d x^2y^2
- * where d = -121665/121666.
- *
- * Representations:
- *   ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
- *   ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
- *   ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
- *   ge_precomp (Duif): (y+x,y-x,2dxy) */
-
-typedef struct {
-  fe X;
-  fe Y;
-  fe Z;
-} ge_p2;
-
-typedef struct {
-  fe X;
-  fe Y;
-  fe Z;
-  fe T;
-} ge_p3;
-
-typedef struct {
-  fe X;
-  fe Y;
-  fe Z;
-  fe T;
-} ge_p1p1;
-
-typedef struct {
-  fe yplusx;
-  fe yminusx;
-  fe xy2d;
-} ge_precomp;
-
-typedef struct {
-  fe YplusX;
-  fe YminusX;
-  fe Z;
-  fe T2d;
-} ge_cached;
-
-static void ge_tobytes(uint8_t *s, const ge_p2 *h) {
+void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h) {
   fe recip;
   fe x;
   fe y;
@@ -1049,7 +993,7 @@
 static const fe sqrtm1 = {-32595792, -7943725,  9377950,  3500415, 12389472,
                           -272473,   -25146209, -2005654, 326686,  11406482};
 
-static int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s) {
+int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
   fe u;
   fe v;
   fe v3;
@@ -1084,7 +1028,7 @@
     fe_mul(h->X, h->X, sqrtm1);
   }
 
-  if (fe_isnegative(h->X) == (s[31] >> 7)) {
+  if (fe_isnegative(h->X) != (s[31] >> 7)) {
     fe_neg(h->X, h->X);
   }
 
@@ -1105,6 +1049,13 @@
   fe_0(h->T);
 }
 
+static void ge_cached_0(ge_cached *h) {
+  fe_1(h->YplusX);
+  fe_1(h->YminusX);
+  fe_1(h->Z);
+  fe_0(h->T2d);
+}
+
 static void ge_precomp_0(ge_precomp *h) {
   fe_1(h->yplusx);
   fe_1(h->yminusx);
@@ -1122,7 +1073,7 @@
                       15978800,  -12551817, -6495438,  29715968, 9444199};
 
 /* r = p */
-static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
+void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
   fe_add(r->YplusX, p->Y, p->X);
   fe_sub(r->YminusX, p->Y, p->X);
   fe_copy(r->Z, p->Z);
@@ -1130,20 +1081,27 @@
 }
 
 /* r = p */
-static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
+void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
   fe_mul(r->X, p->X, p->T);
   fe_mul(r->Y, p->Y, p->Z);
   fe_mul(r->Z, p->Z, p->T);
 }
 
 /* r = p */
-static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
+void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
   fe_mul(r->X, p->X, p->T);
   fe_mul(r->Y, p->Y, p->Z);
   fe_mul(r->Z, p->Z, p->T);
   fe_mul(r->T, p->X, p->Y);
 }
 
+/* r = p */
+static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) {
+  ge_p3 t;
+  x25519_ge_p1p1_to_p3(&t, p);
+  x25519_ge_p3_to_cached(r, &t);
+}
+
 /* r = 2 * p */
 static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
   fe t0;
@@ -1199,7 +1157,7 @@
 }
 
 /* r = p + q */
-static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
   fe t0;
 
   fe_add(r->X, p->Y, p->X);
@@ -1216,7 +1174,7 @@
 }
 
 /* r = p - q */
-static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
   fe t0;
 
   fe_add(r->X, p->Y, p->X);
@@ -1242,12 +1200,64 @@
   return y;
 }
 
-static void cmov(ge_precomp *t, ge_precomp *u, uint8_t b) {
+static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
   fe_cmov(t->yplusx, u->yplusx, b);
   fe_cmov(t->yminusx, u->yminusx, b);
   fe_cmov(t->xy2d, u->xy2d, b);
 }
 
+void x25519_ge_scalarmult_small_precomp(
+    ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) {
+  /* precomp_table is first expanded into matching |ge_precomp|
+   * elements. */
+  ge_precomp multiples[15];
+
+  unsigned i;
+  for (i = 0; i < 15; i++) {
+    const uint8_t *bytes = &precomp_table[i*(2 * 32)];
+    fe x, y;
+    fe_frombytes(x, bytes);
+    fe_frombytes(y, bytes + 32);
+
+    ge_precomp *out = &multiples[i];
+    fe_add(out->yplusx, y, x);
+    fe_sub(out->yminusx, y, x);
+    fe_mul(out->xy2d, x, y);
+    fe_mul(out->xy2d, out->xy2d, d2);
+  }
+
+  /* See the comment above |k25519SmallPrecomp| about the structure of the
+   * precomputed elements. This loop does 64 additions and 64 doublings to
+   * calculate the result. */
+  ge_p3_0(h);
+
+  for (i = 63; i < 64; i--) {
+    unsigned j;
+    signed char index = 0;
+
+    for (j = 0; j < 4; j++) {
+      const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7));
+      index |= (bit << j);
+    }
+
+    ge_precomp e;
+    ge_precomp_0(&e);
+
+    for (j = 1; j < 16; j++) {
+      cmov(&e, &multiples[j-1], equal(index, j));
+    }
+
+    ge_cached cached;
+    ge_p1p1 r;
+    x25519_ge_p3_to_cached(&cached, h);
+    x25519_ge_add(&r, h, &cached);
+    x25519_ge_p1p1_to_p3(h, &r);
+
+    ge_madd(&r, h, &e);
+    x25519_ge_p1p1_to_p3(h, &r);
+  }
+}
+
 #if defined(OPENSSL_SMALL)
 
 /* This block of code replaces the standard base-point table with a much smaller
@@ -1258,7 +1268,7 @@
  * element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀
  * is the most significant bit). The value of the group element is then:
  * (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. */
-static const uint8_t kSmallPrecomp[15 * 2 * 32] = {
+static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = {
     0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
     0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
     0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66,
@@ -1341,60 +1351,14 @@
     0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25,
 };
 
-static void ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
-  /* kSmallPrecomp is first expanded into matching |ge_precomp| elements. */
-  ge_precomp multiples[15];
-
-  unsigned i;
-  for (i = 0; i < 15; i++) {
-    const uint8_t *bytes = &kSmallPrecomp[i*(2 * 32)];
-    fe x, y;
-    fe_frombytes(x, bytes);
-    fe_frombytes(y, bytes + 32);
-
-    ge_precomp *out = &multiples[i];
-    fe_add(out->yplusx, y, x);
-    fe_sub(out->yminusx, y, x);
-    fe_mul(out->xy2d, x, y);
-    fe_mul(out->xy2d, out->xy2d, d2);
-  }
-
-  /* See the comment above |kSmallPrecomp| about the structure of the
-   * precomputed elements. This loop does 64 additions and 64 doublings to
-   * calculate the result. */
-  ge_p3_0(h);
-
-  for (i = 63; i < 64; i--) {
-    unsigned j;
-    signed char index = 0;
-
-    for (j = 0; j < 4; j++) {
-      const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7));
-      index |= (bit << j);
-    }
-
-    ge_precomp e;
-    ge_precomp_0(&e);
-
-    for (j = 1; j < 16; j++) {
-      cmov(&e, &multiples[j-1], equal(index, j));
-    }
-
-    ge_cached cached;
-    ge_p1p1 r;
-    ge_p3_to_cached(&cached, h);
-    ge_add(&r, h, &cached);
-    ge_p1p1_to_p3(h, &r);
-
-    ge_madd(&r, h, &e);
-    ge_p1p1_to_p3(h, &r);
-  }
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
+  x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp);
 }
 
 #else
 
-/* base[i][j] = (j+1)*256^i*B */
-static ge_precomp base[32][8] = {
+/* k25519Precomp[i][j] = (j+1)*256^i*B */
+static const ge_precomp k25519Precomp[32][8] = {
     {
         {
             {25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
@@ -3518,17 +3482,17 @@
 static void table_select(ge_precomp *t, int pos, signed char b) {
   ge_precomp minust;
   uint8_t bnegative = negative(b);
-  uint8_t babs = b - (((-bnegative) & b) << 1);
+  uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
 
   ge_precomp_0(t);
-  cmov(t, &base[pos][0], equal(babs, 1));
-  cmov(t, &base[pos][1], equal(babs, 2));
-  cmov(t, &base[pos][2], equal(babs, 3));
-  cmov(t, &base[pos][3], equal(babs, 4));
-  cmov(t, &base[pos][4], equal(babs, 5));
-  cmov(t, &base[pos][5], equal(babs, 6));
-  cmov(t, &base[pos][6], equal(babs, 7));
-  cmov(t, &base[pos][7], equal(babs, 8));
+  cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
+  cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
+  cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
+  cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
+  cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
+  cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
+  cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
+  cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
   fe_copy(minust.yplusx, t->yminusx);
   fe_copy(minust.yminusx, t->yplusx);
   fe_neg(minust.xy2d, t->xy2d);
@@ -3541,7 +3505,7 @@
  *
  * Preconditions:
  *   a[31] <= 127 */
-static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
   signed char e[64];
   signed char carry;
   ge_p1p1 r;
@@ -3570,27 +3534,88 @@
   for (i = 1; i < 64; i += 2) {
     table_select(&t, i / 2, e[i]);
     ge_madd(&r, h, &t);
-    ge_p1p1_to_p3(h, &r);
+    x25519_ge_p1p1_to_p3(h, &r);
   }
 
   ge_p3_dbl(&r, h);
-  ge_p1p1_to_p2(&s, &r);
+  x25519_ge_p1p1_to_p2(&s, &r);
   ge_p2_dbl(&r, &s);
-  ge_p1p1_to_p2(&s, &r);
+  x25519_ge_p1p1_to_p2(&s, &r);
   ge_p2_dbl(&r, &s);
-  ge_p1p1_to_p2(&s, &r);
+  x25519_ge_p1p1_to_p2(&s, &r);
   ge_p2_dbl(&r, &s);
-  ge_p1p1_to_p3(h, &r);
+  x25519_ge_p1p1_to_p3(h, &r);
 
   for (i = 0; i < 64; i += 2) {
     table_select(&t, i / 2, e[i]);
     ge_madd(&r, h, &t);
-    ge_p1p1_to_p3(h, &r);
+    x25519_ge_p1p1_to_p3(h, &r);
   }
 }
 
 #endif
 
+static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) {
+  fe_cmov(t->YplusX, u->YplusX, b);
+  fe_cmov(t->YminusX, u->YminusX, b);
+  fe_cmov(t->Z, u->Z, b);
+  fe_cmov(t->T2d, u->T2d, b);
+}
+
+/* r = scalar * A.
+ * where a = a[0]+256*a[1]+...+256^31 a[31]. */
+void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) {
+  ge_p2 Ai_p2[8];
+  ge_cached Ai[16];
+  ge_p1p1 t;
+
+  ge_cached_0(&Ai[0]);
+  x25519_ge_p3_to_cached(&Ai[1], A);
+  ge_p3_to_p2(&Ai_p2[1], A);
+
+  unsigned i;
+  for (i = 2; i < 16; i += 2) {
+    ge_p2_dbl(&t, &Ai_p2[i / 2]);
+    ge_p1p1_to_cached(&Ai[i], &t);
+    if (i < 8) {
+      x25519_ge_p1p1_to_p2(&Ai_p2[i], &t);
+    }
+    x25519_ge_add(&t, A, &Ai[i]);
+    ge_p1p1_to_cached(&Ai[i + 1], &t);
+    if (i < 7) {
+      x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t);
+    }
+  }
+
+  ge_p2_0(r);
+  ge_p3 u;
+
+  for (i = 0; i < 256; i += 4) {
+    ge_p2_dbl(&t, r);
+    x25519_ge_p1p1_to_p2(r, &t);
+    ge_p2_dbl(&t, r);
+    x25519_ge_p1p1_to_p2(r, &t);
+    ge_p2_dbl(&t, r);
+    x25519_ge_p1p1_to_p2(r, &t);
+    ge_p2_dbl(&t, r);
+    x25519_ge_p1p1_to_p3(&u, &t);
+
+    uint8_t index = scalar[31 - i/8];
+    index >>= 4 - (i & 4);
+    index &= 0xf;
+
+    unsigned j;
+    ge_cached selected;
+    ge_cached_0(&selected);
+    for (j = 0; j < 16; j++) {
+      cmov_cached(&selected, &Ai[j], equal(j, index));
+    }
+
+    x25519_ge_add(&t, &u, &selected);
+    x25519_ge_p1p1_to_p2(r, &t);
+  }
+}
+
 static void slide(signed char *r, const uint8_t *a) {
   int i;
   int b;
@@ -3625,7 +3650,7 @@
   }
 }
 
-static ge_precomp Bi[8] = {
+static const ge_precomp Bi[8] = {
     {
         {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626,
          -11754271, -6079156, 2047605},
@@ -3696,8 +3721,8 @@
  * where a = a[0]+256*a[1]+...+256^31 a[31].
  * and b = b[0]+256*b[1]+...+256^31 b[31].
  * B is the Ed25519 base point (x,4/5) with x positive. */
-void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
-                                  const ge_p3 *A, const uint8_t *b) {
+static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
+                                         const ge_p3 *A, const uint8_t *b) {
   signed char aslide[256];
   signed char bslide[256];
   ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
@@ -3709,30 +3734,30 @@
   slide(aslide, a);
   slide(bslide, b);
 
-  ge_p3_to_cached(&Ai[0], A);
+  x25519_ge_p3_to_cached(&Ai[0], A);
   ge_p3_dbl(&t, A);
-  ge_p1p1_to_p3(&A2, &t);
-  ge_add(&t, &A2, &Ai[0]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[1], &u);
-  ge_add(&t, &A2, &Ai[1]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[2], &u);
-  ge_add(&t, &A2, &Ai[2]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[3], &u);
-  ge_add(&t, &A2, &Ai[3]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[4], &u);
-  ge_add(&t, &A2, &Ai[4]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[5], &u);
-  ge_add(&t, &A2, &Ai[5]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[6], &u);
-  ge_add(&t, &A2, &Ai[6]);
-  ge_p1p1_to_p3(&u, &t);
-  ge_p3_to_cached(&Ai[7], &u);
+  x25519_ge_p1p1_to_p3(&A2, &t);
+  x25519_ge_add(&t, &A2, &Ai[0]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[1], &u);
+  x25519_ge_add(&t, &A2, &Ai[1]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[2], &u);
+  x25519_ge_add(&t, &A2, &Ai[2]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[3], &u);
+  x25519_ge_add(&t, &A2, &Ai[3]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[4], &u);
+  x25519_ge_add(&t, &A2, &Ai[4]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[5], &u);
+  x25519_ge_add(&t, &A2, &Ai[5]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[6], &u);
+  x25519_ge_add(&t, &A2, &Ai[6]);
+  x25519_ge_p1p1_to_p3(&u, &t);
+  x25519_ge_p3_to_cached(&Ai[7], &u);
 
   ge_p2_0(r);
 
@@ -3746,22 +3771,22 @@
     ge_p2_dbl(&t, r);
 
     if (aslide[i] > 0) {
-      ge_p1p1_to_p3(&u, &t);
-      ge_add(&t, &u, &Ai[aslide[i] / 2]);
+      x25519_ge_p1p1_to_p3(&u, &t);
+      x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]);
     } else if (aslide[i] < 0) {
-      ge_p1p1_to_p3(&u, &t);
-      ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
+      x25519_ge_p1p1_to_p3(&u, &t);
+      x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
     }
 
     if (bslide[i] > 0) {
-      ge_p1p1_to_p3(&u, &t);
+      x25519_ge_p1p1_to_p3(&u, &t);
       ge_madd(&t, &u, &Bi[bslide[i] / 2]);
     } else if (bslide[i] < 0) {
-      ge_p1p1_to_p3(&u, &t);
+      x25519_ge_p1p1_to_p3(&u, &t);
       ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
     }
 
-    ge_p1p1_to_p2(r, &t);
+    x25519_ge_p1p1_to_p2(r, &t);
   }
 }
 
@@ -3775,7 +3800,7 @@
  *   s[0]+256*s[1]+...+256^31*s[31] = s mod l
  *   where l = 2^252 + 27742317777372353535851937790883648493.
  *   Overwrites s in place. */
-static void sc_reduce(uint8_t *s) {
+void x25519_sc_reduce(uint8_t *s) {
   int64_t s0 = 2097151 & load_3(s);
   int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
   int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
@@ -4609,7 +4634,7 @@
   az[31] |= 64;
 
   ge_p3 A;
-  ge_scalarmult_base(&A, az);
+  x25519_ge_scalarmult_base(&A, az);
   ge_p3_tobytes(out_public_key, &A);
 
   memcpy(out_private_key, seed, 32);
@@ -4632,9 +4657,9 @@
   uint8_t nonce[SHA512_DIGEST_LENGTH];
   SHA512_Final(nonce, &hash_ctx);
 
-  sc_reduce(nonce);
+  x25519_sc_reduce(nonce);
   ge_p3 R;
-  ge_scalarmult_base(&R, nonce);
+  x25519_ge_scalarmult_base(&R, nonce);
   ge_p3_tobytes(out_sig, &R);
 
   SHA512_Init(&hash_ctx);
@@ -4644,7 +4669,7 @@
   uint8_t hram[SHA512_DIGEST_LENGTH];
   SHA512_Final(hram, &hash_ctx);
 
-  sc_reduce(hram);
+  x25519_sc_reduce(hram);
   sc_muladd(out_sig + 32, hram, az, nonce);
 
   return 1;
@@ -4654,10 +4679,13 @@
                    const uint8_t signature[64], const uint8_t public_key[32]) {
   ge_p3 A;
   if ((signature[63] & 224) != 0 ||
-      ge_frombytes_negate_vartime(&A, public_key) != 0) {
+      x25519_ge_frombytes_vartime(&A, public_key) != 0) {
     return 0;
   }
 
+  fe_neg(A.X, A.X);
+  fe_neg(A.T, A.T);
+
   uint8_t pkcopy[32];
   memcpy(pkcopy, public_key, 32);
   uint8_t rcopy[32];
@@ -4673,13 +4701,13 @@
   uint8_t h[SHA512_DIGEST_LENGTH];
   SHA512_Final(h, &hash_ctx);
 
-  sc_reduce(h);
+  x25519_sc_reduce(h);
 
   ge_p2 R;
   ge_double_scalarmult_vartime(&R, h, &A, scopy);
 
   uint8_t rcheck[32];
-  ge_tobytes(rcheck, &R);
+  x25519_ge_tobytes(rcheck, &R);
 
   return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
 }
@@ -4749,17 +4777,17 @@
   int64_t carry8;
   int64_t carry9;
 
-  carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
-  carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
-  carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
-  carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
-  carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
 
-  carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
-  carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
-  carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
-  carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
-  carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
 
   h[0] = h0;
   h[1] = h1;
@@ -4883,7 +4911,7 @@
   e[31] |= 64;
 
   ge_p3 A;
-  ge_scalarmult_base(&A, e);
+  x25519_ge_scalarmult_base(&A, e);
 
   /* We only need the u-coordinate of the curve25519 point. The map is
    * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
diff --git a/src/crypto/curve25519/internal.h b/src/crypto/curve25519/internal.h
index 27994b7..ea206a3 100644
--- a/src/crypto/curve25519/internal.h
+++ b/src/crypto/curve25519/internal.h
@@ -37,6 +37,70 @@
                  const uint8_t point[32]);
 #endif
 
+/* fe means field element. Here the field is \Z/(2^255-19). An element t,
+ * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
+ * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
+ * context.  */
+typedef int32_t fe[10];
+
+/* ge means group element.
+
+ * Here the group is the set of pairs (x,y) of field elements (see fe.h)
+ * satisfying -x^2 + y^2 = 1 + d x^2y^2
+ * where d = -121665/121666.
+ *
+ * Representations:
+ *   ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
+ *   ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
+ *   ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
+ *   ge_precomp (Duif): (y+x,y-x,2dxy) */
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+} ge_p2;
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+  fe T;
+} ge_p3;
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+  fe T;
+} ge_p1p1;
+
+typedef struct {
+  fe yplusx;
+  fe yminusx;
+  fe xy2d;
+} ge_precomp;
+
+typedef struct {
+  fe YplusX;
+  fe YminusX;
+  fe Z;
+  fe T2d;
+} ge_cached;
+
+void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h);
+int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s);
+void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
+void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
+void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
+void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
+void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
+void x25519_ge_scalarmult_small_precomp(
+    ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]);
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]);
+void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A);
+void x25519_sc_reduce(uint8_t *s);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/curve25519/spake25519.c b/src/crypto/curve25519/spake25519.c
new file mode 100644
index 0000000..617418c
--- /dev/null
+++ b/src/crypto/curve25519/spake25519.c
@@ -0,0 +1,464 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/curve25519.h>
+
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include "internal.h"
+
+
+/* The following precomputation tables are for the following
+ * points used in the SPAKE2 protocol.
+ *
+ * N:
+ *   x: 49918732221787544735331783592030787422991506689877079631459872391322455579424
+ *   y: 54629554431565467720832445949441049581317094546788069926228343916274969994000
+ *   encoded: 10e3df0ae37d8e7a99b5fe74b44672103dbddcbd06af680d71329a11693bc778
+ *
+ * M:
+ *   x: 31406539342727633121250288103050113562375374900226415211311216773867585644232
+ *   y: 21177308356423958466833845032658859666296341766942662650232962324899758529114
+ *   encoded: 5ada7e4bf6ddd9adb6626d32131c6b5c51a1e347a3478f53cfcf441b88eed12e
+ *
+ * These points and their precomputation tables are generated with the
+ * following Python code. For a description of the precomputation table,
+ * see curve25519.c in this directory.
+ *
+ * Exact copies of the source code are kept in bug 27296743.
+ *
+ * import hashlib
+ * import ed25519 as E  # http://ed25519.cr.yp.to/python/ed25519.py
+ *
+ * SEED_N = 'edwards25519 point generation seed (N)'
+ * SEED_M = 'edwards25519 point generation seed (M)'
+ *
+ * def genpoint(seed):
+ *     v = hashlib.sha256(seed).digest()
+ *     it = 1
+ *     while True:
+ *         try:
+ *             x,y = E.decodepoint(v)
+ *         except Exception, e:
+ *             print e
+ *             it += 1
+ *             v = hashlib.sha256(v).digest()
+ *             continue
+ *         print "Found in %d iterations:" % it
+ *         print "  x = %d" % x
+ *         print "  y = %d" % y
+ *         print " Encoded (hex)"
+ *         print E.encodepoint((x,y)).encode('hex')
+ *         return (x,y)
+ *
+ * def gentable(P):
+ *     t = []
+ *     for i in range(1,16):
+ *         k = (i >> 3 & 1) * (1 << 192) + \
+ *             (i >> 2 & 1) * (1 << 128) + \
+ *             (i >> 1 & 1) * (1 <<  64) + \
+ *             (i      & 1)
+ *         t.append(E.scalarmult(P, k))
+ *     return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t)
+ *
+ * def printtable(table, name):
+ *     print "static const uint8_t %s[15 * 2 * 32] = {" % name,
+ *     for i in range(15 * 2 * 32):
+ *         if i % 12 == 0:
+ *             print "\n   ",
+ *         print " 0x%02x," % ord(table[i]),
+ *     print "\n};"
+ *
+ * if __name__ == "__main__":
+ *     print "Searching for N"
+ *     N = genpoint(SEED_N)
+ *     print "Generating precomputation table for N"
+ *     Ntable = gentable(N)
+ *     printtable(Ntable, "kSpakeNSmallPrecomp")
+ *
+ *     print "Searching for M"
+ *     M = genpoint(SEED_M)
+ *     print "Generating precomputation table for M"
+ *     Mtable = gentable(M)
+ *     printtable(Mtable, "kSpakeMSmallPrecomp")
+ */
+static const uint8_t kSpakeNSmallPrecomp[15 * 2 * 32] = {
+    0x20, 0x1b, 0xc5, 0xb3, 0x43, 0x17, 0x71, 0x10, 0x44, 0x1e, 0x73, 0xb3,
+    0xae, 0x3f, 0xbf, 0x9f, 0xf5, 0x44, 0xc8, 0x13, 0x8f, 0xd1, 0x01, 0xc2,
+    0x8a, 0x1a, 0x6d, 0xea, 0x4d, 0x00, 0x5d, 0x6e, 0x10, 0xe3, 0xdf, 0x0a,
+    0xe3, 0x7d, 0x8e, 0x7a, 0x99, 0xb5, 0xfe, 0x74, 0xb4, 0x46, 0x72, 0x10,
+    0x3d, 0xbd, 0xdc, 0xbd, 0x06, 0xaf, 0x68, 0x0d, 0x71, 0x32, 0x9a, 0x11,
+    0x69, 0x3b, 0xc7, 0x78, 0x93, 0xf1, 0x57, 0x97, 0x6e, 0xf0, 0x6e, 0x45,
+    0x37, 0x4a, 0xf4, 0x0b, 0x18, 0x51, 0xf5, 0x4f, 0x67, 0x3c, 0xdc, 0xec,
+    0x84, 0xed, 0xd0, 0xeb, 0xca, 0xfb, 0xdb, 0xff, 0x7f, 0xeb, 0xa8, 0x23,
+    0x68, 0x87, 0x13, 0x64, 0x6a, 0x10, 0xf7, 0x45, 0xe0, 0x0f, 0x32, 0x21,
+    0x59, 0x7c, 0x0e, 0x50, 0xad, 0x56, 0xd7, 0x12, 0x69, 0x7b, 0x58, 0xf8,
+    0xb9, 0x3b, 0xa5, 0xbb, 0x4d, 0x1b, 0x87, 0x1c, 0x46, 0xa7, 0x17, 0x9d,
+    0x6d, 0x84, 0x45, 0xbe, 0x7f, 0x95, 0xd2, 0x34, 0xcd, 0x89, 0x95, 0xc0,
+    0xf0, 0xd3, 0xdf, 0x6e, 0x10, 0x4a, 0xe3, 0x7b, 0xce, 0x7f, 0x40, 0x27,
+    0xc7, 0x2b, 0xab, 0x66, 0x03, 0x59, 0xb4, 0x7b, 0xc7, 0xc7, 0xf0, 0x39,
+    0x9a, 0x33, 0x35, 0xbf, 0xcc, 0x2f, 0xf3, 0x2e, 0x68, 0x9d, 0x53, 0x5c,
+    0x88, 0x52, 0xe3, 0x77, 0x90, 0xa1, 0x27, 0x85, 0xc5, 0x74, 0x7f, 0x23,
+    0x0e, 0x93, 0x01, 0x3e, 0xe7, 0x2e, 0x2e, 0x95, 0xf3, 0x0d, 0xc2, 0x25,
+    0x25, 0x39, 0x39, 0x3d, 0x6e, 0x8e, 0x89, 0xbd, 0xe8, 0xbb, 0x67, 0x5e,
+    0x8c, 0x66, 0x8b, 0x63, 0x28, 0x1e, 0x4e, 0x74, 0x85, 0xa8, 0xaf, 0x0f,
+    0x12, 0x5d, 0xb6, 0x8a, 0x83, 0x1a, 0x77, 0x76, 0x5e, 0x62, 0x8a, 0xa7,
+    0x3c, 0xb8, 0x05, 0x57, 0x2b, 0xaf, 0x36, 0x2e, 0x10, 0x90, 0xb2, 0x39,
+    0xb4, 0x3e, 0x75, 0x6d, 0x3a, 0xa8, 0x31, 0x35, 0xc2, 0x1e, 0x8f, 0xc2,
+    0x79, 0x89, 0x35, 0x16, 0x26, 0xd1, 0xc7, 0x0b, 0x04, 0x1f, 0x1d, 0xf9,
+    0x9c, 0x05, 0xa6, 0x6b, 0xb5, 0x19, 0x5a, 0x24, 0x6d, 0x91, 0xc5, 0x31,
+    0xfd, 0xc5, 0xfa, 0xe7, 0xa6, 0xcb, 0x0e, 0x4b, 0x18, 0x0d, 0x94, 0xc7,
+    0xee, 0x1d, 0x46, 0x1f, 0x92, 0xb1, 0xb2, 0x4a, 0x2b, 0x43, 0x37, 0xfe,
+    0xc2, 0x15, 0x11, 0x89, 0xef, 0x59, 0x73, 0x3c, 0x06, 0x76, 0x78, 0xcb,
+    0xa6, 0x0d, 0x79, 0x5f, 0x28, 0x0b, 0x5b, 0x8c, 0x9e, 0xe4, 0xaa, 0x51,
+    0x9a, 0x42, 0x6f, 0x11, 0x50, 0x3d, 0x01, 0xd6, 0x21, 0xc0, 0x99, 0x5e,
+    0x1a, 0xe8, 0x81, 0x25, 0x80, 0xeb, 0xed, 0x5d, 0x37, 0x47, 0x30, 0x70,
+    0xa0, 0x4e, 0x0b, 0x43, 0x17, 0xbe, 0xb6, 0x47, 0xe7, 0x2a, 0x62, 0x9d,
+    0x5d, 0xa6, 0xc5, 0x33, 0x62, 0x9d, 0x56, 0x24, 0x9d, 0x1d, 0xb2, 0x13,
+    0xbc, 0x17, 0x66, 0x43, 0xd1, 0x68, 0xd5, 0x3b, 0x17, 0x69, 0x17, 0xa6,
+    0x06, 0x9e, 0x12, 0xb8, 0x7c, 0xd5, 0xaf, 0x3e, 0x21, 0x1b, 0x31, 0xeb,
+    0x0b, 0xa4, 0x98, 0x1c, 0xf2, 0x6a, 0x5e, 0x7c, 0x9b, 0x45, 0x8f, 0xb2,
+    0x12, 0x06, 0xd5, 0x8c, 0x1d, 0xb2, 0xa7, 0x57, 0x5f, 0x2f, 0x4f, 0xdb,
+    0x52, 0x99, 0x7c, 0x58, 0x01, 0x5f, 0xf2, 0xa5, 0xf6, 0x51, 0x86, 0x21,
+    0x2f, 0x5b, 0x8d, 0x6a, 0xae, 0x83, 0x34, 0x6d, 0x58, 0x4b, 0xef, 0xfe,
+    0xbf, 0x73, 0x5d, 0xdb, 0xc4, 0x97, 0x2a, 0x85, 0xf3, 0x6c, 0x46, 0x42,
+    0xb3, 0x90, 0xc1, 0x57, 0x97, 0x50, 0x35, 0xb1, 0x9d, 0xb7, 0xc7, 0x3c,
+    0x85, 0x6d, 0x6c, 0xfd, 0xce, 0xb0, 0xc9, 0xa2, 0x77, 0xee, 0xc3, 0x6b,
+    0x0c, 0x37, 0xfa, 0x30, 0x91, 0xd1, 0x2c, 0xb8, 0x5e, 0x7f, 0x81, 0x5f,
+    0x87, 0xfd, 0x18, 0x02, 0x5a, 0x30, 0x4e, 0x62, 0xbc, 0x65, 0xc6, 0xce,
+    0x1a, 0xcf, 0x2b, 0xaa, 0x56, 0x3e, 0x4d, 0xcf, 0xba, 0x62, 0x5f, 0x9a,
+    0xd0, 0x72, 0xff, 0xef, 0x28, 0xbd, 0xbe, 0xd8, 0x57, 0x3d, 0xf5, 0x57,
+    0x7d, 0xe9, 0x71, 0x31, 0xec, 0x98, 0x90, 0x94, 0xd9, 0x54, 0xbf, 0x84,
+    0x0b, 0xe3, 0x06, 0x47, 0x19, 0x9a, 0x13, 0x1d, 0xef, 0x9d, 0x13, 0xf3,
+    0xdb, 0xc3, 0x5c, 0x72, 0x9e, 0xed, 0x24, 0xaa, 0x64, 0xed, 0xe7, 0x0d,
+    0xa0, 0x7c, 0x73, 0xba, 0x9b, 0x86, 0xa7, 0x3b, 0x55, 0xab, 0x58, 0x30,
+    0xf1, 0x15, 0x81, 0x83, 0x2f, 0xf9, 0x62, 0x84, 0x98, 0x66, 0xf6, 0x55,
+    0x21, 0xd8, 0xf2, 0x25, 0x64, 0x71, 0x4b, 0x12, 0x76, 0x59, 0xc5, 0xaa,
+    0x93, 0x67, 0xc3, 0x86, 0x25, 0xab, 0x4e, 0x4b, 0xf6, 0xd8, 0x3f, 0x44,
+    0x2e, 0x11, 0xe0, 0xbd, 0x6a, 0xf2, 0x5d, 0xf5, 0xf9, 0x53, 0xea, 0xa4,
+    0xc8, 0xd9, 0x50, 0x33, 0x81, 0xd9, 0xa8, 0x2d, 0x91, 0x7d, 0x13, 0x2a,
+    0x11, 0xcf, 0xde, 0x3f, 0x0a, 0xd2, 0xbc, 0x33, 0xb2, 0x62, 0x53, 0xea,
+    0x77, 0x88, 0x43, 0x66, 0x27, 0x43, 0x85, 0xe9, 0x5f, 0x55, 0xf5, 0x2a,
+    0x8a, 0xac, 0xdf, 0xff, 0x9b, 0x4c, 0x96, 0x9c, 0xa5, 0x7a, 0xce, 0xd5,
+    0x79, 0x18, 0xf1, 0x0b, 0x58, 0x95, 0x7a, 0xe7, 0xd3, 0x74, 0x65, 0x0b,
+    0xa4, 0x64, 0x30, 0xe8, 0x5c, 0xfc, 0x55, 0x56, 0xee, 0x14, 0x14, 0xd3,
+    0x45, 0x3b, 0xf8, 0xde, 0x05, 0x3e, 0xb9, 0x3c, 0xd7, 0x6a, 0x52, 0x72,
+    0x5b, 0x39, 0x09, 0xbe, 0x82, 0x23, 0x10, 0x4a, 0xb7, 0xc3, 0xdc, 0x4c,
+    0x5d, 0xc9, 0xf1, 0x14, 0x83, 0xf9, 0x0b, 0x9b, 0xe9, 0x23, 0x84, 0x6a,
+    0xc4, 0x08, 0x3d, 0xda, 0x3d, 0x12, 0x95, 0x87, 0x18, 0xa4, 0x7d, 0x3f,
+    0x23, 0xde, 0xd4, 0x1e, 0xa8, 0x47, 0xc3, 0x71, 0xdb, 0xf5, 0x03, 0x6c,
+    0x57, 0xe7, 0xa4, 0x43, 0x82, 0x33, 0x7b, 0x62, 0x46, 0x7d, 0xf7, 0x10,
+    0x69, 0x18, 0x38, 0x27, 0x9a, 0x6f, 0x38, 0xac, 0xfa, 0x92, 0xc5, 0xae,
+    0x66, 0xa6, 0x73, 0x95, 0x15, 0x0e, 0x4c, 0x04, 0xb6, 0xfc, 0xf5, 0xc7,
+    0x21, 0x3a, 0x99, 0xdb, 0x0e, 0x36, 0xf0, 0x56, 0xbc, 0x75, 0xf9, 0x87,
+    0x9b, 0x11, 0x18, 0x92, 0x64, 0x1a, 0xe7, 0xc7, 0xab, 0x5a, 0xc7, 0x26,
+    0x7f, 0x13, 0x98, 0x42, 0x52, 0x43, 0xdb, 0xc8, 0x6d, 0x0b, 0xb7, 0x31,
+    0x93, 0x24, 0xd6, 0xe8, 0x24, 0x1f, 0x6f, 0x21, 0xa7, 0x8c, 0xeb, 0xdb,
+    0x83, 0xb8, 0x89, 0xe3, 0xc1, 0xd7, 0x69, 0x3b, 0x02, 0x6b, 0x54, 0x0f,
+    0x84, 0x2f, 0xb5, 0x5c, 0x17, 0x77, 0xbe, 0xe5, 0x61, 0x0d, 0xc5, 0xdf,
+    0x3b, 0xcf, 0x3e, 0x93, 0x4f, 0xf5, 0x89, 0xb9, 0x5a, 0xc5, 0x29, 0x31,
+    0xc0, 0xc2, 0xff, 0xe5, 0x3f, 0xa6, 0xac, 0x03, 0xca, 0xf5, 0xff, 0xe0,
+    0x36, 0xce, 0xf3, 0xe2, 0xb7, 0x9c, 0x02, 0xe9, 0x9e, 0xd2, 0xbc, 0x87,
+    0x2f, 0x3d, 0x9a, 0x1d, 0x8f, 0xc5, 0x72, 0xb8, 0xa2, 0x01, 0xd4, 0x68,
+    0xb1, 0x84, 0x16, 0x10, 0xf6, 0xf3, 0x52, 0x25, 0xd9, 0xdc, 0x4c, 0xdd,
+    0x0f, 0xd6, 0x4a, 0xcf, 0x60, 0x96, 0x7e, 0xcc, 0x42, 0x0f, 0x64, 0x9d,
+    0x72, 0x46, 0x04, 0x07, 0xf2, 0x5b, 0xf4, 0x07, 0xd1, 0xf4, 0x59, 0x71,
+};
+
+static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = {
+    0xc8, 0xa6, 0x63, 0xc5, 0x97, 0xf1, 0xee, 0x40, 0xab, 0x62, 0x42, 0xee,
+    0x25, 0x6f, 0x32, 0x6c, 0x75, 0x2c, 0xa7, 0xd3, 0xbd, 0x32, 0x3b, 0x1e,
+    0x11, 0x9c, 0xbd, 0x04, 0xa9, 0x78, 0x6f, 0x45, 0x5a, 0xda, 0x7e, 0x4b,
+    0xf6, 0xdd, 0xd9, 0xad, 0xb6, 0x62, 0x6d, 0x32, 0x13, 0x1c, 0x6b, 0x5c,
+    0x51, 0xa1, 0xe3, 0x47, 0xa3, 0x47, 0x8f, 0x53, 0xcf, 0xcf, 0x44, 0x1b,
+    0x88, 0xee, 0xd1, 0x2e, 0x03, 0x89, 0xaf, 0xc0, 0x61, 0x2d, 0x9e, 0x35,
+    0xeb, 0x0e, 0x03, 0xe0, 0xb7, 0xfb, 0xa5, 0xbc, 0x44, 0xbe, 0x0c, 0x89,
+    0x0a, 0x0f, 0xd6, 0x59, 0x47, 0x9e, 0xe6, 0x3d, 0x36, 0x9d, 0xff, 0x44,
+    0x5e, 0xac, 0xab, 0xe5, 0x3a, 0xd5, 0xb0, 0x35, 0x9f, 0x6d, 0x7f, 0xba,
+    0xc0, 0x85, 0x0e, 0xf4, 0x70, 0x3f, 0x13, 0x90, 0x4c, 0x50, 0x1a, 0xee,
+    0xc5, 0xeb, 0x69, 0xfe, 0x98, 0x42, 0x87, 0x1d, 0xce, 0x6c, 0x29, 0xaa,
+    0x2b, 0x31, 0xc2, 0x38, 0x7b, 0x6b, 0xee, 0x88, 0x0b, 0xba, 0xce, 0xa8,
+    0xca, 0x19, 0x60, 0x1b, 0x16, 0xf1, 0x25, 0x1e, 0xcf, 0x63, 0x66, 0x1e,
+    0xbb, 0x63, 0xeb, 0x7d, 0xca, 0xd2, 0xb4, 0x23, 0x5a, 0x01, 0x6f, 0x05,
+    0xd1, 0xdc, 0x41, 0x73, 0x75, 0xc0, 0xfd, 0x30, 0x91, 0x52, 0x68, 0x96,
+    0x45, 0xb3, 0x66, 0x01, 0x3b, 0x53, 0x89, 0x3c, 0x69, 0xbc, 0x6c, 0x69,
+    0xe3, 0x51, 0x8f, 0xe3, 0xd2, 0x84, 0xd5, 0x28, 0x66, 0xb5, 0xe6, 0x06,
+    0x09, 0xfe, 0x6d, 0xb0, 0x72, 0x16, 0xe0, 0x8a, 0xce, 0x61, 0x65, 0xa9,
+    0x21, 0x32, 0x48, 0xdc, 0x7a, 0x1d, 0xe1, 0x38, 0x7f, 0x8c, 0x75, 0x88,
+    0x3d, 0x08, 0xa9, 0x4a, 0x6f, 0x3d, 0x9f, 0x7f, 0x3f, 0xbd, 0x57, 0x6b,
+    0x19, 0xce, 0x3f, 0x4a, 0xc9, 0xd3, 0xf9, 0x6e, 0x72, 0x7b, 0x5b, 0x74,
+    0xea, 0xbe, 0x9c, 0x7a, 0x6d, 0x9c, 0x40, 0x49, 0xe6, 0xfb, 0x2a, 0x1a,
+    0x75, 0x70, 0xe5, 0x4e, 0xed, 0x74, 0xe0, 0x75, 0xac, 0xc0, 0xb1, 0x11,
+    0x3e, 0xf2, 0xaf, 0x88, 0x4d, 0x66, 0xb6, 0xf6, 0x15, 0x4f, 0x3c, 0x6c,
+    0x77, 0xae, 0x47, 0x51, 0x63, 0x9a, 0xfe, 0xe1, 0xb4, 0x1a, 0x12, 0xdf,
+    0xe9, 0x54, 0x8d, 0x3b, 0x30, 0x2a, 0x75, 0xe3, 0xe5, 0x29, 0xb1, 0x4c,
+    0xb0, 0x7c, 0x6d, 0xb5, 0xae, 0x85, 0xdb, 0x1e, 0x38, 0x55, 0x96, 0xa5,
+    0x5b, 0x9f, 0x15, 0x23, 0x28, 0x36, 0xb8, 0xa2, 0x41, 0xb4, 0xd7, 0x19,
+    0x91, 0x8d, 0x26, 0x3e, 0xca, 0x9c, 0x05, 0x7a, 0x2b, 0x60, 0x45, 0x86,
+    0x8b, 0xee, 0x64, 0x6f, 0x5c, 0x09, 0x4d, 0x4b, 0x5a, 0x7f, 0xb0, 0xc3,
+    0x26, 0x9d, 0x8b, 0xb8, 0x83, 0x69, 0xcf, 0x16, 0x72, 0x62, 0x3e, 0x5e,
+    0x53, 0x4f, 0x9c, 0x73, 0x76, 0xfc, 0x19, 0xef, 0xa0, 0x74, 0x3a, 0x11,
+    0x1e, 0xd0, 0x4d, 0xb7, 0x87, 0xa1, 0xd6, 0x87, 0x6c, 0x0e, 0x6c, 0x8c,
+    0xe9, 0xa0, 0x44, 0xc4, 0x72, 0x3e, 0x73, 0x17, 0x13, 0xd1, 0x4e, 0x3d,
+    0x8e, 0x1d, 0x5a, 0x8b, 0x75, 0xcb, 0x59, 0x2c, 0x47, 0x87, 0x15, 0x41,
+    0xfe, 0x08, 0xe9, 0xa6, 0x97, 0x17, 0x08, 0x26, 0x6a, 0xb5, 0xbb, 0x73,
+    0xaa, 0xb8, 0x5b, 0x65, 0x65, 0x5b, 0x30, 0x9e, 0x62, 0x59, 0x02, 0xf8,
+    0xb8, 0x0f, 0x32, 0x10, 0xc1, 0x36, 0x08, 0x52, 0x98, 0x4a, 0x1e, 0xf0,
+    0xab, 0x21, 0x5e, 0xde, 0x16, 0x0c, 0xda, 0x09, 0x99, 0x6b, 0x9e, 0xc0,
+    0x90, 0xa5, 0x5a, 0xcc, 0xb0, 0xb7, 0xbb, 0xd2, 0x8b, 0x5f, 0xd3, 0x3b,
+    0x3e, 0x8c, 0xa5, 0x71, 0x66, 0x06, 0xe3, 0x28, 0xd4, 0xf8, 0x3f, 0xe5,
+    0x27, 0xdf, 0xfe, 0x0f, 0x09, 0xb2, 0x8a, 0x09, 0x5a, 0x23, 0x61, 0x0d,
+    0x2d, 0xf5, 0x44, 0xf1, 0x5c, 0xf8, 0x82, 0x4e, 0xdc, 0x78, 0x7a, 0xab,
+    0xc3, 0x57, 0x91, 0xaf, 0x65, 0x6e, 0x71, 0xf1, 0x44, 0xbf, 0xed, 0x43,
+    0x50, 0xb4, 0x67, 0x48, 0xef, 0x5a, 0x10, 0x46, 0x81, 0xb4, 0x0c, 0xc8,
+    0x48, 0xed, 0x99, 0x7a, 0x45, 0xa5, 0x92, 0xc3, 0x69, 0xd6, 0xd7, 0x8a,
+    0x20, 0x1b, 0xeb, 0x8f, 0xb2, 0xff, 0xec, 0x6d, 0x76, 0x04, 0xf8, 0xc2,
+    0x58, 0x9b, 0xf2, 0x20, 0x53, 0xc4, 0x74, 0x91, 0x19, 0xdd, 0x2d, 0x12,
+    0x53, 0xc7, 0x6e, 0xd0, 0x02, 0x51, 0x3c, 0xa6, 0x7d, 0x80, 0x75, 0x6b,
+    0x1d, 0xdf, 0xf8, 0x6a, 0x52, 0xbb, 0x81, 0xf8, 0x30, 0x45, 0xef, 0x51,
+    0x85, 0x36, 0xbe, 0x8e, 0xcf, 0x0b, 0x9a, 0x46, 0xe8, 0x3f, 0x99, 0xfd,
+    0xf7, 0xd9, 0x3e, 0x84, 0xe5, 0xe3, 0x37, 0xcf, 0x98, 0x7f, 0xeb, 0x5e,
+    0x5a, 0x53, 0x77, 0x1c, 0x20, 0xdc, 0xf1, 0x20, 0x99, 0xec, 0x60, 0x40,
+    0x93, 0xef, 0x5c, 0x1c, 0x81, 0xe2, 0xa5, 0xad, 0x2a, 0xc2, 0xdb, 0x6b,
+    0xc1, 0x7e, 0x8f, 0xa9, 0x23, 0x5b, 0xd9, 0x0d, 0xfe, 0xa0, 0xac, 0x11,
+    0x28, 0xba, 0x8e, 0x92, 0x07, 0x2d, 0x07, 0x40, 0x83, 0x14, 0x4c, 0x35,
+    0x8d, 0xd0, 0x11, 0xff, 0x98, 0xdb, 0x00, 0x30, 0x6f, 0x65, 0xb6, 0xa0,
+    0x7f, 0x9c, 0x08, 0xb8, 0xce, 0xb3, 0xa8, 0x42, 0xd3, 0x84, 0x45, 0xe1,
+    0xe3, 0x8f, 0xa6, 0x89, 0x21, 0xd7, 0x74, 0x02, 0x4d, 0x64, 0xdf, 0x54,
+    0x15, 0x9e, 0xba, 0x12, 0x49, 0x09, 0x41, 0xf6, 0x10, 0x24, 0xa1, 0x84,
+    0x15, 0xfd, 0x68, 0x6a, 0x57, 0x66, 0xb3, 0x6d, 0x4c, 0xea, 0xbf, 0xbc,
+    0x60, 0x3f, 0x52, 0x1c, 0x44, 0x1b, 0xc0, 0x4a, 0x25, 0xe3, 0xd9, 0x4c,
+    0x9a, 0x74, 0xad, 0xfc, 0x9e, 0x8d, 0x0b, 0x18, 0x66, 0x24, 0xd1, 0x06,
+    0xac, 0x68, 0xc1, 0xae, 0x14, 0xce, 0xb1, 0xf3, 0x86, 0x9f, 0x87, 0x11,
+    0xd7, 0x9f, 0x30, 0x92, 0xdb, 0xec, 0x0b, 0x4a, 0xe8, 0xf6, 0x53, 0x36,
+    0x68, 0x12, 0x11, 0x5e, 0xe0, 0x34, 0xa4, 0xff, 0x00, 0x0a, 0x26, 0xb8,
+    0x62, 0x79, 0x9c, 0x0c, 0xd5, 0xe5, 0xf5, 0x1c, 0x1a, 0x16, 0x84, 0x4d,
+    0x8e, 0x5d, 0x31, 0x7e, 0xf7, 0xe2, 0xd3, 0xa1, 0x41, 0x90, 0x61, 0x5d,
+    0x04, 0xb2, 0x9a, 0x18, 0x9e, 0x54, 0xfb, 0xd1, 0x61, 0x95, 0x1b, 0x08,
+    0xca, 0x7c, 0x49, 0x44, 0x74, 0x1d, 0x2f, 0xca, 0xc4, 0x7a, 0xe1, 0x8b,
+    0x2f, 0xbb, 0x96, 0xee, 0x19, 0x8a, 0x5d, 0xfb, 0x3e, 0x82, 0xe7, 0x15,
+    0xdb, 0x29, 0x14, 0xee, 0xc9, 0x4d, 0x9a, 0xfb, 0x9f, 0x8a, 0xbb, 0x17,
+    0x37, 0x1b, 0x6e, 0x28, 0x6c, 0xf9, 0xff, 0xb5, 0xb5, 0x8b, 0x9d, 0x88,
+    0x20, 0x08, 0x10, 0xd7, 0xca, 0x58, 0xf6, 0xe1, 0x32, 0x91, 0x6f, 0x36,
+    0xc0, 0xad, 0xc1, 0x57, 0x5d, 0x76, 0x31, 0x43, 0xf3, 0xdd, 0xec, 0xf1,
+    0xa9, 0x79, 0xe9, 0xe9, 0x85, 0xd7, 0x91, 0xc7, 0x31, 0x62, 0x3c, 0xd2,
+    0x90, 0x2c, 0x9c, 0xa4, 0x56, 0x37, 0x7b, 0xbe, 0x40, 0x58, 0xc0, 0x81,
+    0x83, 0x22, 0xe8, 0x13, 0x79, 0x18, 0xdb, 0x3a, 0x1b, 0x31, 0x0d, 0x00,
+    0x6c, 0x22, 0x62, 0x75, 0x70, 0xd8, 0x96, 0x59, 0x99, 0x44, 0x79, 0x71,
+    0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06,
+};
+
+enum spake2_state_t {
+  spake2_state_init = 0,
+  spake2_state_msg_generated,
+  spake2_state_key_generated,
+};
+
+struct spake2_ctx_st {
+  uint8_t private_key[32];
+  uint8_t my_msg[32];
+  uint8_t password_scalar[32];
+  uint8_t password_hash[SHA512_DIGEST_LENGTH];
+  uint8_t *my_name;
+  size_t my_name_len;
+  uint8_t *their_name;
+  size_t their_name_len;
+  enum spake2_role_t my_role;
+  enum spake2_state_t state;
+};
+
+SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role,
+                           const uint8_t *my_name, size_t my_name_len,
+                           const uint8_t *their_name, size_t their_name_len) {
+  SPAKE2_CTX *ctx = OPENSSL_malloc(sizeof(SPAKE2_CTX));
+  if (ctx == NULL) {
+    return NULL;
+  }
+
+  memset(ctx, 0, sizeof(SPAKE2_CTX));
+  ctx->my_role = my_role;
+
+  CBS my_name_cbs, their_name_cbs;
+  CBS_init(&my_name_cbs, my_name, my_name_len);
+  CBS_init(&their_name_cbs, their_name, their_name_len);
+  if (!CBS_stow(&my_name_cbs, &ctx->my_name, &ctx->my_name_len) ||
+      !CBS_stow(&their_name_cbs, &ctx->their_name, &ctx->their_name_len)) {
+    SPAKE2_CTX_free(ctx);
+    return NULL;
+  }
+
+  return ctx;
+}
+
+void SPAKE2_CTX_free(SPAKE2_CTX *ctx) {
+  if (ctx == NULL) {
+    return;
+  }
+
+  OPENSSL_free(ctx->my_name);
+  OPENSSL_free(ctx->their_name);
+  OPENSSL_free(ctx);
+}
+
+/* left_shift_3 sets |n| to |n|*8, where |n| is represented in little-endian
+ * order. */
+static void left_shift_3(uint8_t n[32]) {
+  uint8_t carry = 0;
+  unsigned i;
+
+  for (i = 0; i < 32; i++) {
+    const uint8_t next_carry = n[i] >> 5;
+    n[i] = (n[i] << 3) | carry;
+    carry = next_carry;
+  }
+}
+
+int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len,
+                         size_t max_out_len, const uint8_t *password,
+                         size_t password_len) {
+  if (ctx->state != spake2_state_init) {
+    return 0;
+  }
+
+  if (max_out_len < sizeof(ctx->my_msg)) {
+    return 0;
+  }
+
+  uint8_t private_tmp[64];
+  RAND_bytes(private_tmp, sizeof(private_tmp));
+  x25519_sc_reduce(private_tmp);
+  /* Multiply by the cofactor (eight) so that we'll clear it when operating on
+   * the peer's point later in the protocol. */
+  left_shift_3(private_tmp);
+  memcpy(ctx->private_key, private_tmp, sizeof(ctx->private_key));
+
+  ge_p3 P;
+  x25519_ge_scalarmult_base(&P, ctx->private_key);
+
+  /* mask = h(password) * <N or M>. */
+  uint8_t password_tmp[SHA512_DIGEST_LENGTH];
+  SHA512(password, password_len, password_tmp);
+  memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash));
+  x25519_sc_reduce(password_tmp);
+  memcpy(ctx->password_scalar, password_tmp, sizeof(ctx->password_scalar));
+
+  ge_p3 mask;
+  x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar,
+                              ctx->my_role == spake2_role_alice
+                                  ? kSpakeMSmallPrecomp
+                                  : kSpakeNSmallPrecomp);
+
+  /* P* = P + mask. */
+  ge_cached mask_cached;
+  x25519_ge_p3_to_cached(&mask_cached, &mask);
+  ge_p1p1 Pstar;
+  x25519_ge_add(&Pstar, &P, &mask_cached);
+
+  /* Encode P* */
+  ge_p2 Pstar_proj;
+  x25519_ge_p1p1_to_p2(&Pstar_proj, &Pstar);
+  x25519_ge_tobytes(ctx->my_msg, &Pstar_proj);
+
+  memcpy(out, ctx->my_msg, sizeof(ctx->my_msg));
+  *out_len = sizeof(ctx->my_msg);
+  ctx->state = spake2_state_msg_generated;
+
+  return 1;
+}
+
+static void update_with_length_prefix(SHA512_CTX *sha, const uint8_t *data,
+                                      const size_t len) {
+  uint8_t len_le[8];
+  size_t l = len;
+  unsigned i;
+
+  for (i = 0; i < 8; i++) {
+    len_le[i] = l & 0xff;
+    l >>= 8;
+  }
+
+  SHA512_Update(sha, len_le, sizeof(len_le));
+  SHA512_Update(sha, data, len);
+}
+
+int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, size_t *out_key_len,
+                       size_t max_out_key_len, const uint8_t *their_msg,
+                       size_t their_msg_len) {
+  if (ctx->state != spake2_state_msg_generated ||
+      their_msg_len != 32) {
+    return 0;
+  }
+
+  ge_p3 Qstar;
+  if (0 != x25519_ge_frombytes_vartime(&Qstar, their_msg)) {
+    /* Point received from peer was not on the curve. */
+    return 0;
+  }
+
+  /* Unmask peer's value. */
+  ge_p3 peers_mask;
+  x25519_ge_scalarmult_small_precomp(&peers_mask, ctx->password_scalar,
+                                    ctx->my_role == spake2_role_alice
+                                        ? kSpakeNSmallPrecomp
+                                        : kSpakeMSmallPrecomp);
+
+  ge_cached peers_mask_cached;
+  x25519_ge_p3_to_cached(&peers_mask_cached, &peers_mask);
+
+  ge_p1p1 Q_compl;
+  ge_p3 Q_ext;
+  x25519_ge_sub(&Q_compl, &Qstar, &peers_mask_cached);
+  x25519_ge_p1p1_to_p3(&Q_ext, &Q_compl);
+
+  ge_p2 dh_shared;
+  x25519_ge_scalarmult(&dh_shared, ctx->private_key, &Q_ext);
+
+  uint8_t dh_shared_encoded[32];
+  x25519_ge_tobytes(dh_shared_encoded, &dh_shared);
+
+  SHA512_CTX sha;
+  SHA512_Init(&sha);
+  if (ctx->my_role == spake2_role_alice) {
+    update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len);
+    update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len);
+    update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg));
+    update_with_length_prefix(&sha, their_msg, 32);
+  } else {
+    update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len);
+    update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len);
+    update_with_length_prefix(&sha, their_msg, 32);
+    update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg));
+  }
+  update_with_length_prefix(&sha, dh_shared_encoded, sizeof(dh_shared_encoded));
+  update_with_length_prefix(&sha, ctx->password_hash,
+                            sizeof(ctx->password_hash));
+
+  uint8_t key[SHA512_DIGEST_LENGTH];
+  SHA512_Final(key, &sha);
+
+  size_t to_copy = max_out_key_len;
+  if (to_copy > sizeof(key)) {
+    to_copy = sizeof(key);
+  }
+  memcpy(out_key, key, to_copy);
+  *out_key_len = to_copy;
+  ctx->state = spake2_state_key_generated;
+
+  return 1;
+}
diff --git a/src/crypto/curve25519/spake25519_test.cc b/src/crypto/curve25519/spake25519_test.cc
new file mode 100644
index 0000000..d97a860
--- /dev/null
+++ b/src/crypto/curve25519/spake25519_test.cc
@@ -0,0 +1,169 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <string>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/curve25519.h>
+#include "../test/scoped_types.h"
+
+
+struct SPAKE2Run {
+  bool Run() {
+    ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(
+        spake2_role_alice,
+        reinterpret_cast<const uint8_t *>(alice_names.first.data()),
+        alice_names.first.size(),
+        reinterpret_cast<const uint8_t *>(alice_names.second.data()),
+        alice_names.second.size()));
+    ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(
+        spake2_role_bob,
+        reinterpret_cast<const uint8_t *>(bob_names.first.data()),
+        bob_names.first.size(),
+        reinterpret_cast<const uint8_t *>(bob_names.second.data()),
+        bob_names.second.size()));
+
+    if (!alice || !bob) {
+      return false;
+    }
+
+    uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
+    uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE];
+    size_t alice_msg_len, bob_msg_len;
+
+    if (!SPAKE2_generate_msg(
+            alice.get(), alice_msg, &alice_msg_len, sizeof(alice_msg),
+            reinterpret_cast<const uint8_t *>(alice_password.data()),
+            alice_password.size()) ||
+        !SPAKE2_generate_msg(
+            bob.get(), bob_msg, &bob_msg_len, sizeof(bob_msg),
+            reinterpret_cast<const uint8_t *>(bob_password.data()),
+            bob_password.size())) {
+      return false;
+    }
+
+    if (alice_corrupt_msg_bit >= 0 &&
+        static_cast<size_t>(alice_corrupt_msg_bit) < 8 * alice_msg_len) {
+      alice_msg[alice_corrupt_msg_bit/8] ^= 1 << (alice_corrupt_msg_bit & 7);
+    }
+
+    uint8_t alice_key[64], bob_key[64];
+    size_t alice_key_len, bob_key_len;
+
+    if (!SPAKE2_process_msg(alice.get(), alice_key, &alice_key_len,
+                            sizeof(alice_key), bob_msg, bob_msg_len) ||
+        !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len, sizeof(bob_key),
+                            alice_msg, alice_msg_len)) {
+      return false;
+    }
+
+    key_matches_ = (alice_key_len == bob_key_len &&
+                    memcmp(alice_key, bob_key, alice_key_len) == 0);
+
+    return true;
+  }
+
+  bool key_matches() const {
+    return key_matches_;
+  }
+
+  std::string alice_password = "password";
+  std::string bob_password = "password";
+  std::pair<std::string, std::string> alice_names = {"alice", "bob"};
+  std::pair<std::string, std::string> bob_names = {"bob", "alice"};
+  int alice_corrupt_msg_bit = -1;
+
+ private:
+  bool key_matches_ = false;
+};
+
+static bool TestSPAKE2() {
+  for (unsigned i = 0; i < 20; i++) {
+    SPAKE2Run spake2;
+    if (!spake2.Run()) {
+      fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+      return false;
+    }
+
+    if (!spake2.key_matches()) {
+      fprintf(stderr, "Key didn't match for equal passwords.\n");
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static bool TestWrongPassword() {
+  SPAKE2Run spake2;
+  spake2.bob_password = "wrong password";
+  if (!spake2.Run()) {
+    fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+    return false;
+  }
+
+  if (spake2.key_matches()) {
+    fprintf(stderr, "Key matched for unequal passwords.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestWrongNames() {
+  SPAKE2Run spake2;
+  spake2.alice_names.second = "charlie";
+  spake2.bob_names.second = "charlie";
+  if (!spake2.Run()) {
+    fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+    return false;
+  }
+
+  if (spake2.key_matches()) {
+    fprintf(stderr, "Key matched for unequal names.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestCorruptMessages() {
+  for (int i = 0; i < 8 * SPAKE2_MAX_MSG_SIZE; i++) {
+    SPAKE2Run spake2;
+    spake2.alice_corrupt_msg_bit = i;
+    if (spake2.Run() && spake2.key_matches()) {
+      fprintf(stderr, "Passed after corrupting Alice's message, bit %d\n", i);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/* TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down. */
+
+int main(int argc, char **argv) {
+  if (!TestSPAKE2() ||
+      !TestWrongPassword() ||
+      !TestWrongNames() ||
+      !TestCorruptMessages()) {
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/curve25519/x25519_test.cc b/src/crypto/curve25519/x25519_test.cc
index 85ee4a2..24dfa65 100644
--- a/src/crypto/curve25519/x25519_test.cc
+++ b/src/crypto/curve25519/x25519_test.cc
@@ -20,8 +20,7 @@
 
 
 static bool TestX25519() {
-  /* Taken from
-   * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+  /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */
   static const uint8_t kScalar1[32] = {
       0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
       0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
@@ -91,8 +90,7 @@
 }
 
 static bool TestX25519Iterated() {
-  /* Taken from
-   * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+  /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */
   uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
 
   unsigned i;
diff --git a/src/crypto/dh/check.c b/src/crypto/dh/check.c
index 06af6f2..d27fdf1 100644
--- a/src/crypto/dh/check.c
+++ b/src/crypto/dh/check.c
@@ -62,30 +62,52 @@
 
 
 int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
-  int ok = 0;
-  BIGNUM q;
-
   *ret = 0;
-  BN_init(&q);
-  if (!BN_set_word(&q, 1)) {
+
+  BN_CTX *ctx = BN_CTX_new();
+  if (ctx == NULL) {
+    return 0;
+  }
+  BN_CTX_start(ctx);
+
+  int ok = 0;
+
+  /* Check |pub_key| is greater than 1. */
+  BIGNUM *tmp = BN_CTX_get(ctx);
+  if (tmp == NULL ||
+      !BN_set_word(tmp, 1)) {
     goto err;
   }
-
-  if (BN_cmp(pub_key, &q) <= 0) {
+  if (BN_cmp(pub_key, tmp) <= 0) {
     *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
   }
-  if (!BN_copy(&q, dh->p) ||
-      !BN_sub_word(&q, 1)) {
+
+  /* Check |pub_key| is less than |dh->p| - 1. */
+  if (!BN_copy(tmp, dh->p) ||
+      !BN_sub_word(tmp, 1)) {
     goto err;
   }
-  if (BN_cmp(pub_key, &q) >= 0) {
+  if (BN_cmp(pub_key, tmp) >= 0) {
     *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
   }
 
+  if (dh->q != NULL) {
+    /* Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114
+     * groups which are not safe primes but pick a generator on a prime-order
+     * subgroup of size |dh->q|. */
+    if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) {
+      goto err;
+    }
+    if (!BN_is_one(tmp)) {
+      *ret |= DH_CHECK_PUBKEY_INVALID;
+    }
+  }
+
   ok = 1;
 
 err:
-  BN_free(&q);
+  BN_CTX_end(ctx);
+  BN_CTX_free(ctx);
   return ok;
 }
 
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index bf6196c..a5cf94d 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -74,7 +74,7 @@
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 DH *DH_new(void) {
-  DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
+  DH *dh = OPENSSL_malloc(sizeof(DH));
   if (dh == NULL) {
     OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -236,7 +236,6 @@
   int generate_new_key = 0;
   unsigned l;
   BN_CTX *ctx = NULL;
-  BN_MONT_CTX *mont = NULL;
   BIGNUM *pub_key = NULL, *priv_key = NULL;
   BIGNUM local_priv;
 
@@ -269,9 +268,8 @@
     pub_key = dh->pub_key;
   }
 
-  mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
-                                dh->p, ctx);
-  if (!mont) {
+  if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+                              dh->p, ctx)) {
     goto err;
   }
 
@@ -293,7 +291,8 @@
   }
 
   BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
-  if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
+  if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx,
+                       dh->method_mont_p)) {
     goto err;
   }
 
@@ -318,7 +317,6 @@
 
 int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
   BN_CTX *ctx = NULL;
-  BN_MONT_CTX *mont = NULL;
   BIGNUM *shared_key;
   int ret = -1;
   int check_result;
@@ -344,9 +342,8 @@
     goto err;
   }
 
-  mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
-                                dh->p, ctx);
-  if (!mont) {
+  if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+                              dh->p, ctx)) {
     goto err;
   }
 
@@ -357,7 +354,7 @@
 
   BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
   if (!BN_mod_exp_mont(shared_key, peers_key, &local_priv, dh->p, ctx,
-                       mont)) {
+                       dh->method_mont_p)) {
     OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
     goto err;
   }
diff --git a/src/crypto/dh/dh_test.cc b/src/crypto/dh/dh_test.cc
index c117bd4..885bd32 100644
--- a/src/crypto/dh/dh_test.cc
+++ b/src/crypto/dh/dh_test.cc
@@ -72,12 +72,14 @@
 
 static bool RunBasicTests();
 static bool RunRFC5114Tests();
+static bool TestBadY();
 
 int main(int argc, char *argv[]) {
   CRYPTO_library_init();
 
   if (!RunBasicTests() ||
-      !RunRFC5114Tests()) {
+      !RunRFC5114Tests() ||
+      !TestBadY()) {
     ERR_print_errors_fp(stderr);
     return 1;
   }
@@ -477,3 +479,57 @@
 
   return 1;
 }
+
+// kRFC5114_2048_224BadY is a bad y-coordinate for RFC 5114's 2048-bit MODP
+// Group with 224-bit Prime Order Subgroup (section 2.2).
+static const uint8_t kRFC5114_2048_224BadY[] = {
+    0x45, 0x32, 0x5f, 0x51, 0x07, 0xe5, 0xdf, 0x1c, 0xd6, 0x02, 0x82, 0xb3,
+    0x32, 0x8f, 0xa4, 0x0f, 0x87, 0xb8, 0x41, 0xfe, 0xb9, 0x35, 0xde, 0xad,
+    0xc6, 0x26, 0x85, 0xb4, 0xff, 0x94, 0x8c, 0x12, 0x4c, 0xbf, 0x5b, 0x20,
+    0xc4, 0x46, 0xa3, 0x26, 0xeb, 0xa4, 0x25, 0xb7, 0x68, 0x8e, 0xcc, 0x67,
+    0xba, 0xea, 0x58, 0xd0, 0xf2, 0xe9, 0xd2, 0x24, 0x72, 0x60, 0xda, 0x88,
+    0x18, 0x9c, 0xe0, 0x31, 0x6a, 0xad, 0x50, 0x6d, 0x94, 0x35, 0x8b, 0x83,
+    0x4a, 0x6e, 0xfa, 0x48, 0x73, 0x0f, 0x83, 0x87, 0xff, 0x6b, 0x66, 0x1f,
+    0xa8, 0x82, 0xc6, 0x01, 0xe5, 0x80, 0xb5, 0xb0, 0x52, 0xd0, 0xe9, 0xd8,
+    0x72, 0xf9, 0x7d, 0x5b, 0x8b, 0xa5, 0x4c, 0xa5, 0x25, 0x95, 0x74, 0xe2,
+    0x7a, 0x61, 0x4e, 0xa7, 0x8f, 0x12, 0xe2, 0xd2, 0x9d, 0x8c, 0x02, 0x70,
+    0x34, 0x44, 0x32, 0xc7, 0xb2, 0xf3, 0xb9, 0xfe, 0x17, 0x2b, 0xd6, 0x1f,
+    0x8b, 0x7e, 0x4a, 0xfa, 0xa3, 0xb5, 0x3e, 0x7a, 0x81, 0x9a, 0x33, 0x66,
+    0x62, 0xa4, 0x50, 0x18, 0x3e, 0xa2, 0x5f, 0x00, 0x07, 0xd8, 0x9b, 0x22,
+    0xe4, 0xec, 0x84, 0xd5, 0xeb, 0x5a, 0xf3, 0x2a, 0x31, 0x23, 0xd8, 0x44,
+    0x22, 0x2a, 0x8b, 0x37, 0x44, 0xcc, 0xc6, 0x87, 0x4b, 0xbe, 0x50, 0x9d,
+    0x4a, 0xc4, 0x8e, 0x45, 0xcf, 0x72, 0x4d, 0xc0, 0x89, 0xb3, 0x72, 0xed,
+    0x33, 0x2c, 0xbc, 0x7f, 0x16, 0x39, 0x3b, 0xeb, 0xd2, 0xdd, 0xa8, 0x01,
+    0x73, 0x84, 0x62, 0xb9, 0x29, 0xd2, 0xc9, 0x51, 0x32, 0x9e, 0x7a, 0x6a,
+    0xcf, 0xc1, 0x0a, 0xdb, 0x0e, 0xe0, 0x62, 0x77, 0x6f, 0x59, 0x62, 0x72,
+    0x5a, 0x69, 0xa6, 0x5b, 0x70, 0xca, 0x65, 0xc4, 0x95, 0x6f, 0x9a, 0xc2,
+    0xdf, 0x72, 0x6d, 0xb1, 0x1e, 0x54, 0x7b, 0x51, 0xb4, 0xef, 0x7f, 0x89,
+    0x93, 0x74, 0x89, 0x59,
+};
+
+static bool TestBadY() {
+  ScopedDH dh(DH_get_2048_224(nullptr));
+  ScopedBIGNUM pub_key(
+      BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
+  if (!dh || !pub_key || !DH_generate_key(dh.get())) {
+    return false;
+  }
+
+  int flags;
+  if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) {
+    return false;
+  }
+  if (!(flags & DH_CHECK_PUBKEY_INVALID)) {
+    fprintf(stderr, "DH_check_pub_key did not reject the key.\n");
+    return false;
+  }
+
+  std::vector<uint8_t> result(DH_size(dh.get()));
+  if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) {
+    fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n");
+    return false;
+  }
+  ERR_clear_error();
+
+  return true;
+}
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index eb71b07..fdd9fe5 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -60,7 +60,6 @@
 #include <string.h>
 
 #include <openssl/err.h>
-#include <openssl/obj.h>
 #include <openssl/mem.h>
 
 #include "internal.h"
@@ -166,6 +165,7 @@
   if (ctx->digest != type) {
     if (ctx->digest && ctx->digest->ctx_size > 0) {
       OPENSSL_free(ctx->md_data);
+      ctx->md_data = NULL;
     }
     ctx->digest = type;
     if (type->ctx_size > 0) {
@@ -231,11 +231,11 @@
   return ctx->digest;
 }
 
-unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
+size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
   return EVP_MD_size(EVP_MD_CTX_md(ctx));
 }
 
-unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
+size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
   return EVP_MD_block_size(EVP_MD_CTX_md(ctx));
 }
 
diff --git a/src/crypto/digest/digest_test.cc b/src/crypto/digest/digest_test.cc
index 6a6113d..39ceaff 100644
--- a/src/crypto/digest/digest_test.cc
+++ b/src/crypto/digest/digest_test.cc
@@ -245,7 +245,6 @@
 
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   for (size_t i = 0; i < sizeof(kTestVectors) / sizeof(kTestVectors[0]); i++) {
     if (!TestDigest(&kTestVectors[i])) {
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index 9db8c54..4cf050c 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -140,89 +140,29 @@
 
 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
 
-#if !defined(PEDANTIC) && defined(__GNUC__) && __GNUC__ >= 2 && \
-    !defined(OPENSSL_NO_ASM)
-#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
-/* The first macro gives a ~30-40% performance improvement in SHA-256 compiled
- * with gcc on P4. This can only be done on x86, where unaligned data fetches
- * are possible. */
-#define HOST_c2l(c, l)                       \
-  (void)({                                   \
-    uint32_t r = *((const uint32_t *)(c));   \
-    __asm__("bswapl %0" : "=r"(r) : "0"(r)); \
-    (c) += 4;                                \
-    (l) = r;                                 \
-  })
-#define HOST_l2c(l, c)                       \
-  (void)({                                   \
-    uint32_t r = (l);                        \
-    __asm__("bswapl %0" : "=r"(r) : "0"(r)); \
-    *((uint32_t *)(c)) = r;                  \
-    (c) += 4;                                \
-    r;                                       \
-  })
-#elif defined(__aarch64__) && defined(__BYTE_ORDER__)
-#if defined(__ORDER_LITTLE_ENDIAN__) && \
-    __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define HOST_c2l(c, l)                                                 \
-  (void)({                                                             \
-    uint32_t r;                                                        \
-    __asm__("rev %w0, %w1" : "=r"(r) : "r"(*((const uint32_t *)(c)))); \
-    (c) += 4;                                                          \
-    (l) = r;                                                           \
-  })
-#define HOST_l2c(l, c)                                      \
-  (void)({                                                  \
-    uint32_t r;                                             \
-    __asm__("rev %w0, %w1" : "=r"(r) : "r"((uint32_t)(l))); \
-    *((uint32_t *)(c)) = r;                                 \
-    (c) += 4;                                               \
-    r;                                                      \
-  })
-#elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
-#define HOST_l2c(l, c) (*((uint32_t *)(c)) = (l), (c) += 4, (l))
-#endif /* __aarch64__ && __BYTE_ORDER__ */
-#endif /* ARCH */
-#endif /* !PEDANTIC && GNUC && !NO_ASM */
-
-#ifndef HOST_c2l
 #define HOST_c2l(c, l)                        \
   (void)(l = (((uint32_t)(*((c)++))) << 24),  \
          l |= (((uint32_t)(*((c)++))) << 16), \
          l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
-#endif
 
-#ifndef HOST_l2c
 #define HOST_l2c(l, c)                             \
   (void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
          *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
          *((c)++) = (uint8_t)(((l) >> 8) & 0xff),  \
          *((c)++) = (uint8_t)(((l)) & 0xff))
-#endif
 
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
 
-#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
-/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
-#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
-#define HOST_l2c(l, c) (void)(*((uint32_t *)(c)) = (l), (c) += 4, l)
-#endif /* OPENSSL_X86 || OPENSSL_X86_64 */
-
-#ifndef HOST_c2l
 #define HOST_c2l(c, l)                                                     \
   (void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
          l |= (((uint32_t)(*((c)++))) << 16),                              \
          l |= (((uint32_t)(*((c)++))) << 24))
-#endif
 
-#ifndef HOST_l2c
 #define HOST_l2c(l, c)                             \
   (void)(*((c)++) = (uint8_t)(((l)) & 0xff),       \
          *((c)++) = (uint8_t)(((l) >> 8) & 0xff),  \
          *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
          *((c)++) = (uint8_t)(((l) >> 24) & 0xff))
-#endif
 
 #endif /* DATA_ORDER */
 
diff --git a/src/crypto/directory.h b/src/crypto/directory.h
deleted file mode 100644
index 29123ea..0000000
--- a/src/crypto/directory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copied from Richard Levitte's (richard@levitte.org) LP library.  All
- * symbol names have been changed, with permission from the author. */
-
-/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
- */
-
-#ifndef OPENSSL_HEADER_DIRECTORY_H
-#define OPENSSL_HEADER_DIRECTORY_H
-
-#include <openssl/base.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-/* Directory functions abstract the O/S specific operations for opening and
- * reading directories in the filesystem. */
-
-
-/* OPENSSL_dir_context_st is an opaque structure that represents an open
- * directory and a position in that directory. */
-typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
-
-/* OPENSSL_DIR_read reads a single filename from |ctx|. On the first call,
- * |directory| must be given and |*ctx| must be NULL. Subsequent calls with the
- * same |*ctx| will return subsequent file names until it returns NULL to
- * indicate EOF. The strings returned reference a buffer internal to the
- * |OPENSSL_DIR_CTX| and will be overridden by subsequent calls. */
-OPENSSL_EXPORT const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
-                                            const char *directory);
-
-/* OPENSSL_DIR_end closes |*ctx|. It returns one on success and zero on
- * error. */
-OPENSSL_EXPORT int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
-
-
-#if defined(__cplusplus)
-}  /* extern C */
-#endif
-
-#endif  /* OPENSSL_HEADER_DIRECTORY_H */
diff --git a/src/crypto/directory_posix.c b/src/crypto/directory_posix.c
deleted file mode 100644
index b944b69..0000000
--- a/src/crypto/directory_posix.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``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 COPYRIGHT
- * OWNER 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. */
-
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201409  /* for readdir_r */
-#endif
-
-#include "directory.h"
-
-
-#if !defined(OPENSSL_WINDOWS)
-
-#include <dirent.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(OPENSSL_PNACL)
-/* pnacl doesn't include readdir_r! So we do the best we can. */
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
-  errno = 0;
-  *result = readdir(dirp);
-  if (*result != NULL) {
-    return 0;
-  }
-  if (errno) {
-    return 1;
-  }
-  return 0;
-}
-#endif
-
-struct OPENSSL_dir_context_st {
-  DIR *dir;
-  struct dirent dirent;
-};
-
-const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
-  struct dirent *dirent;
-
-  if (ctx == NULL || directory == NULL) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  errno = 0;
-  if (*ctx == NULL) {
-    *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
-    if (*ctx == NULL) {
-      errno = ENOMEM;
-      return 0;
-    }
-    memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
-
-    (*ctx)->dir = opendir(directory);
-    if ((*ctx)->dir == NULL) {
-      int save_errno = errno; /* Probably not needed, but I'm paranoid */
-      free(*ctx);
-      *ctx = NULL;
-      errno = save_errno;
-      return 0;
-    }
-  }
-
-  if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 ||
-      dirent == NULL) {
-    return 0;
-  }
-
-  return (*ctx)->dirent.d_name;
-}
-
-int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
-  if (ctx != NULL && *ctx != NULL) {
-    int r = closedir((*ctx)->dir);
-    free(*ctx);
-    *ctx = NULL;
-    return r == 0;
-  }
-
-  errno = EINVAL;
-  return 0;
-}
-
-#endif  /* !OPENSSL_WINDOWS */
diff --git a/src/crypto/directory_win.c b/src/crypto/directory_win.c
deleted file mode 100644
index 4ebacf2..0000000
--- a/src/crypto/directory_win.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``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 COPYRIGHT
- * OWNER 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.
- */
-
-#include "directory.h"
-
-
-#if defined(OPENSSL_WINDOWS)
-
-#pragma warning(push, 3)
-#include <windows.h>
-#pragma warning(pop)
-#include <errno.h>
-#include <string.h>
-#include <tchar.h>
-
-#ifndef NAME_MAX
-#define NAME_MAX 255
-#endif
-
-#include <openssl/mem.h>
-
-
-struct OPENSSL_dir_context_st {
-  WIN32_FIND_DATA ctx;
-  HANDLE handle;
-  char entry_name[NAME_MAX + 1];
-};
-
-const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
-  if (ctx == NULL || directory == NULL) {
-    errno = EINVAL;
-    return 0;
-  }
-
-  errno = 0;
-  if (*ctx == NULL) {
-    *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
-    if (*ctx == NULL) {
-      errno = ENOMEM;
-      return 0;
-    }
-    memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
-
-    if (sizeof(TCHAR) != sizeof(char)) {
-      TCHAR *wdir = NULL;
-      /* len_0 denotes string length *with* trailing 0 */
-      size_t index = 0, len_0 = strlen(directory) + 1;
-
-      wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
-      if (wdir == NULL) {
-        free(*ctx);
-        *ctx = NULL;
-        errno = ENOMEM;
-        return 0;
-      }
-
-      if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir,
-                               len_0)) {
-        for (index = 0; index < len_0; index++) {
-          wdir[index] = (TCHAR)directory[index];
-        }
-      }
-
-      (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
-
-      free(wdir);
-    } else {
-      (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
-    }
-
-    if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
-      free(*ctx);
-      *ctx = NULL;
-      errno = EINVAL;
-      return 0;
-    }
-  } else {
-    if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
-      return 0;
-    }
-  }
-
-  if (sizeof(TCHAR) != sizeof(char)) {
-    TCHAR *wdir = (*ctx)->ctx.cFileName;
-    size_t index, len_0 = 0;
-
-    while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) {
-      len_0++;
-    }
-    len_0++;
-
-    if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0,
-                             (*ctx)->entry_name, sizeof((*ctx)->entry_name),
-                             NULL, 0)) {
-      for (index = 0; index < len_0; index++) {
-        (*ctx)->entry_name[index] = (char)wdir[index];
-      }
-    }
-  } else {
-    strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
-            sizeof((*ctx)->entry_name) - 1);
-  }
-
-  (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
-
-  return (*ctx)->entry_name;
-}
-
-int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
-  if (ctx != NULL && *ctx != NULL) {
-    FindClose((*ctx)->handle);
-    free(*ctx);
-    *ctx = NULL;
-    return 1;
-  }
-  errno = EINVAL;
-  return 0;
-}
-
-#endif  /* OPENSSL_WINDOWS */
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index ebe55e8..fe29aa0 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -61,7 +61,6 @@
 
 #include <string.h>
 
-#include <openssl/asn1.h>
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 #include <openssl/digest.h>
@@ -73,7 +72,6 @@
 #include <openssl/sha.h>
 #include <openssl/thread.h>
 
-#include "internal.h"
 #include "../internal.h"
 
 
@@ -86,7 +84,7 @@
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 DSA *DSA_new(void) {
-  DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
+  DSA *dsa = OPENSSL_malloc(sizeof(DSA));
   if (dsa == NULL) {
     OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -94,7 +92,6 @@
 
   memset(dsa, 0, sizeof(DSA));
 
-  dsa->write_params = 1;
   dsa->references = 1;
 
   CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
@@ -393,6 +390,21 @@
   return ok;
 }
 
+DSA *DSAparams_dup(const DSA *dsa) {
+  DSA *ret = DSA_new();
+  if (ret == NULL) {
+    return NULL;
+  }
+  ret->p = BN_dup(dsa->p);
+  ret->q = BN_dup(dsa->q);
+  ret->g = BN_dup(dsa->g);
+  if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
+    DSA_free(ret);
+    return NULL;
+  }
+  return ret;
+}
+
 int DSA_generate_key(DSA *dsa) {
   int ok = 0;
   BN_CTX *ctx = NULL;
@@ -579,7 +591,6 @@
                            size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
   BN_CTX *ctx;
   BIGNUM u1, u2, t1;
-  BN_MONT_CTX *mont = NULL;
   int ret = 0;
   unsigned i;
 
@@ -650,15 +661,14 @@
     goto err;
   }
 
-  mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
-                                (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
-                                dsa->p, ctx);
-  if (!mont) {
+  if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+                              (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
+                              ctx)) {
     goto err;
   }
 
   if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
-                        mont)) {
+                        dsa->method_mont_p)) {
     goto err;
   }
 
@@ -740,24 +750,38 @@
   return ret;
 }
 
+/* der_len_len returns the number of bytes needed to represent a length of |len|
+ * in DER. */
+static size_t der_len_len(size_t len) {
+  if (len < 0x80) {
+    return 1;
+  }
+  size_t ret = 1;
+  while (len > 0) {
+    ret++;
+    len >>= 8;
+  }
+  return ret;
+}
+
 int DSA_size(const DSA *dsa) {
-  int ret, i;
-  ASN1_INTEGER bs;
-  unsigned char buf[4]; /* 4 bytes looks really small.
-                           However, i2d_ASN1_INTEGER() will not look
-                           beyond the first byte, as long as the second
-                           parameter is NULL. */
-
-  i = BN_num_bits(dsa->q);
-  bs.length = (i + 7) / 8;
-  bs.data = buf;
-  bs.type = V_ASN1_INTEGER;
-  /* If the top bit is set the asn1 encoding is 1 larger. */
-  buf[0] = 0xff;
-
-  i = i2d_ASN1_INTEGER(&bs, NULL);
-  i += i; /* r and s */
-  ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+  size_t order_len = BN_num_bytes(dsa->q);
+  /* Compute the maximum length of an |order_len| byte integer. Defensively
+   * assume that the leading 0x00 is included. */
+  size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
+  if (integer_len < order_len) {
+    return 0;
+  }
+  /* A DSA signature is two INTEGERs. */
+  size_t value_len = 2 * integer_len;
+  if (value_len < integer_len) {
+    return 0;
+  }
+  /* Add the header. */
+  size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
+  if (ret < value_len) {
+    return 0;
+  }
   return ret;
 }
 
@@ -797,9 +821,9 @@
 
   BN_set_flags(&k, BN_FLG_CONSTTIME);
 
-  if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
-                             (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
-                             ctx) == NULL) {
+  if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+                              (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
+                              ctx)) {
     goto err;
   }
 
diff --git a/src/crypto/dsa/dsa_asn1.c b/src/crypto/dsa/dsa_asn1.c
index b6b3fa4..ff5ee00 100644
--- a/src/crypto/dsa/dsa_asn1.c
+++ b/src/crypto/dsa/dsa_asn1.c
@@ -54,97 +54,286 @@
 
 #include <openssl/dsa.h>
 
-#include <string.h>
+#include <assert.h>
 
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-#include "internal.h"
+#include "../bytestring/internal.h"
 
 
-static int dsa_sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-                      void *exarg) {
-  if (operation != ASN1_OP_NEW_PRE) {
-    return 1;
-  }
-
-  DSA_SIG *sig;
-  sig = OPENSSL_malloc(sizeof(DSA_SIG));
-  if (!sig) {
-    OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
+static int parse_integer(CBS *cbs, BIGNUM **out) {
+  assert(*out == NULL);
+  *out = BN_new();
+  if (*out == NULL) {
     return 0;
   }
-
-  memset(sig, 0, sizeof(DSA_SIG));
-  *pval = (ASN1_VALUE *)sig;
-  return 2;
+  return BN_parse_asn1_unsigned(cbs, *out);
 }
 
-ASN1_SEQUENCE_cb(DSA_SIG, dsa_sig_cb) = {
-    ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
-    ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG);
-
-
-static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-                  void *exarg) {
-  switch (operation) {
-    case ASN1_OP_NEW_PRE:
-      *pval = (ASN1_VALUE *)DSA_new();
-      if (*pval) {
-        return 2;
-      }
-      return 0;
-
-    case ASN1_OP_FREE_PRE:
-      DSA_free((DSA *)*pval);
-      *pval = NULL;
-      return 2;
-
-    default:
-      return 1;
+static int marshal_integer(CBB *cbb, BIGNUM *bn) {
+  if (bn == NULL) {
+    /* A DSA object may be missing some components. */
+    OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
+    return 0;
   }
+  return BN_marshal_asn1(cbb, bn);
 }
 
-ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
-    ASN1_SIMPLE(DSA, version, LONG),
-    ASN1_SIMPLE(DSA, p, BIGNUM),
-    ASN1_SIMPLE(DSA, q, BIGNUM),
-    ASN1_SIMPLE(DSA, g, BIGNUM),
-    ASN1_SIMPLE(DSA, pub_key, BIGNUM),
-    ASN1_SIMPLE(DSA, priv_key, BIGNUM)} ASN1_SEQUENCE_END_cb(DSA,
-                                                             DSAPrivateKey);
+DSA_SIG *DSA_SIG_parse(CBS *cbs) {
+  DSA_SIG *ret = DSA_SIG_new();
+  if (ret == NULL) {
+    return NULL;
+  }
+  CBS child;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+      !parse_integer(&child, &ret->r) ||
+      !parse_integer(&child, &ret->s) ||
+      CBS_len(&child) != 0) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+    DSA_SIG_free(ret);
+    return NULL;
+  }
+  return ret;
+}
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey);
+int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
+  CBB child;
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+      !marshal_integer(&child, sig->r) ||
+      !marshal_integer(&child, sig->s) ||
+      !CBB_flush(cbb)) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+    return 0;
+  }
+  return 1;
+}
 
-ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
-    ASN1_SIMPLE(DSA, p, BIGNUM), ASN1_SIMPLE(DSA, q, BIGNUM),
-    ASN1_SIMPLE(DSA, g, BIGNUM), } ASN1_SEQUENCE_END_cb(DSA, DSAparams);
+DSA *DSA_parse_public_key(CBS *cbs) {
+  DSA *ret = DSA_new();
+  if (ret == NULL) {
+    return NULL;
+  }
+  CBS child;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+      !parse_integer(&child, &ret->pub_key) ||
+      !parse_integer(&child, &ret->p) ||
+      !parse_integer(&child, &ret->q) ||
+      !parse_integer(&child, &ret->g) ||
+      CBS_len(&child) != 0) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+    DSA_free(ret);
+    return NULL;
+  }
+  return ret;
+}
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams);
+int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
+  CBB child;
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+      !marshal_integer(&child, dsa->pub_key) ||
+      !marshal_integer(&child, dsa->p) ||
+      !marshal_integer(&child, dsa->q) ||
+      !marshal_integer(&child, dsa->g) ||
+      !CBB_flush(cbb)) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+    return 0;
+  }
+  return 1;
+}
 
+DSA *DSA_parse_parameters(CBS *cbs) {
+  DSA *ret = DSA_new();
+  if (ret == NULL) {
+    return NULL;
+  }
+  CBS child;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+      !parse_integer(&child, &ret->p) ||
+      !parse_integer(&child, &ret->q) ||
+      !parse_integer(&child, &ret->g) ||
+      CBS_len(&child) != 0) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+    DSA_free(ret);
+    return NULL;
+  }
+  return ret;
+}
 
-/* DSA public key is a bit trickier... its effectively a CHOICE type decided by
- * a field called write_params which can either write out just the public key
- * as an INTEGER or the parameters and public key in a SEQUENCE. */
+int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
+  CBB child;
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+      !marshal_integer(&child, dsa->p) ||
+      !marshal_integer(&child, dsa->q) ||
+      !marshal_integer(&child, dsa->g) ||
+      !CBB_flush(cbb)) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+    return 0;
+  }
+  return 1;
+}
 
-ASN1_SEQUENCE(dsa_pub_internal) = {
-	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
-	ASN1_SIMPLE(DSA, p, BIGNUM),
-	ASN1_SIMPLE(DSA, q, BIGNUM),
-	ASN1_SIMPLE(DSA, g, BIGNUM)
-} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal);
+DSA *DSA_parse_private_key(CBS *cbs) {
+  DSA *ret = DSA_new();
+  if (ret == NULL) {
+    return NULL;
+  }
 
-ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = {
-	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
-	ASN1_EX_COMBINE(0, 0, dsa_pub_internal)
-} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params);
+  CBS child;
+  uint64_t version;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1_uint64(&child, &version)) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+    goto err;
+  }
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey);
+  if (version != 0) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
+    goto err;
+  }
 
-DSA *DSAparams_dup(const DSA *dsa) {
-  return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), (DSA*) dsa);
+  if (!parse_integer(&child, &ret->p) ||
+      !parse_integer(&child, &ret->q) ||
+      !parse_integer(&child, &ret->g) ||
+      !parse_integer(&child, &ret->pub_key) ||
+      !parse_integer(&child, &ret->priv_key) ||
+      CBS_len(&child) != 0) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+    goto err;
+  }
+  return ret;
+
+err:
+  DSA_free(ret);
+  return NULL;
+}
+
+int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
+  CBB child;
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1_uint64(&child, 0 /* version */) ||
+      !marshal_integer(&child, dsa->p) ||
+      !marshal_integer(&child, dsa->q) ||
+      !marshal_integer(&child, dsa->g) ||
+      !marshal_integer(&child, dsa->pub_key) ||
+      !marshal_integer(&child, dsa->priv_key) ||
+      !CBB_flush(cbb)) {
+    OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+    return 0;
+  }
+  return 1;
+}
+
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
+  if (len < 0) {
+    return NULL;
+  }
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  DSA_SIG *ret = DSA_SIG_parse(&cbs);
+  if (ret == NULL) {
+    return NULL;
+  }
+  if (out_sig != NULL) {
+    DSA_SIG_free(*out_sig);
+    *out_sig = ret;
+  }
+  *inp = CBS_data(&cbs);
+  return ret;
+}
+
+int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !DSA_SIG_marshal(&cbb, in)) {
+    CBB_cleanup(&cbb);
+    return -1;
+  }
+  return CBB_finish_i2d(&cbb, outp);
+}
+
+DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
+  if (len < 0) {
+    return NULL;
+  }
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  DSA *ret = DSA_parse_public_key(&cbs);
+  if (ret == NULL) {
+    return NULL;
+  }
+  if (out != NULL) {
+    DSA_free(*out);
+    *out = ret;
+  }
+  *inp = CBS_data(&cbs);
+  return ret;
+}
+
+int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !DSA_marshal_public_key(&cbb, in)) {
+    CBB_cleanup(&cbb);
+    return -1;
+  }
+  return CBB_finish_i2d(&cbb, outp);
+}
+
+DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
+  if (len < 0) {
+    return NULL;
+  }
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  DSA *ret = DSA_parse_private_key(&cbs);
+  if (ret == NULL) {
+    return NULL;
+  }
+  if (out != NULL) {
+    DSA_free(*out);
+    *out = ret;
+  }
+  *inp = CBS_data(&cbs);
+  return ret;
+}
+
+int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !DSA_marshal_private_key(&cbb, in)) {
+    CBB_cleanup(&cbb);
+    return -1;
+  }
+  return CBB_finish_i2d(&cbb, outp);
+}
+
+DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
+  if (len < 0) {
+    return NULL;
+  }
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  DSA *ret = DSA_parse_parameters(&cbs);
+  if (ret == NULL) {
+    return NULL;
+  }
+  if (out != NULL) {
+    DSA_free(*out);
+    *out = ret;
+  }
+  *inp = CBS_data(&cbs);
+  return ret;
+}
+
+int i2d_DSAparams(const DSA *in, uint8_t **outp) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !DSA_marshal_parameters(&cbb, in)) {
+    CBB_cleanup(&cbb);
+    return -1;
+  }
+  return CBB_finish_i2d(&cbb, outp);
 }
diff --git a/src/crypto/dsa/dsa_test.c b/src/crypto/dsa/dsa_test.c
index 8bdaaf4..6296c8f 100644
--- a/src/crypto/dsa/dsa_test.c
+++ b/src/crypto/dsa/dsa_test.c
@@ -65,8 +65,6 @@
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 
-#include "internal.h"
-
 
 static int dsa_cb(int p, int n, BN_GENCB *arg);
 
diff --git a/src/crypto/ec/asm/p256-x86_64-asm.pl b/src/crypto/ec/asm/p256-x86_64-asm.pl
old mode 100644
new mode 100755
index 361a84b..50a5fe6
--- a/src/crypto/ec/asm/p256-x86_64-asm.pl
+++ b/src/crypto/ec/asm/p256-x86_64-asm.pl
@@ -1729,6 +1729,7 @@
 	push	%r15
 	sub	\$32*5+8, %rsp
 
+.Lpoint_double_shortcut$x:
 	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$a_ptr.x
 	mov	$a_ptr, $b_ptr			# backup copy
 	movdqu	0x10($a_ptr), %xmm1
@@ -2019,6 +2020,7 @@
 	 mov	0x40+8*1($b_ptr), $acc6
 	 mov	0x40+8*2($b_ptr), $acc7
 	 mov	0x40+8*3($b_ptr), $acc0
+	movq	$b_ptr, %xmm1
 
 	lea	0x40-$bias($b_ptr), $a_ptr
 	lea	$Z1sqr(%rsp), $r_ptr		# Z1^2
@@ -2074,7 +2076,7 @@
 	test	$acc0, $acc0
 	jnz	.Ladd_proceed$x			# (in1infty || in2infty)?
 	test	$acc1, $acc1
-	jz	.Ladd_proceed$x			# is_equal(S1,S2)?
+	jz	.Ladd_double$x			# is_equal(S1,S2)?
 
 	movq	%xmm0, $r_ptr			# restore $r_ptr
 	pxor	%xmm0, %xmm0
@@ -2087,6 +2089,13 @@
 	jmp	.Ladd_done$x
 
 .align	32
+.Ladd_double$x:
+	movq	%xmm1, $a_ptr			# restore $a_ptr
+	movq	%xmm0, $r_ptr			# restore $r_ptr
+	add	\$`32*(18-5)`, %rsp		# difference in frame sizes
+	jmp	.Lpoint_double_shortcut$x
+
+.align	32
 .Ladd_proceed$x:
 	`&load_for_sqr("$R(%rsp)", "$src0")`
 	lea	$Rsqr(%rsp), $r_ptr		# R^2
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 827cc57..8f3fa6e 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -73,7 +73,7 @@
 #include <openssl/bn.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 #include "../internal.h"
@@ -228,10 +228,25 @@
 #endif
 
 const struct built_in_curve OPENSSL_built_in_curves[] = {
-    {NID_secp521r1, &P521, 0},
-    {NID_secp384r1, &P384, 0},
     {
-        NID_X9_62_prime256v1, &P256,
+        NID_secp521r1,
+        /* 1.3.132.0.35 */
+        {0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
+        &P521,
+        NULL,
+      },
+    {
+        NID_secp384r1,
+        /* 1.3.132.0.34 */
+        {0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
+        &P384,
+        NULL,
+    },
+    {
+        NID_X9_62_prime256v1,
+        /* 1.2.840.10045.3.1.7 */
+        {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}, 8,
+        &P256,
 #if defined(BORINGSSL_USE_INT128_CODE)
 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
     !defined(OPENSSL_SMALL)
@@ -240,18 +255,21 @@
         EC_GFp_nistp256_method,
 #endif
 #else
-        0,
+        NULL,
 #endif
     },
     {
-        NID_secp224r1, &P224,
+        NID_secp224r1,
+        /* 1.3.132.0.33 */
+        {0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
+        &P224,
 #if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
         EC_GFp_nistp224_method,
 #else
-        0,
+        NULL,
 #endif
     },
-    {NID_undef, 0, 0},
+    {NID_undef, {0}, 0, NULL, NULL},
 };
 
 /* built_in_curve_scalar_field_monts contains Montgomery contexts for
@@ -373,40 +391,50 @@
 
 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|. */
+  if (group->curve_name != NID_undef || group->generator != NULL) {
+    /* |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
+     * |EC_GROUP_new_curve_GFp| and may only used once on each group. */
     return 0;
   }
 
-  if (group->generator == NULL) {
-    group->generator = EC_POINT_new(group);
-    if (group->generator == NULL) {
-      return 0;
-    }
+  group->generator = EC_POINT_new(group);
+  return group->generator != NULL &&
+         EC_POINT_copy(group->generator, generator) &&
+         BN_copy(&group->order, order) &&
+         BN_copy(&group->cofactor, cofactor);
+}
+
+EC_GROUP *EC_GROUP_new_arbitrary(const BIGNUM *p, const BIGNUM *a,
+                                 const BIGNUM *b, const BIGNUM *gx,
+                                 const BIGNUM *gy, const BIGNUM *order,
+                                 const BIGNUM *cofactor) {
+  BN_CTX *ctx = BN_CTX_new();
+  if (ctx == NULL) {
+    return NULL;
   }
 
-  if (!EC_POINT_copy(group->generator, generator)) {
-    return 0;
+  EC_POINT *generator = NULL;
+  EC_GROUP *ret = EC_GROUP_new_curve_GFp(p, a, b, ctx);
+  if (ret == NULL) {
+    goto err;
   }
 
-  if (order != NULL) {
-    if (!BN_copy(&group->order, order)) {
-      return 0;
-    }
-  } else {
-    BN_zero(&group->order);
+  generator = EC_POINT_new(ret);
+  if (generator == NULL ||
+      !EC_POINT_set_affine_coordinates_GFp(ret, generator, gx, gy, ctx) ||
+      !EC_GROUP_set_generator(ret, generator, order, cofactor)) {
+    goto err;
   }
 
-  if (cofactor != NULL) {
-    if (!BN_copy(&group->cofactor, cofactor)) {
-      return 0;
-    }
-  } else {
-    BN_zero(&group->cofactor);
-  }
+  EC_POINT_free(generator);
+  BN_CTX_free(ctx);
+  return ret;
 
-  return 1;
+err:
+  EC_POINT_free(generator);
+  EC_GROUP_free(ret);
+  BN_CTX_free(ctx);
+  return NULL;
 }
 
 static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
@@ -887,3 +915,21 @@
     abort();
   }
 }
+
+size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
+                             size_t max_num_curves) {
+  unsigned num_built_in_curves;
+  for (num_built_in_curves = 0;; num_built_in_curves++) {
+    if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
+      break;
+    }
+  }
+
+  unsigned i;
+  for (i = 0; i < max_num_curves && i < num_built_in_curves; i++) {
+    out_curves[i].comment = OPENSSL_built_in_curves[i].data->comment;
+    out_curves[i].nid = OPENSSL_built_in_curves[i].nid;
+  }
+
+  return num_built_in_curves;
+}
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index a085be5..f31e158 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -53,472 +53,435 @@
 
 #include <openssl/ec.h>
 
+#include <limits.h>
 #include <string.h>
 
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
 #include <openssl/bn.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
+#include "../bytestring/internal.h"
 
 
-typedef struct x9_62_fieldid_st {
-  ASN1_OBJECT *fieldType;
-  union {
-    char *ptr;
-    /* NID_X9_62_prime_field */
-    ASN1_INTEGER *prime;
-    /* anything else */
-    ASN1_TYPE *other;
-  } p;
-} X9_62_FIELDID;
+static const uint8_t kParametersTag =
+    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
+static const uint8_t kPublicKeyTag =
+    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
 
-ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
-
-ASN1_ADB(X9_62_FIELDID) = {
-  ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
-} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
-
-ASN1_SEQUENCE(X9_62_FIELDID) = {
-  ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
-  ASN1_ADB_OBJECT(X9_62_FIELDID)
-} ASN1_SEQUENCE_END(X9_62_FIELDID);
-
-typedef struct x9_62_curve_st {
-  ASN1_OCTET_STRING *a;
-  ASN1_OCTET_STRING *b;
-  ASN1_BIT_STRING *seed;
-} X9_62_CURVE;
-
-ASN1_SEQUENCE(X9_62_CURVE) = {
-  ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
-  ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
-  ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(X9_62_CURVE);
-
-typedef struct ec_parameters_st {
-  long version;
-  X9_62_FIELDID *fieldID;
-  X9_62_CURVE *curve;
-  ASN1_OCTET_STRING *base;
-  ASN1_INTEGER *order;
-  ASN1_INTEGER *cofactor;
-} ECPARAMETERS;
-
-DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
-
-ASN1_SEQUENCE(ECPARAMETERS) = {
-    ASN1_SIMPLE(ECPARAMETERS, version, LONG),
-    ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
-    ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
-    ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
-    ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
-    ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
-} ASN1_SEQUENCE_END(ECPARAMETERS);
-
-IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
-
-typedef struct ecpk_parameters_st {
-  int type;
-  union {
-    ASN1_OBJECT *named_curve;
-    ECPARAMETERS *parameters;
-  } value;
-} ECPKPARAMETERS;
-
-/* SEC1 ECPrivateKey */
-typedef struct ec_privatekey_st {
-  long version;
-  ASN1_OCTET_STRING *privateKey;
-  ECPKPARAMETERS *parameters;
-  ASN1_BIT_STRING *publicKey;
-} EC_PRIVATEKEY;
-
-DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS);
-
-ASN1_CHOICE(ECPKPARAMETERS) = {
-    ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
-    ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
-} ASN1_CHOICE_END(ECPKPARAMETERS);
-
-IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
-
-DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY);
-
-ASN1_SEQUENCE(EC_PRIVATEKEY) = {
-    ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
-    ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
-    ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
-    ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1),
-} ASN1_SEQUENCE_END(EC_PRIVATEKEY);
-
-IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
-
-
-ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
-                                           ECPKPARAMETERS *params) {
-  int ok = 0, nid;
-  ECPKPARAMETERS *ret = params;
-
-  if (ret == NULL) {
-    ret = ECPKPARAMETERS_new();
-    if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-      return NULL;
-    }
-  } else {
-    ASN1_OBJECT_free(ret->value.named_curve);
-  }
-
-  /* use the ASN.1 OID to describe the the elliptic curve parameters. */
-  nid = EC_GROUP_get_curve_name(group);
-  if (nid) {
-    ret->type = 0;
-    ret->value.named_curve = (ASN1_OBJECT*) OBJ_nid2obj(nid);
-    ok = ret->value.named_curve != NULL;
-  }
-
-  if (!ok) {
-    ECPKPARAMETERS_free(ret);
+EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
+  CBS ec_private_key, private_key;
+  uint64_t version;
+  if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1_uint64(&ec_private_key, &version) ||
+      version != 1 ||
+      !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
     return NULL;
   }
 
-  return ret;
-}
-
-EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
-  EC_GROUP *ret = NULL;
-  int nid = NID_undef;
-
-  if (params == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
-    return NULL;
-  }
-
-  if (params->type == 0) {
-    nid = OBJ_obj2nid(params->value.named_curve);
-  } else if (params->type == 1) {
-    /* We don't support arbitary curves so we attempt to recognise it from the
-     * group order. */
-    const ECPARAMETERS *ecparams = params->value.parameters;
-    unsigned i;
-    const struct built_in_curve *curve;
-
-    for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
-      curve = &OPENSSL_built_in_curves[i];
-      const unsigned param_len = curve->data->param_len;
-      if ((unsigned) ecparams->order->length == param_len &&
-          memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
-                 param_len) == 0) {
-        nid = curve->nid;
-        break;
-      }
-    }
-  }
-
-  if (nid == NID_undef) {
-    OPENSSL_PUT_ERROR(EC, EC_R_NON_NAMED_CURVE);
-    return NULL;
-  }
-
-  ret = EC_GROUP_new_by_curve_name(nid);
-  if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
-    return NULL;
-  }
-
-  return ret;
-}
-
-static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
-                                    long len) {
-  EC_GROUP *group = NULL;
-  ECPKPARAMETERS *params = NULL;
-  const uint8_t *in = *inp;
-
-  params = d2i_ECPKPARAMETERS(NULL, &in, len);
-  if (params == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_D2I_ECPKPARAMETERS_FAILURE);
-    ECPKPARAMETERS_free(params);
-    return NULL;
-  }
-
-  group = ec_asn1_pkparameters2group(params);
-  if (group == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_PKPARAMETERS2GROUP_FAILURE);
-    ECPKPARAMETERS_free(params);
-    return NULL;
-  }
-
-  if (groupp) {
-    EC_GROUP_free(*groupp);
-    *groupp = group;
-  }
-
-  ECPKPARAMETERS_free(params);
-  *inp = in;
-  return group;
-}
-
-static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
-  int ret = 0;
-  ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
-  if (tmp == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_GROUP2PKPARAMETERS_FAILURE);
-    return 0;
-  }
-  ret = i2d_ECPKPARAMETERS(tmp, outp);
-  if (ret == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
-    ECPKPARAMETERS_free(tmp);
-    return 0;
-  }
-  ECPKPARAMETERS_free(tmp);
-  return ret;
-}
-
-EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
-  int ok = 0;
+  /* Parse the optional parameters field. */
+  EC_GROUP *inner_group = NULL;
   EC_KEY *ret = NULL;
-  EC_PRIVATEKEY *priv_key = NULL;
-
-  const uint8_t *in = *inp;
-  priv_key = d2i_EC_PRIVATEKEY(NULL, &in, len);
-  if (priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-    return NULL;
-  }
-
-  if (a == NULL || *a == NULL) {
-    ret = EC_KEY_new();
-    if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+  if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) {
+    /* Per SEC 1, as an alternative to omitting it, one is allowed to specify
+     * this field and put in a NULL to mean inheriting this value. This was
+     * omitted in a previous version of this logic without problems, so leave it
+     * unimplemented. */
+    CBS child;
+    if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) {
+      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
       goto err;
     }
-  } else {
-    ret = *a;
+    inner_group = EC_KEY_parse_parameters(&child);
+    if (inner_group == NULL) {
+      goto err;
+    }
+    if (group == NULL) {
+      group = inner_group;
+    } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) {
+      /* If a group was supplied externally, it must match. */
+      OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
+      goto err;
+    }
+    if (CBS_len(&child) != 0) {
+      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+      goto err;
+    }
   }
 
-  if (priv_key->parameters) {
-    EC_GROUP_free(ret->group);
-    ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
-  }
-
-  if (ret->group == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+  if (group == NULL) {
+    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
     goto err;
   }
 
-  ret->version = priv_key->version;
-
-  if (priv_key->privateKey) {
-    ret->priv_key =
-        BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
-                  M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key);
-    if (ret->priv_key == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-      goto err;
-    }
-  } else {
-    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PRIVATE_KEY);
+  ret = EC_KEY_new();
+  if (ret == NULL || !EC_KEY_set_group(ret, group)) {
     goto err;
   }
 
-  if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) {
+  /* Although RFC 5915 specifies the length of the key, OpenSSL historically
+   * got this wrong, so accept any length. See upstream's
+   * 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. */
+  ret->priv_key =
+      BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL);
+  ret->pub_key = EC_POINT_new(group);
+  if (ret->priv_key == NULL || ret->pub_key == NULL) {
+    goto err;
+  }
+
+  if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(group)) >= 0) {
     OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
     goto err;
   }
 
-  EC_POINT_free(ret->pub_key);
-  ret->pub_key = EC_POINT_new(ret->group);
-  if (ret->pub_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-    goto err;
-  }
-
-  if (priv_key->publicKey) {
-    const uint8_t *pub_oct;
-    int pub_oct_len;
-
-    pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
-    pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
-    /* The first byte (the point conversion form) must be present. */
-    if (pub_oct_len <= 0) {
-      OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
+  if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) {
+    CBS child, public_key;
+    uint8_t padding;
+    if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) ||
+        !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
+        /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
+         * encoded as a BIT STRING with bits ordered as in the DER encoding. */
+        !CBS_get_u8(&public_key, &padding) ||
+        padding != 0 ||
+        /* Explicitly check |public_key| is non-empty to save the conversion
+         * form later. */
+        CBS_len(&public_key) == 0 ||
+        !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key),
+                            CBS_len(&public_key), NULL) ||
+        CBS_len(&child) != 0) {
+      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
       goto err;
     }
-    /* Save the point conversion form. */
-    ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
-    if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
-                            NULL)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-      goto err;
-    }
+
+    /* Save the point conversion form.
+     * TODO(davidben): Consider removing this. */
+    ret->conv_form = (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01);
   } else {
-    if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
-                      NULL)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+    /* Compute the public key instead. */
+    if (!EC_POINT_mul(group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
       goto err;
     }
-    /* Remember the original private-key-only encoding. */
+    /* Remember the original private-key-only encoding.
+     * TODO(davidben): Consider removing this. */
     ret->enc_flag |= EC_PKEY_NO_PUBKEY;
   }
 
-  if (a) {
-    *a = ret;
+  if (CBS_len(&ec_private_key) != 0) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+    goto err;
   }
-  *inp = in;
-  ok = 1;
+
+  /* Ensure the resulting key is valid. */
+  if (!EC_KEY_check_key(ret)) {
+    goto err;
+  }
+
+  EC_GROUP_free(inner_group);
+  return ret;
 
 err:
-  if (!ok) {
-    if (a == NULL || *a != ret) {
-      EC_KEY_free(ret);
-    }
-    ret = NULL;
+  EC_KEY_free(ret);
+  EC_GROUP_free(inner_group);
+  return NULL;
+}
+
+int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
+                               unsigned enc_flags) {
+  if (key == NULL || key->group == NULL || key->priv_key == NULL) {
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+    return 0;
   }
 
-  EC_PRIVATEKEY_free(priv_key);
+  CBB ec_private_key, private_key;
+  if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) ||
+      !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) ||
+      !BN_bn2cbb_padded(&private_key,
+                        BN_num_bytes(EC_GROUP_get0_order(key->group)),
+                        key->priv_key)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+    return 0;
+  }
 
+  if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) {
+    CBB child;
+    if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) ||
+        !EC_KEY_marshal_curve_name(&child, key->group) ||
+        !CBB_flush(&ec_private_key)) {
+      OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+      return 0;
+    }
+  }
+
+  /* TODO(fork): replace this flexibility with sensible default? */
+  if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
+    CBB child, public_key;
+    if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) ||
+        !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
+        /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
+         * encoded as a BIT STRING with bits ordered as in the DER encoding. */
+        !CBB_add_u8(&public_key, 0 /* padding */) ||
+        !EC_POINT_point2cbb(&public_key, key->group, key->pub_key,
+                            key->conv_form, NULL) ||
+        !CBB_flush(&ec_private_key)) {
+      OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+      return 0;
+    }
+  }
+
+  if (!CBB_flush(cbb)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+    return 0;
+  }
+
+  return 1;
+}
+
+/* is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and
+ * zero otherwise. */
+static int is_unsigned_integer(const CBS *cbs) {
+  if (CBS_len(cbs) == 0) {
+    return 0;
+  }
+  uint8_t byte = CBS_data(cbs)[0];
+  if ((byte & 0x80) ||
+      (byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) {
+    /* Negative or not minimally-encoded. */
+    return 0;
+  }
+  return 1;
+}
+
+/* kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. */
+static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01};
+
+static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
+                                      CBS *out_b, CBS *out_base_x,
+                                      CBS *out_base_y, CBS *out_order) {
+  /* See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an
+   * ECParameters while RFC 5480 calls it a SpecifiedECDomain. */
+  CBS params, field_id, field_type, curve, base;
+  uint64_t version;
+  if (!CBS_get_asn1(in, &params, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1_uint64(&params, &version) ||
+      version != 1 ||
+      !CBS_get_asn1(&params, &field_id, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
+      CBS_len(&field_type) != sizeof(kPrimeField) ||
+      memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 ||
+      !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) ||
+      !is_unsigned_integer(out_prime) ||
+      CBS_len(&field_id) != 0 ||
+      !CBS_get_asn1(&params, &curve, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) ||
+      !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) ||
+      /* |curve| has an optional BIT STRING seed which we ignore. */
+      !CBS_get_asn1(&params, &base, CBS_ASN1_OCTETSTRING) ||
+      !CBS_get_asn1(&params, out_order, CBS_ASN1_INTEGER) ||
+      !is_unsigned_integer(out_order)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+    return 0;
+  }
+
+  /* |params| has an optional cofactor which we ignore. With the optional seed
+   * in |curve|, a group already has arbitrarily many encodings. Parse enough to
+   * uniquely determine the curve. */
+
+  /* Require that the base point use uncompressed form. */
+  uint8_t form;
+  if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) {
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
+    return 0;
+  }
+
+  if (CBS_len(&base) % 2 != 0) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+    return 0;
+  }
+  size_t field_len = CBS_len(&base) / 2;
+  CBS_init(out_base_x, CBS_data(&base), field_len);
+  CBS_init(out_base_y, CBS_data(&base) + field_len, field_len);
+
+  return 1;
+}
+
+/* integers_equal returns one if |a| and |b| are equal, up to leading zeros, and
+ * zero otherwise. */
+static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) {
+  /* Remove leading zeros from |a| and |b|. */
+  CBS a_copy = *a;
+  while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) {
+    CBS_skip(&a_copy, 1);
+  }
+  while (b_len > 0 && b[0] == 0) {
+    b++;
+    b_len--;
+  }
+  return CBS_mem_equal(&a_copy, b, b_len);
+}
+
+EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) {
+  CBS named_curve;
+  if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+    return NULL;
+  }
+
+  /* Look for a matching curve. */
+  unsigned i;
+  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+    if (CBS_len(&named_curve) == curve->oid_len &&
+        memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == 0) {
+      return EC_GROUP_new_by_curve_name(curve->nid);
+    }
+  }
+
+  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+  return NULL;
+}
+
+int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) {
+  int nid = EC_GROUP_get_curve_name(group);
+  if (nid == NID_undef) {
+    OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+    return 0;
+  }
+
+  unsigned i;
+  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+    if (curve->nid == nid) {
+      CBB child;
+      return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) &&
+             CBB_add_bytes(&child, curve->oid, curve->oid_len) &&
+             CBB_flush(cbb);
+    }
+  }
+
+  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+  return 0;
+}
+
+EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) {
+  if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) {
+    return EC_KEY_parse_curve_name(cbs);
+  }
+
+  /* OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions
+   * of named curves.
+   *
+   * TODO(davidben): Remove support for this. */
+  CBS prime, a, b, base_x, base_y, order;
+  if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y,
+                                  &order)) {
+    return NULL;
+  }
+
+  /* Look for a matching prime curve. */
+  unsigned i;
+  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+    const unsigned param_len = curve->data->param_len;
+    /* |curve->data->data| is ordered p, a, b, x, y, order, each component
+     * zero-padded up to the field length. Although SEC 1 states that the
+     * Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes
+     * |a| and |b|, so this comparison must allow omitting leading zeros. (This
+     * is relevant for P-521 whose |b| has a leading 0.) */
+    if (integers_equal(&prime, curve->data->data, param_len) &&
+        integers_equal(&a, curve->data->data + param_len, param_len) &&
+        integers_equal(&b, curve->data->data + param_len * 2, param_len) &&
+        integers_equal(&base_x, curve->data->data + param_len * 3, param_len) &&
+        integers_equal(&base_y, curve->data->data + param_len * 4, param_len) &&
+        integers_equal(&order, curve->data->data + param_len * 5, param_len)) {
+      return EC_GROUP_new_by_curve_name(curve->nid);
+    }
+  }
+
+  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+  return NULL;
+}
+
+EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) {
+  /* This function treats its |out| parameter differently from other |d2i|
+   * functions. If supplied, take the group from |*out|. */
+  const EC_GROUP *group = NULL;
+  if (out != NULL && *out != NULL) {
+    group = EC_KEY_get0_group(*out);
+  }
+
+  if (len < 0) {
+    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+    return NULL;
+  }
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group);
+  if (ret == NULL) {
+    return NULL;
+  }
+  if (out != NULL) {
+    EC_KEY_free(*out);
+    *out = ret;
+  }
+  *inp = CBS_data(&cbs);
   return ret;
 }
 
 int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
-  int ret = 0, ok = 0;
-  uint8_t *buffer = NULL;
-  size_t buf_len = 0, tmp_len;
-  EC_PRIVATEKEY *priv_key = NULL;
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) {
+    CBB_cleanup(&cbb);
+    return -1;
+  }
+  return CBB_finish_i2d(&cbb, outp);
+}
 
-  if (key == NULL || key->group == NULL || key->priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
-    goto err;
+EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) {
+  if (len < 0) {
+    return NULL;
   }
 
-  priv_key = EC_PRIVATEKEY_new();
-  if (priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-    goto err;
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
+  if (group == NULL) {
+    return NULL;
   }
 
-  priv_key->version = key->version;
-
-  buf_len = BN_num_bytes(&key->group->order);
-  buffer = OPENSSL_malloc(buf_len);
-  if (buffer == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-    goto err;
+  EC_KEY *ret = EC_KEY_new();
+  if (ret == NULL || !EC_KEY_set_group(ret, group)) {
+    EC_GROUP_free(group);
+    EC_KEY_free(ret);
+    return NULL;
   }
+  EC_GROUP_free(group);
 
-  if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-    goto err;
+  if (out_key != NULL) {
+    EC_KEY_free(*out_key);
+    *out_key = ret;
   }
-
-  if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
-    goto err;
-  }
-
-  /* TODO(fork): replace this flexibility with key sensible default? */
-  if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
-    if ((priv_key->parameters = ec_asn1_group2pkparameters(
-             key->group, priv_key->parameters)) == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-      goto err;
-    }
-  }
-
-  /* TODO(fork): replace this flexibility with key sensible default? */
-  if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
-    priv_key->publicKey = M_ASN1_BIT_STRING_new();
-    if (priv_key->publicKey == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-
-    tmp_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
-                                 0, NULL);
-
-    if (tmp_len > buf_len) {
-      uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
-      if (!tmp_buffer) {
-        OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-        goto err;
-      }
-      buffer = tmp_buffer;
-      buf_len = tmp_len;
-    }
-
-    if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
-                            buf_len, NULL)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-      goto err;
-    }
-
-    priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-    priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-    if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
-      goto err;
-    }
-  }
-
-  ret = i2d_EC_PRIVATEKEY(priv_key, outp);
-  if (ret == 0) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-    goto err;
-  }
-  ok = 1;
-
-err:
-  OPENSSL_free(buffer);
-  EC_PRIVATEKEY_free(priv_key);
-  return (ok ? ret : 0);
+  *inp = CBS_data(&cbs);
+  return ret;
 }
 
 int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
-  if (key == NULL) {
+  if (key == NULL || key->group == NULL) {
     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
-    return 0;
-  }
-  return i2d_ECPKParameters(key->group, outp);
-}
-
-EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
-  EC_KEY *ret;
-
-  if (inp == NULL || *inp == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
-    return NULL;
+    return -1;
   }
 
-  if (key == NULL || *key == NULL) {
-    ret = EC_KEY_new();
-    if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-      return NULL;
-    }
-  } else {
-    ret = *key;
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !EC_KEY_marshal_curve_name(&cbb, key->group)) {
+    CBB_cleanup(&cbb);
+    return -1;
   }
-
-  if (!d2i_ECPKParameters(&ret->group, inp, len)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-    if (key == NULL || *key == NULL) {
-      EC_KEY_free(ret);
-    }
-    return NULL;
-  }
-
-  if (key) {
-    *key = ret;
-  }
-  return ret;
+  return CBB_finish_i2d(&cbb, outp);
 }
 
 EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
@@ -526,17 +489,17 @@
 
   if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
-    return 0;
+    return NULL;
   }
   ret = *keyp;
   if (ret->pub_key == NULL &&
       (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-    return 0;
+    return NULL;
   }
   if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-    return 0;
+    return NULL;
   }
   /* save the point conversion form */
   ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index d3bf4c6..fee71fe 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -85,7 +85,7 @@
 EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); }
 
 EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
-  EC_KEY *ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
+  EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY));
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -100,7 +100,6 @@
     METHOD_ref(ret->ecdsa_meth);
   }
 
-  ret->version = 1;
   ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
   ret->references = 1;
 
@@ -209,8 +208,6 @@
   /* copy the rest */
   dest->enc_flag = src->enc_flag;
   dest->conv_form = src->conv_form;
-  dest->version = src->version;
-  dest->flags = src->flags;
 
   return dest;
 }
@@ -368,15 +365,24 @@
     return 0;
   }
   ctx = BN_CTX_new();
+
+  if (ctx == NULL) {
+    return 0;
+  }
+
+  BN_CTX_start(ctx);
   point = EC_POINT_new(key->group);
 
-  if (ctx == NULL ||
-      point == NULL) {
+  if (point == NULL) {
     goto err;
   }
 
   tx = BN_CTX_get(ctx);
   ty = BN_CTX_get(ctx);
+  if (tx == NULL ||
+      ty == NULL) {
+    goto err;
+  }
 
   if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, ctx) ||
       !EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, ctx)) {
@@ -401,6 +407,7 @@
   ok = 1;
 
 err:
+  BN_CTX_end(ctx);
   BN_CTX_free(ctx);
   EC_POINT_free(point);
   return ok;
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 1d4113d..35df365 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -79,31 +79,18 @@
 
   ok = ec_GFp_simple_group_init(group);
   group->mont = NULL;
-  group->one = NULL;
   return ok;
 }
 
 void ec_GFp_mont_group_finish(EC_GROUP *group) {
   BN_MONT_CTX_free(group->mont);
   group->mont = NULL;
-  BN_free(group->one);
-  group->one = NULL;
   ec_GFp_simple_group_finish(group);
 }
 
-void ec_GFp_mont_group_clear_finish(EC_GROUP *group) {
-  BN_MONT_CTX_free(group->mont);
-  group->mont = NULL;
-  BN_clear_free(group->one);
-  group->one = NULL;
-  ec_GFp_simple_group_clear_finish(group);
-}
-
 int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
   BN_MONT_CTX_free(dest->mont);
   dest->mont = NULL;
-  BN_clear_free(dest->one);
-  dest->one = NULL;
 
   if (!ec_GFp_simple_group_copy(dest, src)) {
     return 0;
@@ -118,12 +105,6 @@
       goto err;
     }
   }
-  if (src->one != NULL) {
-    dest->one = BN_dup(src->one);
-    if (dest->one == NULL) {
-      goto err;
-    }
-  }
 
   return 1;
 
@@ -137,13 +118,10 @@
                                 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
   BN_CTX *new_ctx = NULL;
   BN_MONT_CTX *mont = NULL;
-  BIGNUM *one = NULL;
   int ret = 0;
 
   BN_MONT_CTX_free(group->mont);
   group->mont = NULL;
-  BN_free(group->one);
-  group->one = NULL;
 
   if (ctx == NULL) {
     ctx = new_ctx = BN_CTX_new();
@@ -160,29 +138,20 @@
     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
-  one = BN_new();
-  if (one == NULL || !BN_to_montgomery(one, BN_value_one(), mont, ctx)) {
-    goto err;
-  }
 
   group->mont = mont;
   mont = NULL;
-  group->one = one;
-  one = NULL;
 
   ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
 
   if (!ret) {
     BN_MONT_CTX_free(group->mont);
     group->mont = NULL;
-    BN_free(group->one);
-    group->one = NULL;
   }
 
 err:
   BN_CTX_free(new_ctx);
   BN_MONT_CTX_free(mont);
-  BN_free(one);
   return ret;
 }
 
@@ -226,19 +195,6 @@
   return BN_from_montgomery(r, a, group->mont, ctx);
 }
 
-int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
-                                 BN_CTX *ctx) {
-  if (group->one == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
-    return 0;
-  }
-
-  if (!BN_copy(r, group->one)) {
-    return 0;
-  }
-  return 1;
-}
-
 static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group,
                                            const EC_POINT* pub_key,
                                            BN_CTX *ctx) {
@@ -259,21 +215,108 @@
   return ret;
 }
 
+static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
+                                                    const EC_POINT *point,
+                                                    BIGNUM *x, BIGNUM *y,
+                                                    BN_CTX *ctx) {
+  if (EC_POINT_is_at_infinity(group, point)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+    return 0;
+  }
+
+  BN_CTX *new_ctx = NULL;
+  if (ctx == NULL) {
+    ctx = new_ctx = BN_CTX_new();
+    if (ctx == NULL) {
+      return 0;
+    }
+  }
+
+  int ret = 0;
+
+  BN_CTX_start(ctx);
+
+  if (BN_cmp(&point->Z, &group->one) == 0) {
+    /* |point| is already affine. */
+    if (x != NULL && !BN_from_montgomery(x, &point->X, group->mont, ctx)) {
+      goto err;
+    }
+    if (y != NULL && !BN_from_montgomery(y, &point->Y, group->mont, ctx)) {
+      goto err;
+    }
+  } else {
+    /* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
+
+    BIGNUM *Z_1 = BN_CTX_get(ctx);
+    BIGNUM *Z_2 = BN_CTX_get(ctx);
+    BIGNUM *Z_3 = BN_CTX_get(ctx);
+    if (Z_1 == NULL ||
+        Z_2 == NULL ||
+        Z_3 == NULL) {
+      goto err;
+    }
+
+    /* The straightforward way to calculate the inverse of a Montgomery-encoded
+     * value where the result is Montgomery-encoded is:
+     *
+     *    |BN_from_montgomery| + |BN_mod_inverse| + |BN_to_montgomery|.
+     *
+     * This is equivalent, but more efficient, because |BN_from_montgomery|
+     * is more efficient (at least in theory) than |BN_to_montgomery|, since it
+     * doesn't have to do the multiplication before the reduction. */
+    if (!BN_from_montgomery(Z_1, &point->Z, group->mont, ctx) ||
+        !BN_from_montgomery(Z_1, Z_1, group->mont, ctx) ||
+        !BN_mod_inverse(Z_1, Z_1, &group->field, ctx)) {
+      goto err;
+    }
+
+    if (!BN_mod_mul_montgomery(Z_2, Z_1, Z_1, group->mont, ctx)) {
+      goto err;
+    }
+
+    /* Instead of using |BN_from_montgomery| to convert the |x| coordinate
+     * and then calling |BN_from_montgomery| again to convert the |y|
+     * coordinate below, convert the common factor |Z_2| once now, saving one
+     * reduction. */
+    if (!BN_from_montgomery(Z_2, Z_2, group->mont, ctx)) {
+      goto err;
+    }
+
+    if (x != NULL) {
+      if (!BN_mod_mul_montgomery(x, &point->X, Z_2, group->mont, ctx)) {
+        goto err;
+      }
+    }
+
+    if (y != NULL) {
+      if (!BN_mod_mul_montgomery(Z_3, Z_2, Z_1, group->mont, ctx) ||
+          !BN_mod_mul_montgomery(y, &point->Y, Z_3, group->mont, ctx)) {
+        goto err;
+      }
+    }
+  }
+
+  ret = 1;
+
+err:
+  BN_CTX_end(ctx);
+  BN_CTX_free(new_ctx);
+  return ret;
+}
+
 const EC_METHOD *EC_GFp_mont_method(void) {
   static const EC_METHOD ret = {
     ec_GFp_mont_group_init,
     ec_GFp_mont_group_finish,
-    ec_GFp_mont_group_clear_finish,
     ec_GFp_mont_group_copy,
     ec_GFp_mont_group_set_curve,
-    ec_GFp_simple_point_get_affine_coordinates,
+    ec_GFp_mont_point_get_affine_coordinates,
     ec_wNAF_mul /* XXX: Not constant time. */,
     ec_GFp_mont_check_pub_key_order,
     ec_GFp_mont_field_mul,
     ec_GFp_mont_field_sqr,
     ec_GFp_mont_field_encode,
     ec_GFp_mont_field_decode,
-    ec_GFp_mont_field_set_to_one,
   };
 
   return &ret;
diff --git a/src/crypto/ec/ec_test.cc b/src/crypto/ec/ec_test.cc
index 2088e72..ce9d99f 100644
--- a/src/crypto/ec/ec_test.cc
+++ b/src/crypto/ec/ec_test.cc
@@ -17,6 +17,7 @@
 
 #include <vector>
 
+#include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 #include <openssl/ec_key.h>
 #include <openssl/err.h>
@@ -34,6 +35,36 @@
   0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
 };
 
+// kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
+// spelled out rather than using a named curve.
+static const uint8_t kECKeySpecifiedCurve[] = {
+    0x30, 0x82, 0x01, 0x22, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa,
+    0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
+    0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc,
+    0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x81, 0xfa, 0x30, 0x81, 0xf7, 0x02,
+    0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
+    0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+    0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
+    0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+    0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
+    0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
+    0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
+    0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
+    0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+    0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
+    0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+    0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+    0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
+    0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
+    0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
+    0x63, 0x25, 0x51, 0x02, 0x01, 0x01,
+};
+
 // kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
 // the private key is one. The private key is incorrectly encoded without zero
 // padding.
@@ -66,9 +97,10 @@
 // DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
 // result or nullptr on error.
 static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
-  const uint8_t *inp = in;
-  ScopedEC_KEY ret(d2i_ECPrivateKey(NULL, &inp, in_len));
-  if (!ret || inp != in + in_len) {
+  CBS cbs;
+  CBS_init(&cbs, in, in_len);
+  ScopedEC_KEY ret(EC_KEY_parse_private_key(&cbs, NULL));
+  if (!ret || CBS_len(&cbs) != 0) {
     return nullptr;
   }
   return ret;
@@ -76,14 +108,21 @@
 
 // EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
 // returns true on success or false on error.
-static bool EncodeECPrivateKey(std::vector<uint8_t> *out, EC_KEY *key) {
-  int len = i2d_ECPrivateKey(key, NULL);
-  out->resize(len);
-  uint8_t *outp = out->data();
-  return i2d_ECPrivateKey(key, &outp) == len;
+static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
+  ScopedCBB cbb;
+  uint8_t *der;
+  size_t der_len;
+  if (!CBB_init(cbb.get(), 0) ||
+      !EC_KEY_marshal_private_key(cbb.get(), key, EC_KEY_get_enc_flags(key)) ||
+      !CBB_finish(cbb.get(), &der, &der_len)) {
+    return false;
+  }
+  out->assign(der, der + der_len);
+  OPENSSL_free(der);
+  return true;
 }
 
-bool Testd2i_ECPrivateKey() {
+static bool Testd2i_ECPrivateKey() {
   ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithoutPublic,
                                         sizeof(kECKeyWithoutPublic));
   if (!key) {
@@ -172,7 +211,39 @@
   return true;
 }
 
-bool TestSetAffine(const int nid) {
+static bool TestSpecifiedCurve() {
+  // Test keys with specified curves may be decoded.
+  ScopedEC_KEY key =
+      DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
+  if (!key) {
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  // The group should have been interpreted as P-256.
+  if (EC_GROUP_get_curve_name(EC_KEY_get0_group(key.get())) !=
+      NID_X9_62_prime256v1) {
+    fprintf(stderr, "Curve name incorrect.\n");
+    return false;
+  }
+
+  // Encoding the key should still use named form.
+  std::vector<uint8_t> out;
+  if (!EncodeECPrivateKey(&out, key.get())) {
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+  if (std::vector<uint8_t>(kECKeyWithoutPublic,
+                           kECKeyWithoutPublic + sizeof(kECKeyWithoutPublic)) !=
+      out) {
+    fprintf(stderr, "Serialisation of key was incorrect.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestSetAffine(const int nid) {
   ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
   if (!key) {
     return false;
@@ -240,16 +311,206 @@
   return true;
 }
 
+static bool TestArbitraryCurve() {
+  // Make a P-256 key and extract the affine coordinates.
+  ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  if (!key || !EC_KEY_generate_key(key.get())) {
+    return false;
+  }
+
+  // Make an arbitrary curve which is identical to P-256.
+  static const uint8_t kP[] = {
+      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  };
+  static const uint8_t kA[] = {
+      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+  };
+  static const uint8_t kB[] = {
+      0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
+      0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+      0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
+  };
+  static const uint8_t kX[] = {
+      0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
+      0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
+      0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
+  };
+  static const uint8_t kY[] = {
+      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
+      0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
+      0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+  };
+  static const uint8_t kOrder[] = {
+      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
+      0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
+  };
+  ScopedBN_CTX ctx(BN_CTX_new());
+  ScopedBIGNUM p(BN_bin2bn(kP, sizeof(kP), nullptr));
+  ScopedBIGNUM a(BN_bin2bn(kA, sizeof(kA), nullptr));
+  ScopedBIGNUM b(BN_bin2bn(kB, sizeof(kB), nullptr));
+  ScopedBIGNUM gx(BN_bin2bn(kX, sizeof(kX), nullptr));
+  ScopedBIGNUM gy(BN_bin2bn(kY, sizeof(kY), nullptr));
+  ScopedBIGNUM order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+  ScopedBIGNUM cofactor(BN_new());
+  if (!ctx || !p || !a || !b || !gx || !gy || !order || !cofactor ||
+      !BN_set_word(cofactor.get(), 1)) {
+    return false;
+  }
+
+  ScopedEC_GROUP group(
+      EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+  if (!group) {
+    return false;
+  }
+  ScopedEC_POINT generator(EC_POINT_new(group.get()));
+  if (!generator ||
+      !EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
+                                           gx.get(), gy.get(), ctx.get()) ||
+      !EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
+                              cofactor.get())) {
+    return false;
+  }
+
+  // |group| should not have a curve name.
+  if (EC_GROUP_get_curve_name(group.get()) != NID_undef) {
+    return false;
+  }
+
+  // Copy |key| to |key2| using |group|.
+  ScopedEC_KEY key2(EC_KEY_new());
+  ScopedEC_POINT point(EC_POINT_new(group.get()));
+  ScopedBIGNUM x(BN_new()), y(BN_new());
+  if (!key2 || !point || !x || !y ||
+      !EC_KEY_set_group(key2.get(), group.get()) ||
+      !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
+      !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
+                                           EC_KEY_get0_public_key(key.get()),
+                                           x.get(), y.get(), nullptr) ||
+      !EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
+                                           y.get(), nullptr) ||
+      !EC_KEY_set_public_key(key2.get(), point.get())) {
+    fprintf(stderr, "Could not copy key.\n");
+    return false;
+  }
+
+  // The key must be valid according to the new group too.
+  if (!EC_KEY_check_key(key2.get())) {
+    fprintf(stderr, "Copied key is not valid.\n");
+    return false;
+  }
+
+  // Repeat the process for |EC_GROUP_new_arbitrary|.
+  group.reset(EC_GROUP_new_arbitrary(p.get(), a.get(), b.get(), gx.get(),
+                                     gy.get(), order.get(), cofactor.get()));
+  if (!group) {
+    return false;
+  }
+
+  // |group| should not have a curve name.
+  if (EC_GROUP_get_curve_name(group.get()) != NID_undef) {
+    return false;
+  }
+
+  // Copy |key| to |key2| using |group|.
+  key2.reset(EC_KEY_new());
+  point.reset(EC_POINT_new(group.get()));
+  if (!key2 || !point ||
+      !EC_KEY_set_group(key2.get(), group.get()) ||
+      !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
+      !EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
+                                           y.get(), nullptr) ||
+      !EC_KEY_set_public_key(key2.get(), point.get())) {
+    fprintf(stderr, "Could not copy key.\n");
+    return false;
+  }
+
+  // The key must be valid according to the new group too.
+  if (!EC_KEY_check_key(key2.get())) {
+    fprintf(stderr, "Copied key is not valid.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestAddingEqualPoints(int nid) {
+  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+  if (!key) {
+    return false;
+  }
+
+  const EC_GROUP *const group = EC_KEY_get0_group(key.get());
+
+  if (!EC_KEY_generate_key(key.get())) {
+    fprintf(stderr, "EC_KEY_generate_key failed with nid %d\n", nid);
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  ScopedEC_POINT p1(EC_POINT_new(group));
+  ScopedEC_POINT p2(EC_POINT_new(group));
+  ScopedEC_POINT double_p1(EC_POINT_new(group));
+  ScopedEC_POINT p1_plus_p2(EC_POINT_new(group));
+  if (!p1 || !p2 || !double_p1 || !p1_plus_p2) {
+    return false;
+  }
+
+  if (!EC_POINT_copy(p1.get(), EC_KEY_get0_public_key(key.get())) ||
+      !EC_POINT_copy(p2.get(), EC_KEY_get0_public_key(key.get()))) {
+    fprintf(stderr, "EC_POINT_COPY failed with nid %d\n", nid);
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  ScopedBN_CTX ctx(BN_CTX_new());
+  if (!ctx) {
+    return false;
+  }
+
+  if (!EC_POINT_dbl(group, double_p1.get(), p1.get(), ctx.get()) ||
+      !EC_POINT_add(group, p1_plus_p2.get(), p1.get(), p2.get(), ctx.get())) {
+    fprintf(stderr, "Point operation failed with nid %d\n", nid);
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  if (EC_POINT_cmp(group, double_p1.get(), p1_plus_p2.get(), ctx.get()) != 0) {
+    fprintf(stderr, "A+A != 2A for nid %d", nid);
+    return false;
+  }
+
+  return true;
+}
+
+static bool ForEachCurve(bool (*test_func)(int nid)) {
+  const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
+  std::vector<EC_builtin_curve> curves(num_curves);
+  EC_get_builtin_curves(curves.data(), num_curves);
+
+  for (const auto& curve : curves) {
+    if (!test_func(curve.nid)) {
+      fprintf(stderr, "Test failed for %s\n", curve.comment);
+      return false;
+    }
+  }
+
+  return true;
+}
+
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!Testd2i_ECPrivateKey() ||
       !TestZeroPadding() ||
-      !TestSetAffine(NID_secp224r1) ||
-      !TestSetAffine(NID_X9_62_prime256v1) ||
-      !TestSetAffine(NID_secp384r1) ||
-      !TestSetAffine(NID_secp521r1)) {
+      !TestSpecifiedCurve() ||
+      !ForEachCurve(TestSetAffine) ||
+      !ForEachCurve(TestAddingEqualPoints) ||
+      !TestArbitraryCurve()) {
     fprintf(stderr, "failed\n");
     return 1;
   }
diff --git a/src/crypto/ec/example_mul.c b/src/crypto/ec/example_mul.c
index ebb724f..a2bdd52 100644
--- a/src/crypto/ec/example_mul.c
+++ b/src/crypto/ec/example_mul.c
@@ -70,10 +70,10 @@
 #include <openssl/bn.h>
 #include <openssl/crypto.h>
 #include <openssl/ec.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 
-int example_EC_POINT_mul(void) {
+static int example_EC_POINT_mul(void) {
   /* This example ensures that 10×∞ + G = G, in P-256. */
   EC_GROUP *group = NULL;
   EC_POINT *p = NULL, *result = NULL;
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index bcc0e37..f2cbb96 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -80,18 +80,11 @@
 
 
 struct ec_method_st {
-  /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
   int (*group_init)(EC_GROUP *);
   void (*group_finish)(EC_GROUP *);
-  void (*group_clear_finish)(EC_GROUP *);
   int (*group_copy)(EC_GROUP *, const EC_GROUP *);
-
-  /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
-  /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
   int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
                          const BIGNUM *b, BN_CTX *);
-
-  /* used by EC_POINT_get_affine_coordinates_GFp: */
   int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
                                       BIGNUM *x, BIGNUM *y, BN_CTX *);
 
@@ -112,8 +105,6 @@
   int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key,
                              BN_CTX *ctx);
 
-  /* internal functions */
-
   /* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that the
    * same implementations of point operations can be used with different
    * optimized implementations of expensive field operations: */
@@ -125,7 +116,6 @@
                       BN_CTX *); /* e.g. to Montgomery */
   int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                       BN_CTX *); /* e.g. from Montgomery */
-  int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
 } /* EC_METHOD */;
 
 const EC_METHOD* EC_GFp_mont_method(void);
@@ -133,7 +123,7 @@
 struct ec_group_st {
   const EC_METHOD *meth;
 
-  EC_POINT *generator; /* optional */
+  EC_POINT *generator;
   BIGNUM order, cofactor;
 
   int curve_name; /* optional NID for named curve */
@@ -150,20 +140,17 @@
   int a_is_minus3; /* enable optimized point arithmetics for special case */
 
   BN_MONT_CTX *mont; /* Montgomery structure. */
-  BIGNUM *one; /* The value one */
+
+  BIGNUM one; /* The value one. */
 } /* EC_GROUP */;
 
 struct ec_point_st {
   const EC_METHOD *meth;
 
-  /* All members except 'meth' are handled by the method functions,
-   * even if they appear generic */
-
   BIGNUM X;
   BIGNUM Y;
   BIGNUM Z; /* Jacobian projective coordinates:
              * (X, Y, Z)  represents  (X/Z^2, Y/Z^3)  if  Z != 0 */
-  int Z_is_one; /* enable optimized point arithmetics for special case */
 } /* EC_POINT */;
 
 EC_GROUP *ec_group_new(const EC_METHOD *meth);
@@ -180,14 +167,12 @@
 /* method functions in simple.c */
 int ec_GFp_simple_group_init(EC_GROUP *);
 void ec_GFp_simple_group_finish(EC_GROUP *);
-void ec_GFp_simple_group_clear_finish(EC_GROUP *);
 int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
 int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
                                   const BIGNUM *b, BN_CTX *);
 int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
                                   BIGNUM *b, BN_CTX *);
 unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *);
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
 int ec_GFp_simple_point_init(EC_POINT *);
 void ec_GFp_simple_point_finish(EC_POINT *);
 void ec_GFp_simple_point_clear_finish(EC_POINT *);
@@ -204,9 +189,6 @@
 int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
                                                const BIGNUM *x, const BIGNUM *y,
                                                BN_CTX *);
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
-                                               const EC_POINT *, BIGNUM *x,
-                                               BIGNUM *y, BN_CTX *);
 int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
                                              const BIGNUM *x, int y_bit,
                                              BN_CTX *);
@@ -232,7 +214,6 @@
 int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
                                 const BIGNUM *b, BN_CTX *);
 void ec_GFp_mont_group_finish(EC_GROUP *);
-void ec_GFp_mont_group_clear_finish(EC_GROUP *);
 int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
 int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                           const BIGNUM *b, BN_CTX *);
@@ -242,22 +223,12 @@
                              BN_CTX *);
 int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                              BN_CTX *);
-int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
 
 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                              EC_POINT *point, const BIGNUM *x,
                                              const BIGNUM *y, const BIGNUM *z,
                                              BN_CTX *ctx);
 
-void ec_GFp_nistp_points_make_affine_internal(
-    size_t num, void *point_array, size_t felem_size, void *tmp_felems,
-    void (*felem_one)(void *out), int (*felem_is_zero)(const void *in),
-    void (*felem_assign)(void *out, const void *in),
-    void (*felem_square)(void *out, const void *in),
-    void (*felem_mul)(void *out, const void *in1, const void *in2),
-    void (*felem_inv)(void *out, const void *in),
-    void (*felem_contract)(void *out, const void *in));
-
 void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
 
 const EC_METHOD *EC_GFp_nistp224_method(void);
@@ -268,8 +239,6 @@
 const EC_METHOD *EC_GFp_nistz256_method(void);
 
 struct ec_key_st {
-  int version;
-
   EC_GROUP *group;
 
   EC_POINT *pub_key;
@@ -279,7 +248,6 @@
   point_conversion_form_t conv_form;
 
   CRYPTO_refcount_t references;
-  int flags;
 
   ECDSA_METHOD *ecdsa_meth;
 
@@ -303,6 +271,8 @@
 
 struct built_in_curve {
   int nid;
+  uint8_t oid[8];
+  uint8_t oid_len;
   const struct curve_data *data;
   const EC_METHOD *(*method)(void);
 };
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index e39337d..bf1957c 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -68,6 +68,7 @@
 #include <openssl/ec.h>
 
 #include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/err.h>
 
 #include "internal.h"
@@ -268,11 +269,27 @@
   return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
 }
 
+int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point,
+                       point_conversion_form_t form, BN_CTX *ctx) {
+  size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+  if (len == 0) {
+    return 0;
+  }
+  uint8_t *p;
+  return CBB_add_space(out, &p, len) &&
+         EC_POINT_point2oct(group, point, form, p, len, ctx) == len;
+}
+
 int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
-                                             EC_POINT *point, const BIGNUM *x_,
+                                             EC_POINT *point, const BIGNUM *x,
                                              int y_bit, BN_CTX *ctx) {
+  if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) {
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
+    return 0;
+  }
+
   BN_CTX *new_ctx = NULL;
-  BIGNUM *tmp1, *tmp2, *x, *y;
+  BIGNUM *tmp1, *tmp2, *y;
   int ret = 0;
 
   ERR_clear_error();
@@ -289,7 +306,6 @@
   BN_CTX_start(ctx);
   tmp1 = BN_CTX_get(ctx);
   tmp2 = BN_CTX_get(ctx);
-  x = BN_CTX_get(ctx);
   y = BN_CTX_get(ctx);
   if (y == NULL) {
     goto err;
@@ -300,19 +316,15 @@
    * so  y  is one of the square roots of  x^3 + a*x + b. */
 
   /* tmp1 := x^3 */
-  if (!BN_nnmod(x, x_, &group->field, ctx)) {
-    goto err;
-  }
-
   if (group->meth->field_decode == 0) {
     /* field_{sqr,mul} work on standard representation */
-    if (!group->meth->field_sqr(group, tmp2, x_, ctx) ||
-        !group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) {
+    if (!group->meth->field_sqr(group, tmp2, x, ctx) ||
+        !group->meth->field_mul(group, tmp1, tmp2, x, ctx)) {
       goto err;
     }
   } else {
-    if (!BN_mod_sqr(tmp2, x_, &group->field, ctx) ||
-        !BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) {
+    if (!BN_mod_sqr(tmp2, x, &group->field, ctx) ||
+        !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) {
       goto err;
     }
   }
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
index e026fc4..7bf889c 100644
--- a/src/crypto/ec/p224-64.c
+++ b/src/crypto/ec/p224-64.c
@@ -26,11 +26,11 @@
 #include <openssl/ec.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 
 #include <string.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 typedef uint8_t u8;
@@ -50,7 +50,7 @@
  * to the unique minimal representation at the end of the computation. */
 
 typedef uint64_t limb;
-typedef __uint128_t widelimb;
+typedef uint128_t widelimb;
 
 typedef limb felem[4];
 typedef widelimb widefelem[7];
@@ -60,23 +60,6 @@
  * scalars for point multiplication. */
 typedef u8 felem_bytearray[28];
 
-static const felem_bytearray nistp224_curve_params[5] = {
-    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
-     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
-     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
-    {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
-     0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B,
-     0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
-    {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
-     0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32,
-     0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
-    {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
-     0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5,
-     0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}};
-
 /* Precomputed multiples of the standard generator
  * Points are given in coordinates (X, Y, Z) where Z normally is 1
  * (0 for the point at infinity).
@@ -209,7 +192,7 @@
 }
 
 static void felem_to_bin28(u8 out[28], const felem in) {
-  unsigned i;
+  size_t i;
   for (i = 0; i < 7; ++i) {
     out[i] = in[0] >> (8 * i);
     out[i + 7] = in[1] >> (8 * i);
@@ -219,8 +202,8 @@
 }
 
 /* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len) {
-  unsigned i;
+static void flip_endian(u8 *out, const u8 *in, size_t len) {
+  size_t i;
   for (i = 0; i < len; ++i) {
     out[i] = in[len - 1 - i];
   }
@@ -231,7 +214,7 @@
   /* BN_bn2bin eats leading zeroes */
   felem_bytearray b_out;
   memset(b_out, 0, sizeof(b_out));
-  unsigned num_bytes = BN_num_bytes(bn);
+  size_t num_bytes = BN_num_bytes(bn);
   if (num_bytes > sizeof(b_out) ||
       BN_is_negative(bn)) {
     OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
@@ -258,13 +241,6 @@
  * expected to be correct in general - e.g., multiplication with a large scalar
  * will cause an overflow. */
 
-static void felem_one(felem out) {
-  out[0] = 1;
-  out[1] = 0;
-  out[2] = 0;
-  out[3] = 0;
-}
-
 static void felem_assign(felem out, const felem in) {
   out[0] = in[0];
   out[1] = in[1];
@@ -476,18 +452,6 @@
   out[3] = output[3];
 }
 
-static void felem_square_reduce(felem out, const felem in) {
-  widefelem tmp;
-  felem_square(tmp, in);
-  felem_reduce(out, tmp);
-}
-
-static void felem_mul_reduce(felem out, const felem in1, const felem in2) {
-  widefelem tmp;
-  felem_mul(tmp, in1, in2);
-  felem_reduce(out, tmp);
-}
-
 /* Reduce to unique minimal representation.
  * Requires 0 <= in < 2*p (always call felem_reduce first) */
 static void felem_contract(felem out, const felem in) {
@@ -555,16 +519,12 @@
   return (zero | two224m96p1 | two225m97p2);
 }
 
-static limb felem_is_zero_int(const felem in) {
-  return (int)(felem_is_zero(in) & ((limb)1));
-}
-
 /* Invert a field element */
 /* Computation chain copied from djb's code */
 static void felem_inv(felem out, const felem in) {
   felem ftmp, ftmp2, ftmp3, ftmp4;
   widefelem tmp;
-  unsigned i;
+  size_t i;
 
   felem_square(tmp, in);
   felem_reduce(ftmp, tmp); /* 2 */
@@ -644,7 +604,7 @@
  * if icopy == 1, copy in to out,
  * if icopy == 0, copy out to itself. */
 static void copy_conditional(felem out, const felem in, limb icopy) {
-  unsigned i;
+  size_t i;
   /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
   const limb copy = -icopy;
   for (i = 0; i < 4; ++i) {
@@ -901,12 +861,12 @@
 
 /* select_point selects the |idx|th point from a precomputation table and
  * copies it to out. */
-static void select_point(const u64 idx, unsigned int size,
+static void select_point(const u64 idx, size_t size,
                          const felem pre_comp[/*size*/][3], felem out[3]) {
-  unsigned i, j;
   limb *outlimbs = &out[0][0];
   memset(outlimbs, 0, 3 * sizeof(felem));
 
+  size_t i;
   for (i = 0; i < size; i++) {
     const limb *inlimbs = &pre_comp[i][0][0];
     u64 mask = i ^ idx;
@@ -915,6 +875,7 @@
     mask |= mask >> 1;
     mask &= 1;
     mask--;
+    size_t j;
     for (j = 0; j < 4 * 3; j++) {
       outlimbs[j] |= inlimbs[j] & mask;
     }
@@ -922,7 +883,7 @@
 }
 
 /* get_bit returns the |i|th bit in |in| */
-static char get_bit(const felem_bytearray in, unsigned i) {
+static char get_bit(const felem_bytearray in, size_t i) {
   if (i >= 224) {
     return 0;
   }
@@ -936,11 +897,8 @@
  * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
 static void batch_mul(felem x_out, felem y_out, felem z_out,
                       const felem_bytearray scalars[],
-                      const unsigned num_points, const u8 *g_scalar,
-                      const int mixed, const felem pre_comp[][17][3]) {
-  int i, skip;
-  unsigned num;
-  unsigned gen_mul = (g_scalar != NULL);
+                      const size_t num_points, const u8 *g_scalar,
+                      const felem pre_comp[][17][3]) {
   felem nq[3], tmp[4];
   u64 bits;
   u8 sign, digit;
@@ -951,15 +909,16 @@
   /* Loop over all scalars msb-to-lsb, interleaving additions
    * of multiples of the generator (two in each of the last 28 rounds)
    * and additions of other points multiples (every 5th round). */
-  skip = 1; /* save two point operations in the first round */
-  for (i = (num_points ? 220 : 27); i >= 0; --i) {
+  int skip = 1; /* save two point operations in the first round */
+  size_t i = num_points != 0 ? 220 : 27;
+  for (;;) {
     /* double */
     if (!skip) {
       point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
     }
 
     /* add multiples of the generator */
-    if (gen_mul && (i <= 27)) {
+    if (g_scalar != NULL && i <= 27) {
       /* first, look 28 bits upwards */
       bits = get_bit(g_scalar, i + 196) << 3;
       bits |= get_bit(g_scalar, i + 140) << 2;
@@ -988,8 +947,9 @@
     }
 
     /* do other additions every 5 doublings */
-    if (num_points && (i % 5 == 0)) {
+    if (num_points != 0 && i % 5 == 0) {
       /* loop over all scalars */
+      size_t num;
       for (num = 0; num < num_points; ++num) {
         bits = get_bit(scalars[num], i + 4) << 5;
         bits |= get_bit(scalars[num], i + 3) << 4;
@@ -1005,70 +965,31 @@
         copy_conditional(tmp[1], tmp[3], sign);
 
         if (!skip) {
-          point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], mixed, tmp[0],
-                    tmp[1], tmp[2]);
+          point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+                    tmp[0], tmp[1], tmp[2]);
         } else {
           memcpy(nq, tmp, 3 * sizeof(felem));
           skip = 0;
         }
       }
     }
+
+    if (i == 0) {
+      break;
+    }
+    --i;
   }
   felem_assign(x_out, nq[0]);
   felem_assign(y_out, nq[1]);
   felem_assign(z_out, nq[2]);
 }
 
-int ec_GFp_nistp224_group_init(EC_GROUP *group) {
-  int ret;
-  ret = ec_GFp_simple_group_init(group);
-  group->a_is_minus3 = 1;
-  return ret;
-}
-
-int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-                                    const BIGNUM *a, const BIGNUM *b,
-                                    BN_CTX *ctx) {
-  int ret = 0;
-  BN_CTX *new_ctx = NULL;
-  BIGNUM *curve_p, *curve_a, *curve_b;
-
-  if (ctx == NULL) {
-    ctx = BN_CTX_new();
-    new_ctx = ctx;
-    if (ctx == NULL) {
-      return 0;
-    }
-  }
-  BN_CTX_start(ctx);
-  if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
-      ((curve_a = BN_CTX_get(ctx)) == NULL) ||
-      ((curve_b = BN_CTX_get(ctx)) == NULL)) {
-    goto err;
-  }
-  BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
-  BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
-  BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
-  if (BN_cmp(curve_p, p) ||
-      BN_cmp(curve_a, a) ||
-      BN_cmp(curve_b, b)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
-    goto err;
-  }
-  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-
-err:
-  BN_CTX_end(ctx);
-  BN_CTX_free(new_ctx);
-  return ret;
-}
-
 /* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
  * (X', Y') = (X/Z^2, Y/Z^3) */
-int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
-                                                 const EC_POINT *point,
-                                                 BIGNUM *x, BIGNUM *y,
-                                                 BN_CTX *ctx) {
+static int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+                                                        const EC_POINT *point,
+                                                        BIGNUM *x, BIGNUM *y,
+                                                        BN_CTX *ctx) {
   felem z1, z2, x_in, y_in, x_out, y_out;
   widefelem tmp;
 
@@ -1107,23 +1028,12 @@
   return 1;
 }
 
-static void make_points_affine(size_t num, felem points[/*num*/][3],
-                               felem tmp_felems[/*num+1*/]) {
-  /* Runs in constant time, unless an input is the point at infinity
-   * (which normally shouldn't happen). */
-  ec_GFp_nistp_points_make_affine_internal(
-      num, points, sizeof(felem), tmp_felems, (void (*)(void *))felem_one,
-      (int (*)(const void *))felem_is_zero_int,
-      (void (*)(void *, const void *))felem_assign,
-      (void (*)(void *, const void *))felem_square_reduce,
-      (void (*)(void *, const void *, const void *))felem_mul_reduce,
-      (void (*)(void *, const void *))felem_inv,
-      (void (*)(void *, const void *))felem_contract);
-}
-
-int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
-                               const BIGNUM *g_scalar, const EC_POINT *p_,
-                               const BIGNUM *p_scalar_, BN_CTX *ctx) {
+static int ec_GFp_nistp224_points_mul(const EC_GROUP *group,
+                                      EC_POINT *r,
+                                      const BIGNUM *g_scalar,
+                                      const EC_POINT *p_,
+                                      const BIGNUM *p_scalar_,
+                                      BN_CTX *ctx) {
   /* TODO: This function used to take |points| and |scalars| as arrays of
    * |num| elements. The code below should be simplified to work in terms of
    * |p_| and |p_scalar_|. */
@@ -1132,17 +1042,12 @@
   BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
 
   int ret = 0;
-  int j;
-  unsigned i;
-  int mixed = 0;
   BN_CTX *new_ctx = NULL;
   BIGNUM *x, *y, *z, *tmp_scalar;
   felem_bytearray g_secret;
   felem_bytearray *secrets = NULL;
   felem(*pre_comp)[17][3] = NULL;
-  felem *tmp_felems = NULL;
   felem_bytearray tmp;
-  unsigned num_bytes;
   size_t num_points = num;
   felem x_in, y_in, z_in, x_out, y_out, z_out;
   const EC_POINT *p = NULL;
@@ -1165,19 +1070,10 @@
   }
 
   if (num_points > 0) {
-    if (num_points >= 3) {
-      /* unless we precompute multiples for just one or two points,
-       * converting those into affine form is time well spent  */
-      mixed = 1;
-    }
     secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
     pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3]));
-    if (mixed) {
-      tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
-    }
     if (secrets == NULL ||
-        pre_comp == NULL ||
-        (mixed && tmp_felems == NULL)) {
+        pre_comp == NULL) {
       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       goto err;
     }
@@ -1186,6 +1082,7 @@
      * i.e., they contribute nothing to the linear combination */
     memset(secrets, 0, num_points * sizeof(felem_bytearray));
     memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+    size_t i;
     for (i = 0; i < num_points; ++i) {
       if (i == num) {
         /* the generator */
@@ -1198,6 +1095,7 @@
       }
 
       if (p_scalar != NULL && p != NULL) {
+        size_t num_bytes;
         /* reduce g_scalar to 0 <= g_scalar < 2^224 */
         if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) {
           /* this is an unusual input, and we don't guarantee
@@ -1223,6 +1121,7 @@
         felem_assign(pre_comp[i][1][1], y_out);
         felem_assign(pre_comp[i][1][2], z_out);
 
+        size_t j;
         for (j = 2; j <= 16; ++j) {
           if (j & 1) {
             point_add(pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
@@ -1237,14 +1136,11 @@
         }
       }
     }
-
-    if (mixed) {
-      make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
-    }
   }
 
   if (g_scalar != NULL) {
     memset(g_secret, 0, sizeof(g_secret));
+    size_t num_bytes;
     /* reduce g_scalar to 0 <= g_scalar < 2^224 */
     if (BN_num_bits(g_scalar) > 224 || BN_is_negative(g_scalar)) {
       /* this is an unusual input, and we don't guarantee constant-timeness */
@@ -1260,7 +1156,7 @@
     flip_endian(g_secret, tmp, num_bytes);
   }
   batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
-            num_points, g_scalar != NULL ? g_secret : NULL, mixed,
+            num_points, g_scalar != NULL ? g_secret : NULL,
             (const felem(*)[17][3])pre_comp);
 
   /* reduce the output to its unique minimal representation */
@@ -1280,24 +1176,21 @@
   BN_CTX_free(new_ctx);
   OPENSSL_free(secrets);
   OPENSSL_free(pre_comp);
-  OPENSSL_free(tmp_felems);
   return ret;
 }
 
 const EC_METHOD *EC_GFp_nistp224_method(void) {
-  static const EC_METHOD ret = {ec_GFp_nistp224_group_init,
+  static const EC_METHOD ret = {ec_GFp_simple_group_init,
                                 ec_GFp_simple_group_finish,
-                                ec_GFp_simple_group_clear_finish,
                                 ec_GFp_simple_group_copy,
-                                ec_GFp_nistp224_group_set_curve,
+                                ec_GFp_simple_group_set_curve,
                                 ec_GFp_nistp224_point_get_affine_coordinates,
                                 ec_GFp_nistp224_points_mul,
                                 0 /* check_pub_key_order */,
                                 ec_GFp_simple_field_mul,
                                 ec_GFp_simple_field_sqr,
                                 0 /* field_encode */,
-                                0 /* field_decode */,
-                                0 /* field_set_to_one */};
+                                0 /* field_decode */};
 
   return &ret;
 }
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 32852dd..c4259b6 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -27,44 +27,22 @@
 #include <openssl/ec.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 
 #include <string.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 typedef uint8_t u8;
 typedef uint64_t u64;
 typedef int64_t s64;
-typedef __uint128_t uint128_t;
-typedef __int128_t int128_t;
 
 /* The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
  * can serialise an element of this field into 32 bytes. We call this an
  * felem_bytearray. */
 typedef u8 felem_bytearray[32];
 
-/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
- * values are big-endian. */
-static const felem_bytearray nistp256_curve_params[5] = {
-    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
-    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-     0xfc}, /* b */
-    {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55,
-     0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
-     0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
-    {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
-     0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
-     0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
-    {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
-     0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
-     0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}};
-
 /* The representation of field elements.
  * ------------------------------------
  *
@@ -99,10 +77,10 @@
 /* bin32_to_felem takes a little-endian byte array and converts it into felem
  * form. This assumes that the CPU is little-endian. */
 static void bin32_to_felem(felem out, const u8 in[32]) {
-  out[0] = *((u64 *)&in[0]);
-  out[1] = *((u64 *)&in[8]);
-  out[2] = *((u64 *)&in[16]);
-  out[3] = *((u64 *)&in[24]);
+  out[0] = *((const u64 *)&in[0]);
+  out[1] = *((const u64 *)&in[8]);
+  out[2] = *((const u64 *)&in[16]);
+  out[3] = *((const u64 *)&in[24]);
 }
 
 /* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
@@ -115,8 +93,8 @@
 }
 
 /* To preserve endianness when using BN_bn2bin and BN_bin2bn. */
-static void flip_endian(u8 *out, const u8 *in, unsigned len) {
-  unsigned i;
+static void flip_endian(u8 *out, const u8 *in, size_t len) {
+  size_t i;
   for (i = 0; i < len; ++i) {
     out[i] = in[len - 1 - i];
   }
@@ -132,7 +110,7 @@
   felem_bytearray b_out;
   /* BN_bn2bin eats leading zeroes */
   memset(b_out, 0, sizeof(b_out));
-  unsigned num_bytes = BN_num_bytes(bn);
+  size_t num_bytes = BN_num_bytes(bn);
   if (num_bytes > sizeof(b_out)) {
     OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
     return 0;
@@ -155,20 +133,6 @@
 
 /* Field operations. */
 
-static void smallfelem_one(smallfelem out) {
-  out[0] = 1;
-  out[1] = 0;
-  out[2] = 0;
-  out[3] = 0;
-}
-
-static void smallfelem_assign(smallfelem out, const smallfelem in) {
-  out[0] = in[0];
-  out[1] = in[1];
-  out[2] = in[2];
-  out[3] = in[3];
-}
-
 static void felem_assign(felem out, const felem in) {
   out[0] = in[0];
   out[1] = in[1];
@@ -364,8 +328,7 @@
    * conditionally subtract kPrime if tmp[3] is large enough. */
   high = tmp[3] >> 64;
   /* As tmp[3] < 2^65, high is either 1 or 0 */
-  high <<= 63;
-  high >>= 63;
+  high = ~(high - 1);
   /* high is:
    *   all ones   if the high word of tmp[3] is 1
    *   all zeros  if the high word of tmp[3] if 0 */
@@ -756,7 +719,7 @@
    * each u64, from most-significant to least significant. For each one, if
    * all words so far have been equal (m is all ones) then a non-equal
    * result is the answer. Otherwise we continue. */
-  unsigned i;
+  size_t i;
   for (i = 3; i < 4; i--) {
     u64 equal;
     uint128_t a = ((uint128_t)kPrime[i]) - out[i];
@@ -800,25 +763,6 @@
   subtract_u64(&out[3], &carry, result & kPrime[3]);
 }
 
-static void smallfelem_square_contract(smallfelem out, const smallfelem in) {
-  longfelem longtmp;
-  felem tmp;
-
-  smallfelem_square(longtmp, in);
-  felem_reduce(tmp, longtmp);
-  felem_contract(out, tmp);
-}
-
-static void smallfelem_mul_contract(smallfelem out, const smallfelem in1,
-                                    const smallfelem in2) {
-  longfelem longtmp;
-  felem tmp;
-
-  smallfelem_mul(longtmp, in1, in2);
-  felem_reduce(tmp, longtmp);
-  felem_contract(out, tmp);
-}
-
 /* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
  * otherwise.
  * On entry:
@@ -855,10 +799,6 @@
   return result;
 }
 
-static int smallfelem_is_zero_int(const smallfelem small) {
-  return (int)(smallfelem_is_zero(small) & ((limb)1));
-}
-
 /* felem_inv calculates |out| = |in|^{-1}
  *
  * Based on Fermat's Little Theorem:
@@ -870,7 +810,7 @@
   /* each e_I will hold |in|^{2^I - 1} */
   felem e2, e4, e8, e16, e32, e64;
   longfelem tmp;
-  unsigned i;
+  size_t i;
 
   felem_square(tmp, in);
   felem_reduce(ftmp, tmp); /* 2^1 */
@@ -958,14 +898,6 @@
   felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
 }
 
-static void smallfelem_inv_contract(smallfelem out, const smallfelem in) {
-  felem tmp;
-
-  smallfelem_expand(tmp, in);
-  felem_inv(tmp, tmp);
-  felem_contract(out, tmp);
-}
-
 /* Group operations
  * ----------------
  *
@@ -1076,7 +1008,7 @@
 
 /* copy_conditional copies in to out iff mask is all ones. */
 static void copy_conditional(felem out, const felem in, limb mask) {
-  unsigned i;
+  size_t i;
   for (i = 0; i < NLIMBS; ++i) {
     const limb tmp = mask & (in[i] ^ out[i]);
     out[i] ^= tmp;
@@ -1085,7 +1017,7 @@
 
 /* copy_small_conditional copies in to out iff mask is all ones. */
 static void copy_small_conditional(felem out, const smallfelem in, limb mask) {
-  unsigned i;
+  size_t i;
   const u64 mask64 = mask;
   for (i = 0; i < NLIMBS; ++i) {
     out[i] = ((limb)(in[i] & mask64)) | (out[i] & ~mask);
@@ -1469,20 +1401,22 @@
 
 /* select_point selects the |idx|th point from a precomputation table and
  * copies it to out. */
-static void select_point(const u64 idx, unsigned int size,
-                         const smallfelem pre_comp[16][3], smallfelem out[3]) {
-  unsigned i, j;
+static void select_point(const u64 idx, size_t size,
+                         const smallfelem pre_comp[/*size*/][3],
+                         smallfelem out[3]) {
   u64 *outlimbs = &out[0][0];
   memset(outlimbs, 0, 3 * sizeof(smallfelem));
 
+  size_t i;
   for (i = 0; i < size; i++) {
-    const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
+    const u64 *inlimbs = (const u64 *)&pre_comp[i][0][0];
     u64 mask = i ^ idx;
     mask |= mask >> 4;
     mask |= mask >> 2;
     mask |= mask >> 1;
     mask &= 1;
     mask--;
+    size_t j;
     for (j = 0; j < NLIMBS * 3; j++) {
       outlimbs[j] |= inlimbs[j] & mask;
     }
@@ -1504,10 +1438,8 @@
  * Output point (X, Y, Z) is stored in x_out, y_out, z_out. */
 static void batch_mul(felem x_out, felem y_out, felem z_out,
                       const felem_bytearray scalars[],
-                      const unsigned num_points, const u8 *g_scalar,
-                      const int mixed, const smallfelem pre_comp[][17][3]) {
-  int i, skip;
-  unsigned num, gen_mul = (g_scalar != NULL);
+                      const size_t num_points, const u8 *g_scalar,
+                      const smallfelem pre_comp[][17][3]) {
   felem nq[3], ftmp;
   smallfelem tmp[3];
   u64 bits;
@@ -1520,16 +1452,16 @@
    * of the generator (two in each of the last 32 rounds) and additions of
    * other points multiples (every 5th round). */
 
-  skip = 1; /* save two point operations in the first
-             * round */
-  for (i = (num_points ? 255 : 31); i >= 0; --i) {
+  int skip = 1; /* save two point operations in the first round */
+  size_t i = num_points != 0 ? 255 : 31;
+  for (;;) {
     /* double */
     if (!skip) {
       point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
     }
 
     /* add multiples of the generator */
-    if (gen_mul && i <= 31) {
+    if (g_scalar != NULL && i <= 31) {
       /* first, look 32 bits upwards */
       bits = get_bit(g_scalar, i + 224) << 3;
       bits |= get_bit(g_scalar, i + 160) << 2;
@@ -1539,9 +1471,8 @@
       select_point(bits, 16, g_pre_comp[1], tmp);
 
       if (!skip) {
-        /* Arg 1 below is for "mixed" */
-        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1, tmp[0], tmp[1],
-                  tmp[2]);
+        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+                  tmp[0], tmp[1], tmp[2]);
       } else {
         smallfelem_expand(nq[0], tmp[0]);
         smallfelem_expand(nq[1], tmp[1]);
@@ -1556,14 +1487,14 @@
       bits |= get_bit(g_scalar, i);
       /* select the point to add, in constant time */
       select_point(bits, 16, g_pre_comp[0], tmp);
-      /* Arg 1 below is for "mixed" */
-      point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1, tmp[0], tmp[1],
-                tmp[2]);
+      point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0],
+                tmp[1], tmp[2]);
     }
 
     /* do other additions every 5 doublings */
-    if (num_points && (i % 5 == 0)) {
+    if (num_points != 0 && i % 5 == 0) {
       /* loop over all scalars */
+      size_t num;
       for (num = 0; num < num_points; ++num) {
         bits = get_bit(scalars[num], i + 4) << 5;
         bits |= get_bit(scalars[num], i + 3) << 4;
@@ -1581,8 +1512,8 @@
         felem_contract(tmp[1], ftmp);
 
         if (!skip) {
-          point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], mixed, tmp[0],
-                    tmp[1], tmp[2]);
+          point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+                    tmp[0], tmp[1], tmp[2]);
         } else {
           smallfelem_expand(nq[0], tmp[0]);
           smallfelem_expand(nq[1], tmp[1]);
@@ -1591,6 +1522,11 @@
         }
       }
     }
+
+    if (i == 0) {
+      break;
+    }
+    --i;
   }
   felem_assign(x_out, nq[0]);
   felem_assign(y_out, nq[1]);
@@ -1602,53 +1538,12 @@
  * OPENSSL EC_METHOD FUNCTIONS
  */
 
-int ec_GFp_nistp256_group_init(EC_GROUP *group) {
-  int ret = ec_GFp_simple_group_init(group);
-  group->a_is_minus3 = 1;
-  return ret;
-}
-
-int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-                                    const BIGNUM *a, const BIGNUM *b,
-                                    BN_CTX *ctx) {
-  int ret = 0;
-  BN_CTX *new_ctx = NULL;
-  BIGNUM *curve_p, *curve_a, *curve_b;
-
-  if (ctx == NULL) {
-    if ((ctx = new_ctx = BN_CTX_new()) == NULL) {
-      return 0;
-    }
-  }
-  BN_CTX_start(ctx);
-  if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
-      ((curve_a = BN_CTX_get(ctx)) == NULL) ||
-      ((curve_b = BN_CTX_get(ctx)) == NULL)) {
-    goto err;
-  }
-  BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
-  BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
-  BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
-  if (BN_cmp(curve_p, p) ||
-      BN_cmp(curve_a, a) ||
-      BN_cmp(curve_b, b)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
-    goto err;
-  }
-  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-
-err:
-  BN_CTX_end(ctx);
-  BN_CTX_free(new_ctx);
-  return ret;
-}
-
 /* Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
  * (X/Z^2, Y/Z^3). */
-int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
-                                                 const EC_POINT *point,
-                                                 BIGNUM *x, BIGNUM *y,
-                                                 BN_CTX *ctx) {
+static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+                                                        const EC_POINT *point,
+                                                        BIGNUM *x, BIGNUM *y,
+                                                        BN_CTX *ctx) {
   felem z1, z2, x_in, y_in;
   smallfelem x_out, y_out;
   longfelem tmp;
@@ -1665,45 +1560,38 @@
   felem_inv(z2, z1);
   felem_square(tmp, z2);
   felem_reduce(z1, tmp);
-  felem_mul(tmp, x_in, z1);
-  felem_reduce(x_in, tmp);
-  felem_contract(x_out, x_in);
-  if (x != NULL && !smallfelem_to_BN(x, x_out)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-    return 0;
+
+  if (x != NULL) {
+    felem_mul(tmp, x_in, z1);
+    felem_reduce(x_in, tmp);
+    felem_contract(x_out, x_in);
+    if (!smallfelem_to_BN(x, x_out)) {
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+      return 0;
+    }
   }
-  felem_mul(tmp, z1, z2);
-  felem_reduce(z1, tmp);
-  felem_mul(tmp, y_in, z1);
-  felem_reduce(y_in, tmp);
-  felem_contract(y_out, y_in);
-  if (y != NULL && !smallfelem_to_BN(y, y_out)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-    return 0;
+
+  if (y != NULL) {
+    felem_mul(tmp, z1, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, y_in, z1);
+    felem_reduce(y_in, tmp);
+    felem_contract(y_out, y_in);
+    if (!smallfelem_to_BN(y, y_out)) {
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+      return 0;
+    }
   }
+
   return 1;
 }
 
-/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */
-static void make_points_affine(size_t num, smallfelem points[][3],
-                               smallfelem tmp_smallfelems[]) {
-  /* Runs in constant time, unless an input is the point at infinity (which
-   * normally shouldn't happen). */
-  ec_GFp_nistp_points_make_affine_internal(
-      num, points, sizeof(smallfelem), tmp_smallfelems,
-      (void (*)(void *))smallfelem_one,
-      (int (*)(const void *))smallfelem_is_zero_int,
-      (void (*)(void *, const void *))smallfelem_assign,
-      (void (*)(void *, const void *))smallfelem_square_contract,
-      (void (*)(void *, const void *, const void *))smallfelem_mul_contract,
-      (void (*)(void *, const void *))smallfelem_inv_contract,
-      /* nothing to contract */
-      (void (*)(void *, const void *))smallfelem_assign);
-}
-
-int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
-                               const BIGNUM *g_scalar, const EC_POINT *p_,
-                               const BIGNUM *p_scalar_, BN_CTX *ctx) {
+static int ec_GFp_nistp256_points_mul(const EC_GROUP *group,
+                                      EC_POINT *r,
+                                      const BIGNUM *g_scalar,
+                                      const EC_POINT *p_,
+                                      const BIGNUM *p_scalar_,
+                                      BN_CTX *ctx) {
   /* TODO: This function used to take |points| and |scalars| as arrays of
    * |num| elements. The code below should be simplified to work in terms of |p|
    * and |p_scalar|. */
@@ -1712,16 +1600,12 @@
   BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
 
   int ret = 0;
-  int j;
-  int mixed = 0;
   BN_CTX *new_ctx = NULL;
   BIGNUM *x, *y, *z, *tmp_scalar;
   felem_bytearray g_secret;
   felem_bytearray *secrets = NULL;
   smallfelem(*pre_comp)[17][3] = NULL;
-  smallfelem *tmp_smallfelems = NULL;
   felem_bytearray tmp;
-  unsigned i, num_bytes;
   size_t num_points = num;
   smallfelem x_in, y_in, z_in;
   felem x_out, y_out, z_out;
@@ -1744,19 +1628,9 @@
   }
 
   if (num_points > 0) {
-    if (num_points >= 3) {
-      /* unless we precompute multiples for just one or two points,
-       * converting those into affine form is time well spent */
-      mixed = 1;
-    }
     secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
     pre_comp = OPENSSL_malloc(num_points * sizeof(smallfelem[17][3]));
-    if (mixed) {
-      tmp_smallfelems =
-          OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
-    }
-    if (secrets == NULL || pre_comp == NULL ||
-        (mixed && tmp_smallfelems == NULL)) {
+    if (secrets == NULL || pre_comp == NULL) {
       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       goto err;
     }
@@ -1765,6 +1639,7 @@
      * i.e., they contribute nothing to the linear combination. */
     memset(secrets, 0, num_points * sizeof(felem_bytearray));
     memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
+    size_t i;
     for (i = 0; i < num_points; ++i) {
       if (i == num) {
         /* we didn't have a valid precomputation, so we pick the generator. */
@@ -1776,6 +1651,7 @@
         p_scalar = scalars[i];
       }
       if (p_scalar != NULL && p != NULL) {
+        size_t num_bytes;
         /* reduce g_scalar to 0 <= g_scalar < 2^256 */
         if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
           /* this is an unusual input, and we don't guarantee
@@ -1798,6 +1674,7 @@
         felem_shrink(pre_comp[i][1][0], x_out);
         felem_shrink(pre_comp[i][1][1], y_out);
         felem_shrink(pre_comp[i][1][2], z_out);
+        size_t j;
         for (j = 2; j <= 16; ++j) {
           if (j & 1) {
             point_add_small(pre_comp[i][j][0], pre_comp[i][j][1],
@@ -1813,12 +1690,11 @@
         }
       }
     }
-    if (mixed) {
-      make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
-    }
   }
 
   if (g_scalar != NULL) {
+    size_t num_bytes;
+
     memset(g_secret, 0, sizeof(g_secret));
     /* reduce g_scalar to 0 <= g_scalar < 2^256 */
     if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
@@ -1835,7 +1711,7 @@
     flip_endian(g_secret, tmp, num_bytes);
   }
   batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
-            num_points, g_scalar != NULL ? g_secret : NULL, mixed,
+            num_points, g_scalar != NULL ? g_secret : NULL,
             (const smallfelem(*)[17][3])pre_comp);
 
   /* reduce the output to its unique minimal representation */
@@ -1855,21 +1731,20 @@
   BN_CTX_free(new_ctx);
   OPENSSL_free(secrets);
   OPENSSL_free(pre_comp);
-  OPENSSL_free(tmp_smallfelems);
   return ret;
 }
 
 const EC_METHOD *EC_GFp_nistp256_method(void) {
   static const EC_METHOD ret = {
-      ec_GFp_nistp256_group_init,
+      ec_GFp_simple_group_init,
       ec_GFp_simple_group_finish,
-      ec_GFp_simple_group_clear_finish,
-      ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
+      ec_GFp_simple_group_copy,
+      ec_GFp_simple_group_set_curve,
       ec_GFp_nistp256_point_get_affine_coordinates,
       ec_GFp_nistp256_points_mul,
       0 /* check_pub_key_order */,
       ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
-      0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
+      0 /* field_encode */, 0 /* field_decode */,
   };
 
   return &ret;
diff --git a/src/crypto/ec/p256-x86_64-table.h b/src/crypto/ec/p256-x86_64-table.h
index 5b3254c..e4705f8 100644
--- a/src/crypto/ec/p256-x86_64-table.h
+++ b/src/crypto/ec/p256-x86_64-table.h
@@ -24,12 +24,7 @@
  * in order to increase the chances of using a large page but that appears to
  * lead to invalid ELF files being produced. */
 
-#if defined(__GNUC__)
-__attribute((aligned(4096)))
-#elif defined(_MSC_VER)
-__declspec(align(4096))
-#endif
-static const BN_ULONG
+static const alignas(4096) BN_ULONG
     ecp_nistz256_precomputed[37][64 * sizeof(P256_POINT_AFFINE) /
                                  sizeof(BN_ULONG)] = {
         {TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c
index 2f7023d..e1afec4 100644
--- a/src/crypto/ec/p256-x86_64.c
+++ b/src/crypto/ec/p256-x86_64.c
@@ -39,15 +39,6 @@
     !defined(OPENSSL_SMALL)
 
 
-#if defined(__GNUC__)
-#define ALIGN(x) __attribute((aligned(x)))
-#elif defined(_MSC_VER)
-#define ALIGN(x) __declspec(align(x))
-#else
-#define ALIGN(x)
-#endif
-
-#define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
 #define P256_LIMBS (256 / BN_BITS2)
 
 typedef struct {
@@ -214,9 +205,7 @@
 
   ecp_nistz256_sqr_mont(res, res);
   ecp_nistz256_sqr_mont(res, res);
-  ecp_nistz256_mul_mont(res, res, in);
-
-  memcpy(r, res, sizeof(res));
+  ecp_nistz256_mul_mont(r, res, in);
 }
 
 /* ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
@@ -245,7 +234,7 @@
   /* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
    * add no more than 63 bytes of overhead. Thus, |table| should require
    * ~1599 ((96 * 16) + 63) bytes of stack space. */
-  ALIGN(64) P256_POINT table[16];
+  alignas(64) P256_POINT table[16];
   uint8_t p_str[33];
 
 
@@ -326,7 +315,7 @@
   ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
 
   BN_ULONG tmp[P256_LIMBS];
-  ALIGN(32) P256_POINT h;
+  alignas(32) P256_POINT h;
   unsigned index = 255;
   unsigned wvalue = p_str[(index - 1) / 8];
   wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
@@ -390,7 +379,7 @@
   static const unsigned kWindowSize = 7;
   static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
 
-  ALIGN(32) union {
+  alignas(32) union {
     P256_POINT p;
     P256_POINT_AFFINE a;
   } t, p;
@@ -399,17 +388,6 @@
   BN_CTX *new_ctx = NULL;
   int ctx_started = 0;
 
-  /* Need 256 bits for space for all coordinates. */
-  if (bn_wexpand(&r->X, P256_LIMBS) == NULL ||
-      bn_wexpand(&r->Y, P256_LIMBS) == NULL ||
-      bn_wexpand(&r->Z, P256_LIMBS) == NULL) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-  r->X.top = P256_LIMBS;
-  r->Y.top = P256_LIMBS;
-  r->Z.top = P256_LIMBS;
-
   if (g_scalar != NULL) {
     if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
       if (ctx == NULL) {
@@ -503,15 +481,12 @@
     }
   }
 
-  memcpy(r->X.d, p.p.X, sizeof(p.p.X));
-  memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y));
-  memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z));
-
   /* Not constant-time, but we're only operating on the public output. */
-  bn_correct_top(&r->X);
-  bn_correct_top(&r->Y);
-  bn_correct_top(&r->Z);
-  r->Z_is_one = BN_is_one(&r->Z);
+  if (!bn_set_words(&r->X, p.p.X, P256_LIMBS) ||
+      !bn_set_words(&r->Y, p.p.Y, P256_LIMBS) ||
+      !bn_set_words(&r->Z, p.p.Z, P256_LIMBS)) {
+    return 0;
+  }
 
   ret = 1;
 
@@ -527,8 +502,6 @@
                                    BIGNUM *x, BIGNUM *y, BN_CTX *ctx) {
   BN_ULONG z_inv2[P256_LIMBS];
   BN_ULONG z_inv3[P256_LIMBS];
-  BN_ULONG x_aff[P256_LIMBS];
-  BN_ULONG y_aff[P256_LIMBS];
   BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
 
   if (EC_POINT_is_at_infinity(group, point)) {
@@ -545,7 +518,12 @@
 
   ecp_nistz256_mod_inverse(z_inv3, point_z);
   ecp_nistz256_sqr_mont(z_inv2, z_inv3);
-  ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
+
+  /* Instead of using |ecp_nistz256_from_mont| to convert the |x| coordinate
+   * and then calling |ecp_nistz256_from_mont| again to convert the |y|
+   * coordinate below, convert the common factor |z_inv2| once now, saving one
+   * reduction. */
+  ecp_nistz256_from_mont(z_inv2, z_inv2);
 
   if (x != NULL) {
     if (bn_wexpand(x, P256_LIMBS) == NULL) {
@@ -553,19 +531,20 @@
       return 0;
     }
     x->top = P256_LIMBS;
-    ecp_nistz256_from_mont(x->d, x_aff);
+    x->neg = 0;
+    ecp_nistz256_mul_mont(x->d, z_inv2, point_x);
     bn_correct_top(x);
   }
 
   if (y != NULL) {
     ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
-    ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
     if (bn_wexpand(y, P256_LIMBS) == NULL) {
       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       return 0;
     }
     y->top = P256_LIMBS;
-    ecp_nistz256_from_mont(y->d, y_aff);
+    y->neg = 0;
+    ecp_nistz256_mul_mont(y->d, z_inv3, point_y);
     bn_correct_top(y);
   }
 
@@ -576,7 +555,6 @@
   static const EC_METHOD ret = {
       ec_GFp_mont_group_init,
       ec_GFp_mont_group_finish,
-      ec_GFp_mont_group_clear_finish,
       ec_GFp_mont_group_copy,
       ec_GFp_mont_group_set_curve,
       ecp_nistz256_get_affine,
@@ -586,7 +564,6 @@
       ec_GFp_mont_field_sqr,
       ec_GFp_mont_field_encode,
       ec_GFp_mont_field_decode,
-      ec_GFp_mont_field_set_to_one,
   };
 
   return &ret;
diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c
index cef0e94..4508d83 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -82,16 +82,16 @@
  * field_sqr methods will be used for multiplication, and field_encode and
  * field_decode (if defined) will be used for converting between
  * representations.
-
- * Functions ec_GFp_simple_points_make_affine() and
- * ec_GFp_simple_point_get_affine_coordinates() specifically assume that if a
- * non-trivial representation is used, it is a Montgomery representation (i.e.
- * 'encoding' means multiplying by some factor R). */
+ *
+ * Functions here specifically assume that if a non-trivial representation is
+ * used, it is a Montgomery representation (i.e. 'encoding' means multiplying
+ * by some factor R). */
 
 int ec_GFp_simple_group_init(EC_GROUP *group) {
   BN_init(&group->field);
   BN_init(&group->a);
   BN_init(&group->b);
+  BN_init(&group->one);
   group->a_is_minus3 = 0;
   return 1;
 }
@@ -100,18 +100,14 @@
   BN_free(&group->field);
   BN_free(&group->a);
   BN_free(&group->b);
-}
-
-void ec_GFp_simple_group_clear_finish(EC_GROUP *group) {
-  BN_clear_free(&group->field);
-  BN_clear_free(&group->a);
-  BN_clear_free(&group->b);
+  BN_free(&group->one);
 }
 
 int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
   if (!BN_copy(&dest->field, &src->field) ||
       !BN_copy(&dest->a, &src->a) ||
-      !BN_copy(&dest->b, &src->b)) {
+      !BN_copy(&dest->b, &src->b) ||
+      !BN_copy(&dest->one, &src->one)) {
     return 0;
   }
 
@@ -178,6 +174,14 @@
   }
   group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
 
+  if (group->meth->field_encode != NULL) {
+    if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) {
+      goto err;
+    }
+  } else if (!BN_copy(&group->one, BN_value_one())) {
+    goto err;
+  }
+
   ret = 1;
 
 err:
@@ -230,81 +234,10 @@
   return BN_num_bits(&group->field);
 }
 
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) {
-  int ret = 0;
-  BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
-  const BIGNUM *p = &group->field;
-  BN_CTX *new_ctx = NULL;
-
-  if (ctx == NULL) {
-    ctx = new_ctx = BN_CTX_new();
-    if (ctx == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-  }
-  BN_CTX_start(ctx);
-  a = BN_CTX_get(ctx);
-  b = BN_CTX_get(ctx);
-  tmp_1 = BN_CTX_get(ctx);
-  tmp_2 = BN_CTX_get(ctx);
-  order = BN_CTX_get(ctx);
-  if (order == NULL) {
-    goto err;
-  }
-
-  if (group->meth->field_decode) {
-    if (!group->meth->field_decode(group, a, &group->a, ctx) ||
-        !group->meth->field_decode(group, b, &group->b, ctx)) {
-      goto err;
-    }
-  } else {
-    if (!BN_copy(a, &group->a) || !BN_copy(b, &group->b)) {
-      goto err;
-    }
-  }
-
-  /* check the discriminant:
-   * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
-   * 0 =< a, b < p */
-  if (BN_is_zero(a)) {
-    if (BN_is_zero(b)) {
-      goto err;
-    }
-  } else if (!BN_is_zero(b)) {
-    if (!BN_mod_sqr(tmp_1, a, p, ctx) ||
-        !BN_mod_mul(tmp_2, tmp_1, a, p, ctx) ||
-        !BN_lshift(tmp_1, tmp_2, 2)) {
-      goto err;
-    }
-    /* tmp_1 = 4*a^3 */
-
-    if (!BN_mod_sqr(tmp_2, b, p, ctx) ||
-        !BN_mul_word(tmp_2, 27)) {
-      goto err;
-    }
-    /* tmp_2 = 27*b^2 */
-
-    if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx) ||
-        BN_is_zero(a)) {
-      goto err;
-    }
-  }
-  ret = 1;
-
-err:
-  if (ctx != NULL) {
-    BN_CTX_end(ctx);
-  }
-  BN_CTX_free(new_ctx);
-  return ret;
-}
-
 int ec_GFp_simple_point_init(EC_POINT *point) {
   BN_init(&point->X);
   BN_init(&point->Y);
   BN_init(&point->Z);
-  point->Z_is_one = 0;
 
   return 1;
 }
@@ -319,7 +252,6 @@
   BN_clear_free(&point->X);
   BN_clear_free(&point->Y);
   BN_clear_free(&point->Z);
-  point->Z_is_one = 0;
 }
 
 int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
@@ -328,18 +260,32 @@
       !BN_copy(&dest->Z, &src->Z)) {
     return 0;
   }
-  dest->Z_is_one = src->Z_is_one;
 
   return 1;
 }
 
 int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
                                         EC_POINT *point) {
-  point->Z_is_one = 0;
   BN_zero(&point->Z);
   return 1;
 }
 
+static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
+                                          const BIGNUM *in, BN_CTX *ctx) {
+  if (in == NULL) {
+    return 1;
+  }
+  if (BN_is_negative(in) ||
+      BN_cmp(in, &group->field) >= 0) {
+    OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
+    return 0;
+  }
+  if (group->meth->field_encode) {
+    return group->meth->field_encode(group, out, in, ctx);
+  }
+  return BN_copy(out, in) != NULL;
+}
+
 int ec_GFp_simple_set_Jprojective_coordinates_GFp(
     const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y,
     const BIGNUM *z, BN_CTX *ctx) {
@@ -353,43 +299,10 @@
     }
   }
 
-  if (x != NULL) {
-    if (!BN_nnmod(&point->X, x, &group->field, ctx)) {
-      goto err;
-    }
-    if (group->meth->field_encode &&
-        !group->meth->field_encode(group, &point->X, &point->X, ctx)) {
-      goto err;
-    }
-  }
-
-  if (y != NULL) {
-    if (!BN_nnmod(&point->Y, y, &group->field, ctx)) {
-      goto err;
-    }
-    if (group->meth->field_encode &&
-        !group->meth->field_encode(group, &point->Y, &point->Y, ctx)) {
-      goto err;
-    }
-  }
-
-  if (z != NULL) {
-    int Z_is_one;
-
-    if (!BN_nnmod(&point->Z, z, &group->field, ctx)) {
-      goto err;
-    }
-    Z_is_one = BN_is_one(&point->Z);
-    if (group->meth->field_encode) {
-      if (Z_is_one && (group->meth->field_set_to_one != 0)) {
-        if (!group->meth->field_set_to_one(group, &point->Z, ctx)) {
-          goto err;
-        }
-      } else if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) {
-        goto err;
-      }
-    }
-    point->Z_is_one = Z_is_one;
+  if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) ||
+      !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) ||
+      !set_Jprojective_coordinate_GFp(group, &point->Z, z, ctx)) {
+    goto err;
   }
 
   ret = 1;
@@ -455,109 +368,6 @@
                                                   BN_value_one(), ctx);
 }
 
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
-                                               const EC_POINT *point, BIGNUM *x,
-                                               BIGNUM *y, BN_CTX *ctx) {
-  BN_CTX *new_ctx = NULL;
-  BIGNUM *Z, *Z_1, *Z_2, *Z_3;
-  const BIGNUM *Z_;
-  int ret = 0;
-
-  if (EC_POINT_is_at_infinity(group, point)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
-    return 0;
-  }
-
-  if (ctx == NULL) {
-    ctx = new_ctx = BN_CTX_new();
-    if (ctx == NULL) {
-      return 0;
-    }
-  }
-
-  BN_CTX_start(ctx);
-  Z = BN_CTX_get(ctx);
-  Z_1 = BN_CTX_get(ctx);
-  Z_2 = BN_CTX_get(ctx);
-  Z_3 = BN_CTX_get(ctx);
-  if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
-    goto err;
-  }
-
-  /* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
-
-  if (group->meth->field_decode) {
-    if (!group->meth->field_decode(group, Z, &point->Z, ctx)) {
-      goto err;
-    }
-    Z_ = Z;
-  } else {
-    Z_ = &point->Z;
-  }
-
-  if (BN_is_one(Z_)) {
-    if (group->meth->field_decode) {
-      if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
-        goto err;
-      }
-      if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
-        goto err;
-      }
-    } else {
-      if (x != NULL && !BN_copy(x, &point->X)) {
-        goto err;
-      }
-      if (y != NULL && !BN_copy(y, &point->Y)) {
-        goto err;
-      }
-    }
-  } else {
-    if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-      goto err;
-    }
-
-    if (group->meth->field_encode == 0) {
-      /* field_sqr works on standard representation */
-      if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) {
-        goto err;
-      }
-    } else if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) {
-      goto err;
-    }
-
-    /* in the Montgomery case, field_mul will cancel out Montgomery factor in
-     * X: */
-    if (x != NULL && !group->meth->field_mul(group, x, &point->X, Z_2, ctx)) {
-      goto err;
-    }
-
-    if (y != NULL) {
-      if (group->meth->field_encode == 0) {
-        /* field_mul works on standard representation */
-        if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) {
-          goto err;
-        }
-      } else if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) {
-        goto err;
-      }
-
-      /* in the Montgomery case, field_mul will cancel out Montgomery factor in
-       * Y: */
-      if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) {
-        goto err;
-      }
-    }
-  }
-
-  ret = 1;
-
-err:
-  BN_CTX_end(ctx);
-  BN_CTX_free(new_ctx);
-  return ret;
-}
-
 int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                       const EC_POINT *b, BN_CTX *ctx) {
   int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
@@ -607,7 +417,9 @@
    */
 
   /* n1, n2 */
-  if (b->Z_is_one) {
+  int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
+
+  if (b_Z_is_one) {
     if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) {
       goto end;
     }
@@ -628,7 +440,8 @@
   }
 
   /* n3, n4 */
-  if (a->Z_is_one) {
+  int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
+  if (a_Z_is_one) {
     if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) {
       goto end;
     }
@@ -666,7 +479,6 @@
     } else {
       /* a is the inverse of b */
       BN_zero(&r->Z);
-      r->Z_is_one = 0;
       ret = 1;
       goto end;
     }
@@ -681,16 +493,16 @@
   /* 'n8' = n2 + n4 */
 
   /* Z_r */
-  if (a->Z_is_one && b->Z_is_one) {
+  if (a_Z_is_one && b_Z_is_one) {
     if (!BN_copy(&r->Z, n5)) {
       goto end;
     }
   } else {
-    if (a->Z_is_one) {
+    if (a_Z_is_one) {
       if (!BN_copy(n0, &b->Z)) {
         goto end;
       }
-    } else if (b->Z_is_one) {
+    } else if (b_Z_is_one) {
       if (!BN_copy(n0, &a->Z)) {
         goto end;
       }
@@ -701,7 +513,7 @@
       goto end;
     }
   }
-  r->Z_is_one = 0;
+
   /* Z_r = Z_a * Z_b * n5 */
 
   /* X_r */
@@ -761,7 +573,6 @@
 
   if (EC_POINT_is_at_infinity(group, a)) {
     BN_zero(&r->Z);
-    r->Z_is_one = 0;
     return 1;
   }
 
@@ -791,7 +602,7 @@
    */
 
   /* n1 */
-  if (a->Z_is_one) {
+  if (BN_cmp(&a->Z, &group->one) == 0) {
     if (!field_sqr(group, n0, &a->X, ctx) ||
         !BN_mod_lshift1_quick(n1, n0, p) ||
         !BN_mod_add_quick(n0, n0, n1, p) ||
@@ -824,7 +635,7 @@
   }
 
   /* Z_r */
-  if (a->Z_is_one) {
+  if (BN_cmp(&a->Z, &group->one) == 0) {
     if (!BN_copy(n0, &a->Y)) {
       goto err;
     }
@@ -834,7 +645,6 @@
   if (!BN_mod_lshift1_quick(&r->Z, n0, p)) {
     goto err;
   }
-  r->Z_is_one = 0;
   /* Z_r = 2 * Y_a * Z_a */
 
   /* n2 */
@@ -886,7 +696,7 @@
 }
 
 int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
-  return !point->Z_is_one && BN_is_zero(&point->Z);
+  return BN_is_zero(&point->Z);
 }
 
 int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
@@ -897,7 +707,7 @@
   const BIGNUM *p;
   BN_CTX *new_ctx = NULL;
   BIGNUM *rh, *tmp, *Z4, *Z6;
-  int ret = -1;
+  int ret = 0;
 
   if (EC_POINT_is_at_infinity(group, point)) {
     return 1;
@@ -910,7 +720,7 @@
   if (ctx == NULL) {
     ctx = new_ctx = BN_CTX_new();
     if (ctx == NULL) {
-      return -1;
+      return 0;
     }
   }
 
@@ -938,7 +748,7 @@
     goto err;
   }
 
-  if (!point->Z_is_one) {
+  if (BN_cmp(&point->Z, &group->one) != 0) {
     if (!field_sqr(group, tmp, &point->Z, ctx) ||
         !field_sqr(group, Z4, tmp, ctx) ||
         !field_mul(group, Z6, Z4, tmp, ctx)) {
@@ -967,8 +777,6 @@
       goto err;
     }
   } else {
-    /* point->Z_is_one */
-
     /* rh := (rh + a)*X */
     if (!BN_mod_add_quick(rh, rh, &group->a, p) ||
         !field_mul(group, rh, rh, &point->X, ctx)) {
@@ -1017,7 +825,10 @@
     return 1;
   }
 
-  if (a->Z_is_one && b->Z_is_one) {
+  int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
+  int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
+
+  if (a_Z_is_one && b_Z_is_one) {
     return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
   }
 
@@ -1046,7 +857,7 @@
    *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
    */
 
-  if (!b->Z_is_one) {
+  if (!b_Z_is_one) {
     if (!field_sqr(group, Zb23, &b->Z, ctx) ||
         !field_mul(group, tmp1, &a->X, Zb23, ctx)) {
       goto end;
@@ -1055,7 +866,7 @@
   } else {
     tmp1_ = &a->X;
   }
-  if (!a->Z_is_one) {
+  if (!a_Z_is_one) {
     if (!field_sqr(group, Za23, &a->Z, ctx) ||
         !field_mul(group, tmp2, &b->X, Za23, ctx)) {
       goto end;
@@ -1072,7 +883,7 @@
   }
 
 
-  if (!b->Z_is_one) {
+  if (!b_Z_is_one) {
     if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) ||
         !field_mul(group, tmp1, &a->Y, Zb23, ctx)) {
       goto end;
@@ -1081,7 +892,7 @@
   } else {
     tmp1_ = &a->Y;
   }
-  if (!a->Z_is_one) {
+  if (!a_Z_is_one) {
     if (!field_mul(group, Za23, Za23, &a->Z, ctx) ||
         !field_mul(group, tmp2, &b->Y, Za23, ctx)) {
       goto end;
@@ -1112,7 +923,8 @@
   BIGNUM *x, *y;
   int ret = 0;
 
-  if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) {
+  if (BN_cmp(&point->Z, &group->one) == 0 ||
+      EC_POINT_is_at_infinity(group, point)) {
     return 1;
   }
 
@@ -1134,7 +946,7 @@
       !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
     goto err;
   }
-  if (!point->Z_is_one) {
+  if (BN_cmp(&point->Z, &group->one) != 0) {
     OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
     goto err;
   }
@@ -1193,14 +1005,8 @@
       goto err;
     }
   } else {
-    if (group->meth->field_set_to_one != 0) {
-      if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) {
-        goto err;
-      }
-    } else {
-      if (!BN_one(prod_Z[0])) {
-        goto err;
-      }
+    if (BN_copy(prod_Z[0], &group->one) == NULL) {
+      goto err;
     }
   }
 
@@ -1271,16 +1077,9 @@
         goto err;
       }
 
-      if (group->meth->field_set_to_one != NULL) {
-        if (!group->meth->field_set_to_one(group, &p->Z, ctx)) {
-          goto err;
-        }
-      } else {
-        if (!BN_one(&p->Z)) {
-          goto err;
-        }
+      if (BN_copy(&p->Z, &group->one) == NULL) {
+        goto err;
       }
-      p->Z_is_one = 1;
     }
   }
 
diff --git a/src/crypto/ec/util-64.c b/src/crypto/ec/util-64.c
index 171b063..4006271 100644
--- a/src/crypto/ec/util-64.c
+++ b/src/crypto/ec/util-64.c
@@ -21,80 +21,6 @@
 
 #include "internal.h"
 
-/* Convert an array of points into affine coordinates. (If the point at
- * infinity is found (Z = 0), it remains unchanged.) This function is
- * essentially an equivalent to EC_POINTs_make_affine(), but works with the
- * internal representation of points as used by ecp_nistp###.c rather than
- * with (BIGNUM-based) EC_POINT data structures. point_array is the
- * input/output buffer ('num' points in projective form, i.e. three
- * coordinates each), based on an internal representation of field elements
- * of size 'felem_size'. tmp_felems needs to point to a temporary array of
- * 'num'+1 field elements for storage of intermediate values. */
-void ec_GFp_nistp_points_make_affine_internal(
-    size_t num, void *point_array, size_t felem_size, void *tmp_felems,
-    void (*felem_one)(void *out), int (*felem_is_zero)(const void *in),
-    void (*felem_assign)(void *out, const void *in),
-    void (*felem_square)(void *out, const void *in),
-    void (*felem_mul)(void *out, const void *in1, const void *in2),
-    void (*felem_inv)(void *out, const void *in),
-    void (*felem_contract)(void *out, const void *in)) {
-  int i = 0;
-
-#define tmp_felem(I) (&((char *)tmp_felems)[(I)*felem_size])
-#define X(I) (&((char *)point_array)[3 * (I)*felem_size])
-#define Y(I) (&((char *)point_array)[(3 * (I) + 1) * felem_size])
-#define Z(I) (&((char *)point_array)[(3 * (I) + 2) * felem_size])
-
-  if (!felem_is_zero(Z(0))) {
-    felem_assign(tmp_felem(0), Z(0));
-  } else {
-    felem_one(tmp_felem(0));
-  }
-
-  for (i = 1; i < (int)num; i++) {
-    if (!felem_is_zero(Z(i))) {
-      felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
-    } else {
-      felem_assign(tmp_felem(i), tmp_felem(i - 1));
-    }
-  }
-  /* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
-   * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1. */
-
-  felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
-  for (i = num - 1; i >= 0; i--) {
-    if (i > 0) {
-      /* tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
-       * is the inverse of the product of Z(0) .. Z(i). */
-      /* 1/Z(i) */
-      felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
-    } else {
-      felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
-    }
-
-    if (!felem_is_zero(Z(i))) {
-      if (i > 0) {
-        /* For next iteration, replace tmp_felem(i-1) by its inverse. */
-        felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
-      }
-
-      /* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1). */
-      felem_square(Z(i), tmp_felem(num));    /* 1/(Z^2) */
-      felem_mul(X(i), X(i), Z(i));           /* X/(Z^2) */
-      felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
-      felem_mul(Y(i), Y(i), Z(i));           /* Y/(Z^3) */
-      felem_contract(X(i), X(i));
-      felem_contract(Y(i), Y(i));
-      felem_one(Z(i));
-    } else {
-      if (i > 0) {
-        /* For next iteration, replace tmp_felem(i-1) by its inverse. */
-        felem_assign(tmp_felem(i - 1), tmp_felem(i));
-      }
-    }
-  }
-}
-
 /* This function looks at 5+1 scalar bits (5 current, 1 adjacent less
  * significant bit), and recodes them into a signed digit for use in fast point
  * multiplication: the use of signed rather than unsigned digits means that
diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c
index 16760ed..70cb118 100644
--- a/src/crypto/ecdsa/ecdsa.c
+++ b/src/crypto/ecdsa/ecdsa.c
@@ -79,10 +79,6 @@
   int ret = 0;
   uint8_t *der = NULL;
 
-  if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
-    return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
-  }
-
   /* Decode the ECDSA signature. */
   s = ECDSA_SIG_from_bytes(sig, sig_len);
   if (s == NULL) {
@@ -148,11 +144,6 @@
   const EC_GROUP *group;
   const EC_POINT *pub_key;
 
-  if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
-    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
-    return 0;
-  }
-
   /* check input values */
   if ((group = EC_KEY_get0_group(eckey)) == NULL ||
       (pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
@@ -224,7 +215,7 @@
   ret = (BN_ucmp(u1, sig->r) == 0);
 
 err:
-  BN_CTX_end(ctx);

+  BN_CTX_end(ctx);
   BN_CTX_free(ctx);
   EC_POINT_free(point);
   return ret;
diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c
index 3fee191..d41a536 100644
--- a/src/crypto/ecdsa/ecdsa_asn1.c
+++ b/src/crypto/ecdsa/ecdsa_asn1.c
@@ -61,6 +61,7 @@
 #include <openssl/ec_key.h>
 #include <openssl/mem.h>
 
+#include "../bytestring/internal.h"
 #include "../ec/internal.h"
 
 
@@ -115,8 +116,8 @@
   }
   CBS child;
   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
-      !BN_cbs2unsigned(&child, ret->r) ||
-      !BN_cbs2unsigned(&child, ret->s) ||
+      !BN_parse_asn1_unsigned(&child, ret->r) ||
+      !BN_parse_asn1_unsigned(&child, ret->s) ||
       CBS_len(&child) != 0) {
     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
     ECDSA_SIG_free(ret);
@@ -140,8 +141,8 @@
 int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) {
   CBB child;
   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
-      !BN_bn2cbb(&child, sig->r) ||
-      !BN_bn2cbb(&child, sig->s) ||
+      !BN_marshal_asn1(&child, sig->r) ||
+      !BN_marshal_asn1(&child, sig->s) ||
       !CBB_flush(cbb)) {
     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
     return 0;
@@ -211,30 +212,16 @@
     ECDSA_SIG_free(*out);
     *out = ret;
   }
-  *inp += (size_t)len - CBS_len(&cbs);
+  *inp = CBS_data(&cbs);
   return ret;
 }
 
 int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) {
-  uint8_t *der;
-  size_t der_len;
-  if (!ECDSA_SIG_to_bytes(&der, &der_len, sig)) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !ECDSA_SIG_marshal(&cbb, sig)) {
+    CBB_cleanup(&cbb);
     return -1;
   }
-  if (der_len > INT_MAX) {
-    OPENSSL_PUT_ERROR(ECDSA, ERR_R_OVERFLOW);
-    OPENSSL_free(der);
-    return -1;
-  }
-  if (outp != NULL) {
-    if (*outp == NULL) {
-      *outp = der;
-      der = NULL;
-    } else {
-      memcpy(*outp, der, der_len);
-      *outp += der_len;
-    }
-  }
-  OPENSSL_free(der);
-  return (int)der_len;
+  return CBB_finish_i2d(&cbb, outp);
 }
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index a0c8fbd..8d7827d 100644
--- a/src/crypto/ecdsa/ecdsa_test.cc
+++ b/src/crypto/ecdsa/ecdsa_test.cc
@@ -59,7 +59,7 @@
 #include <openssl/ec.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 
 #include "../test/scoped_types.h"
@@ -340,16 +340,19 @@
   return true;
 }
 
+static size_t BitsToBytes(size_t bits) {
+  return (bits / 8) + (7 + (bits % 8)) / 8;
+}
+
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!TestBuiltin(stdout) ||
-      !TestECDSA_SIG_max_len(224/8) ||
-      !TestECDSA_SIG_max_len(256/8) ||
-      !TestECDSA_SIG_max_len(384/8) ||
-      !TestECDSA_SIG_max_len(512/8) ||
-      !TestECDSA_SIG_max_len(10000)) {
+      !TestECDSA_SIG_max_len(BitsToBytes(224)) ||
+      !TestECDSA_SIG_max_len(BitsToBytes(256)) ||
+      !TestECDSA_SIG_max_len(BitsToBytes(384)) ||
+      !TestECDSA_SIG_max_len(BitsToBytes(521)) ||
+      !TestECDSA_SIG_max_len(BitsToBytes(10000))) {
     printf("\nECDSA test failed\n");
     ERR_print_errors_fp(stdout);
     return 1;
diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata
index b1b0437..c304b2c 100644
--- a/src/crypto/err/asn1.errordata
+++ b/src/crypto/err/asn1.errordata
@@ -6,82 +6,87 @@
 ASN1,105,BN_LIB
 ASN1,106,BOOLEAN_IS_WRONG_LENGTH
 ASN1,107,BUFFER_TOO_SMALL
-ASN1,108,DECODE_ERROR
-ASN1,109,DEPTH_EXCEEDED
-ASN1,110,ENCODE_ERROR
-ASN1,111,ERROR_GETTING_TIME
-ASN1,112,EXPECTING_AN_ASN1_SEQUENCE
-ASN1,113,EXPECTING_AN_INTEGER
-ASN1,114,EXPECTING_AN_OBJECT
-ASN1,115,EXPECTING_A_BOOLEAN
-ASN1,116,EXPECTING_A_TIME
-ASN1,117,EXPLICIT_LENGTH_MISMATCH
-ASN1,118,EXPLICIT_TAG_NOT_CONSTRUCTED
-ASN1,119,FIELD_MISSING
-ASN1,120,FIRST_NUM_TOO_LARGE
-ASN1,121,HEADER_TOO_LONG
-ASN1,122,ILLEGAL_BITSTRING_FORMAT
-ASN1,123,ILLEGAL_BOOLEAN
-ASN1,124,ILLEGAL_CHARACTERS
-ASN1,125,ILLEGAL_FORMAT
-ASN1,126,ILLEGAL_HEX
-ASN1,127,ILLEGAL_IMPLICIT_TAG
-ASN1,128,ILLEGAL_INTEGER
-ASN1,129,ILLEGAL_NESTED_TAGGING
-ASN1,130,ILLEGAL_NULL
-ASN1,131,ILLEGAL_NULL_VALUE
-ASN1,132,ILLEGAL_OBJECT
-ASN1,133,ILLEGAL_OPTIONAL_ANY
-ASN1,134,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
-ASN1,135,ILLEGAL_TAGGED_ANY
-ASN1,136,ILLEGAL_TIME_VALUE
-ASN1,137,INTEGER_NOT_ASCII_FORMAT
-ASN1,138,INTEGER_TOO_LARGE_FOR_LONG
-ASN1,139,INVALID_BIT_STRING_BITS_LEFT
-ASN1,140,INVALID_BMPSTRING_LENGTH
-ASN1,141,INVALID_DIGIT
-ASN1,142,INVALID_MODIFIER
-ASN1,143,INVALID_NUMBER
-ASN1,144,INVALID_OBJECT_ENCODING
-ASN1,145,INVALID_SEPARATOR
-ASN1,146,INVALID_TIME_FORMAT
-ASN1,147,INVALID_UNIVERSALSTRING_LENGTH
-ASN1,148,INVALID_UTF8STRING
-ASN1,149,LIST_ERROR
-ASN1,150,MISSING_ASN1_EOS
-ASN1,151,MISSING_EOC
-ASN1,152,MISSING_SECOND_NUMBER
-ASN1,153,MISSING_VALUE
-ASN1,154,MSTRING_NOT_UNIVERSAL
-ASN1,155,MSTRING_WRONG_TAG
-ASN1,156,NESTED_ASN1_ERROR
-ASN1,157,NESTED_ASN1_STRING
-ASN1,158,NON_HEX_CHARACTERS
-ASN1,159,NOT_ASCII_FORMAT
-ASN1,160,NOT_ENOUGH_DATA
-ASN1,161,NO_MATCHING_CHOICE_TYPE
-ASN1,162,NULL_IS_WRONG_LENGTH
-ASN1,163,OBJECT_NOT_ASCII_FORMAT
-ASN1,164,ODD_NUMBER_OF_CHARS
-ASN1,165,SECOND_NUMBER_TOO_LARGE
-ASN1,166,SEQUENCE_LENGTH_MISMATCH
-ASN1,167,SEQUENCE_NOT_CONSTRUCTED
-ASN1,168,SEQUENCE_OR_SET_NEEDS_CONFIG
-ASN1,169,SHORT_LINE
-ASN1,170,STREAMING_NOT_SUPPORTED
-ASN1,171,STRING_TOO_LONG
-ASN1,172,STRING_TOO_SHORT
-ASN1,173,TAG_VALUE_TOO_HIGH
-ASN1,174,TIME_NOT_ASCII_FORMAT
-ASN1,175,TOO_LONG
-ASN1,176,TYPE_NOT_CONSTRUCTED
-ASN1,177,TYPE_NOT_PRIMITIVE
-ASN1,178,UNEXPECTED_EOC
-ASN1,179,UNIVERSALSTRING_IS_WRONG_LENGTH
-ASN1,180,UNKNOWN_FORMAT
-ASN1,181,UNKNOWN_TAG
-ASN1,182,UNSUPPORTED_ANY_DEFINED_BY_TYPE
-ASN1,183,UNSUPPORTED_PUBLIC_KEY_TYPE
-ASN1,184,UNSUPPORTED_TYPE
-ASN1,185,WRONG_TAG
-ASN1,186,WRONG_TYPE
+ASN1,108,CONTEXT_NOT_INITIALISED
+ASN1,109,DECODE_ERROR
+ASN1,110,DEPTH_EXCEEDED
+ASN1,111,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
+ASN1,112,ENCODE_ERROR
+ASN1,113,ERROR_GETTING_TIME
+ASN1,114,EXPECTING_AN_ASN1_SEQUENCE
+ASN1,115,EXPECTING_AN_INTEGER
+ASN1,116,EXPECTING_AN_OBJECT
+ASN1,117,EXPECTING_A_BOOLEAN
+ASN1,118,EXPECTING_A_TIME
+ASN1,119,EXPLICIT_LENGTH_MISMATCH
+ASN1,120,EXPLICIT_TAG_NOT_CONSTRUCTED
+ASN1,121,FIELD_MISSING
+ASN1,122,FIRST_NUM_TOO_LARGE
+ASN1,123,HEADER_TOO_LONG
+ASN1,124,ILLEGAL_BITSTRING_FORMAT
+ASN1,125,ILLEGAL_BOOLEAN
+ASN1,126,ILLEGAL_CHARACTERS
+ASN1,127,ILLEGAL_FORMAT
+ASN1,128,ILLEGAL_HEX
+ASN1,129,ILLEGAL_IMPLICIT_TAG
+ASN1,130,ILLEGAL_INTEGER
+ASN1,131,ILLEGAL_NESTED_TAGGING
+ASN1,132,ILLEGAL_NULL
+ASN1,133,ILLEGAL_NULL_VALUE
+ASN1,134,ILLEGAL_OBJECT
+ASN1,135,ILLEGAL_OPTIONAL_ANY
+ASN1,136,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
+ASN1,137,ILLEGAL_TAGGED_ANY
+ASN1,138,ILLEGAL_TIME_VALUE
+ASN1,139,INTEGER_NOT_ASCII_FORMAT
+ASN1,140,INTEGER_TOO_LARGE_FOR_LONG
+ASN1,141,INVALID_BIT_STRING_BITS_LEFT
+ASN1,142,INVALID_BMPSTRING_LENGTH
+ASN1,143,INVALID_DIGIT
+ASN1,144,INVALID_MODIFIER
+ASN1,145,INVALID_NUMBER
+ASN1,146,INVALID_OBJECT_ENCODING
+ASN1,147,INVALID_SEPARATOR
+ASN1,148,INVALID_TIME_FORMAT
+ASN1,149,INVALID_UNIVERSALSTRING_LENGTH
+ASN1,150,INVALID_UTF8STRING
+ASN1,151,LIST_ERROR
+ASN1,152,MISSING_ASN1_EOS
+ASN1,153,MISSING_EOC
+ASN1,154,MISSING_SECOND_NUMBER
+ASN1,155,MISSING_VALUE
+ASN1,156,MSTRING_NOT_UNIVERSAL
+ASN1,157,MSTRING_WRONG_TAG
+ASN1,158,NESTED_ASN1_ERROR
+ASN1,159,NESTED_ASN1_STRING
+ASN1,160,NON_HEX_CHARACTERS
+ASN1,161,NOT_ASCII_FORMAT
+ASN1,162,NOT_ENOUGH_DATA
+ASN1,163,NO_MATCHING_CHOICE_TYPE
+ASN1,164,NULL_IS_WRONG_LENGTH
+ASN1,165,OBJECT_NOT_ASCII_FORMAT
+ASN1,166,ODD_NUMBER_OF_CHARS
+ASN1,167,SECOND_NUMBER_TOO_LARGE
+ASN1,168,SEQUENCE_LENGTH_MISMATCH
+ASN1,169,SEQUENCE_NOT_CONSTRUCTED
+ASN1,170,SEQUENCE_OR_SET_NEEDS_CONFIG
+ASN1,171,SHORT_LINE
+ASN1,172,STREAMING_NOT_SUPPORTED
+ASN1,173,STRING_TOO_LONG
+ASN1,174,STRING_TOO_SHORT
+ASN1,175,TAG_VALUE_TOO_HIGH
+ASN1,176,TIME_NOT_ASCII_FORMAT
+ASN1,177,TOO_LONG
+ASN1,178,TYPE_NOT_CONSTRUCTED
+ASN1,179,TYPE_NOT_PRIMITIVE
+ASN1,180,UNEXPECTED_EOC
+ASN1,181,UNIVERSALSTRING_IS_WRONG_LENGTH
+ASN1,182,UNKNOWN_FORMAT
+ASN1,183,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
+ASN1,184,UNKNOWN_SIGNATURE_ALGORITHM
+ASN1,185,UNKNOWN_TAG
+ASN1,186,UNSUPPORTED_ANY_DEFINED_BY_TYPE
+ASN1,187,UNSUPPORTED_PUBLIC_KEY_TYPE
+ASN1,188,UNSUPPORTED_TYPE
+ASN1,189,WRONG_PUBLIC_KEY_TYPE
+ASN1,190,WRONG_TAG
+ASN1,191,WRONG_TYPE
diff --git a/src/crypto/err/dsa.errordata b/src/crypto/err/dsa.errordata
index 3c5764a..6f4bc13 100644
--- a/src/crypto/err/dsa.errordata
+++ b/src/crypto/err/dsa.errordata
@@ -1,4 +1,7 @@
 DSA,100,BAD_Q_VALUE
+DSA,104,BAD_VERSION
+DSA,105,DECODE_ERROR
+DSA,106,ENCODE_ERROR
 DSA,101,MISSING_PARAMETERS
 DSA,102,MODULUS_TOO_LARGE
 DSA,103,NEED_NEW_SETUP_VALUES
diff --git a/src/crypto/err/ec.errordata b/src/crypto/err/ec.errordata
index e7b4175..d074afc 100644
--- a/src/crypto/err/ec.errordata
+++ b/src/crypto/err/ec.errordata
@@ -2,8 +2,11 @@
 EC,100,BUFFER_TOO_SMALL
 EC,101,COORDINATES_OUT_OF_RANGE
 EC,102,D2I_ECPKPARAMETERS_FAILURE
+EC,128,DECODE_ERROR
 EC,103,EC_GROUP_NEW_BY_NAME_FAILURE
+EC,129,ENCODE_ERROR
 EC,104,GROUP2PKPARAMETERS_FAILURE
+EC,130,GROUP_MISMATCH
 EC,105,I2D_ECPKPARAMETERS_FAILURE
 EC,106,INCOMPATIBLE_OBJECTS
 EC,107,INVALID_COMPRESSED_POINT
diff --git a/src/crypto/err/err_data_generate.go b/src/crypto/err/err_data_generate.go
index 24e0d66..893ebff 100644
--- a/src/crypto/err/err_data_generate.go
+++ b/src/crypto/err/err_data_generate.go
@@ -18,6 +18,7 @@
 	"bufio"
 	"bytes"
 	"errors"
+	"flag"
 	"fmt"
 	"io"
 	"os"
@@ -26,6 +27,8 @@
 	"strings"
 )
 
+var verbose = flag.Bool("verbose", false, "If true, prints a status message at the end.")
+
 // libraryNames must be kept in sync with the enum in err.h. The generated code
 // will contain static assertions to enforce this.
 var libraryNames = []string{
@@ -138,7 +141,9 @@
 
 func (st *stringList) WriteTo(out stringWriter, name string) {
 	list := st.buildList()
-	fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
+	if *verbose {
+		fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
+	}
 
 	values := "kOpenSSL" + name + "Values"
 	out.WriteString("const uint32_t " + values + "[] = {\n")
@@ -215,6 +220,8 @@
 }
 
 func main() {
+	flag.Parse()
+
 	e := &errorData{
 		reasons:    newStringList(),
 		libraryMap: make(map[string]uint32),
diff --git a/src/crypto/err/evp.errordata b/src/crypto/err/evp.errordata
index 8f8dd48..a482f76 100644
--- a/src/crypto/err/evp.errordata
+++ b/src/crypto/err/evp.errordata
@@ -1,46 +1,30 @@
-EVP,151,BN_DECODE_ERROR
 EVP,100,BUFFER_TOO_SMALL
 EVP,101,COMMAND_NOT_SUPPORTED
-EVP,146,CONTEXT_NOT_INITIALISED
-EVP,143,DECODE_ERROR
-EVP,104,DIFFERENT_KEY_TYPES
-EVP,105,DIFFERENT_PARAMETERS
-EVP,147,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
-EVP,107,EXPECTING_AN_EC_KEY_KEY
-EVP,141,EXPECTING_AN_RSA_KEY
-EVP,109,EXPECTING_A_DH_KEY
-EVP,110,EXPECTING_A_DSA_KEY
-EVP,111,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
-EVP,112,INVALID_CURVE
-EVP,113,INVALID_DIGEST_LENGTH
-EVP,114,INVALID_DIGEST_TYPE
-EVP,115,INVALID_KEYBITS
-EVP,116,INVALID_MGF1_MD
-EVP,142,INVALID_OPERATION
-EVP,118,INVALID_PADDING_MODE
-EVP,119,INVALID_PSS_PARAMETERS
-EVP,144,INVALID_PSS_SALTLEN
-EVP,121,INVALID_SALT_LENGTH
-EVP,122,INVALID_TRAILER
-EVP,123,KEYS_NOT_SET
-EVP,124,MISSING_PARAMETERS
-EVP,125,NO_DEFAULT_DIGEST
-EVP,126,NO_KEY_SET
-EVP,127,NO_MDC2_SUPPORT
-EVP,128,NO_NID_FOR_CURVE
-EVP,129,NO_OPERATION_SET
-EVP,130,NO_PARAMETERS_SET
-EVP,131,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
-EVP,132,OPERATON_NOT_INITIALIZED
-EVP,152,PARAMETER_ENCODING_ERROR
-EVP,133,UNKNOWN_DIGEST
-EVP,134,UNKNOWN_MASK_DIGEST
-EVP,150,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
-EVP,145,UNKNOWN_PUBLIC_KEY_TYPE
-EVP,149,UNKNOWN_SIGNATURE_ALGORITHM
-EVP,138,UNSUPPORTED_ALGORITHM
-EVP,139,UNSUPPORTED_MASK_ALGORITHM
-EVP,140,UNSUPPORTED_MASK_PARAMETER
-EVP,153,UNSUPPORTED_PUBLIC_KEY_TYPE
-EVP,154,UNSUPPORTED_SIGNATURE_TYPE
-EVP,148,WRONG_PUBLIC_KEY_TYPE
+EVP,102,DECODE_ERROR
+EVP,103,DIFFERENT_KEY_TYPES
+EVP,104,DIFFERENT_PARAMETERS
+EVP,105,ENCODE_ERROR
+EVP,106,EXPECTING_AN_EC_KEY_KEY
+EVP,107,EXPECTING_AN_RSA_KEY
+EVP,108,EXPECTING_A_DSA_KEY
+EVP,109,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
+EVP,110,INVALID_DIGEST_LENGTH
+EVP,111,INVALID_DIGEST_TYPE
+EVP,112,INVALID_KEYBITS
+EVP,113,INVALID_MGF1_MD
+EVP,114,INVALID_OPERATION
+EVP,115,INVALID_PADDING_MODE
+EVP,116,INVALID_PSS_SALTLEN
+EVP,117,KEYS_NOT_SET
+EVP,118,MISSING_PARAMETERS
+EVP,119,NO_DEFAULT_DIGEST
+EVP,120,NO_KEY_SET
+EVP,121,NO_MDC2_SUPPORT
+EVP,122,NO_NID_FOR_CURVE
+EVP,123,NO_OPERATION_SET
+EVP,124,NO_PARAMETERS_SET
+EVP,125,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
+EVP,126,OPERATON_NOT_INITIALIZED
+EVP,127,UNKNOWN_PUBLIC_KEY_TYPE
+EVP,128,UNSUPPORTED_ALGORITHM
+EVP,129,UNSUPPORTED_PUBLIC_KEY_TYPE
diff --git a/src/crypto/err/rsa.errordata b/src/crypto/err/rsa.errordata
index c19f73c..62d286c 100644
--- a/src/crypto/err/rsa.errordata
+++ b/src/crypto/err/rsa.errordata
@@ -1,46 +1,46 @@
-RSA,143,BAD_ENCODING
-RSA,100,BAD_E_VALUE
-RSA,101,BAD_FIXED_HEADER_DECRYPT
-RSA,102,BAD_PAD_BYTE_COUNT
-RSA,103,BAD_RSA_PARAMETERS
-RSA,104,BAD_SIGNATURE
-RSA,145,BAD_VERSION
-RSA,105,BLOCK_TYPE_IS_NOT_01
-RSA,106,BN_NOT_INITIALIZED
-RSA,142,CANNOT_RECOVER_MULTI_PRIME_KEY
-RSA,107,CRT_PARAMS_ALREADY_GIVEN
-RSA,108,CRT_VALUES_INCORRECT
-RSA,109,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
-RSA,110,DATA_TOO_LARGE
-RSA,111,DATA_TOO_LARGE_FOR_KEY_SIZE
-RSA,112,DATA_TOO_LARGE_FOR_MODULUS
-RSA,113,DATA_TOO_SMALL
-RSA,114,DATA_TOO_SMALL_FOR_KEY_SIZE
-RSA,115,DIGEST_TOO_BIG_FOR_RSA_KEY
-RSA,116,D_E_NOT_CONGRUENT_TO_1
-RSA,117,EMPTY_PUBLIC_KEY
-RSA,144,ENCODE_ERROR
-RSA,118,FIRST_OCTET_INVALID
-RSA,119,INCONSISTENT_SET_OF_CRT_VALUES
-RSA,120,INTERNAL_ERROR
-RSA,121,INVALID_MESSAGE_LENGTH
-RSA,122,KEY_SIZE_TOO_SMALL
-RSA,123,LAST_OCTET_INVALID
-RSA,124,MODULUS_TOO_LARGE
-RSA,141,MUST_HAVE_AT_LEAST_TWO_PRIMES
-RSA,125,NO_PUBLIC_EXPONENT
-RSA,126,NULL_BEFORE_BLOCK_MISSING
-RSA,127,N_NOT_EQUAL_P_Q
-RSA,128,OAEP_DECODING_ERROR
-RSA,129,ONLY_ONE_OF_P_Q_GIVEN
-RSA,130,OUTPUT_BUFFER_TOO_SMALL
-RSA,131,PADDING_CHECK_FAILED
-RSA,132,PKCS_DECODING_ERROR
-RSA,133,SLEN_CHECK_FAILED
-RSA,134,SLEN_RECOVERY_FAILED
-RSA,135,TOO_LONG
-RSA,136,TOO_MANY_ITERATIONS
-RSA,137,UNKNOWN_ALGORITHM_TYPE
-RSA,138,UNKNOWN_PADDING_TYPE
-RSA,139,VALUE_MISSING
-RSA,140,WRONG_SIGNATURE_LENGTH
+RSA,100,BAD_ENCODING
+RSA,101,BAD_E_VALUE
+RSA,102,BAD_FIXED_HEADER_DECRYPT
+RSA,103,BAD_PAD_BYTE_COUNT
+RSA,104,BAD_RSA_PARAMETERS
+RSA,105,BAD_SIGNATURE
+RSA,106,BAD_VERSION
+RSA,107,BLOCK_TYPE_IS_NOT_01
+RSA,108,BN_NOT_INITIALIZED
+RSA,109,CANNOT_RECOVER_MULTI_PRIME_KEY
+RSA,110,CRT_PARAMS_ALREADY_GIVEN
+RSA,111,CRT_VALUES_INCORRECT
+RSA,112,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
+RSA,113,DATA_TOO_LARGE
+RSA,114,DATA_TOO_LARGE_FOR_KEY_SIZE
+RSA,115,DATA_TOO_LARGE_FOR_MODULUS
+RSA,116,DATA_TOO_SMALL
+RSA,117,DATA_TOO_SMALL_FOR_KEY_SIZE
+RSA,118,DIGEST_TOO_BIG_FOR_RSA_KEY
+RSA,119,D_E_NOT_CONGRUENT_TO_1
+RSA,120,EMPTY_PUBLIC_KEY
+RSA,121,ENCODE_ERROR
+RSA,122,FIRST_OCTET_INVALID
+RSA,123,INCONSISTENT_SET_OF_CRT_VALUES
+RSA,124,INTERNAL_ERROR
+RSA,125,INVALID_MESSAGE_LENGTH
+RSA,126,KEY_SIZE_TOO_SMALL
+RSA,127,LAST_OCTET_INVALID
+RSA,128,MODULUS_TOO_LARGE
+RSA,129,MUST_HAVE_AT_LEAST_TWO_PRIMES
+RSA,130,NO_PUBLIC_EXPONENT
+RSA,131,NULL_BEFORE_BLOCK_MISSING
+RSA,132,N_NOT_EQUAL_P_Q
+RSA,133,OAEP_DECODING_ERROR
+RSA,134,ONLY_ONE_OF_P_Q_GIVEN
+RSA,135,OUTPUT_BUFFER_TOO_SMALL
+RSA,136,PADDING_CHECK_FAILED
+RSA,137,PKCS_DECODING_ERROR
+RSA,138,SLEN_CHECK_FAILED
+RSA,139,SLEN_RECOVERY_FAILED
+RSA,140,TOO_LONG
+RSA,141,TOO_MANY_ITERATIONS
+RSA,142,UNKNOWN_ALGORITHM_TYPE
+RSA,143,UNKNOWN_PADDING_TYPE
+RSA,144,VALUE_MISSING
+RSA,145,WRONG_SIGNATURE_LENGTH
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 3766bb9..dfe4ac8 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -108,6 +108,7 @@
 SSL,207,SERVERHELLO_TLSEXT
 SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
 SSL,209,SESSION_MAY_NOT_BE_CREATED
+SSL,250,SHUTDOWN_WHILE_IN_INIT
 SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
 SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
 SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
diff --git a/src/crypto/err/x509.errordata b/src/crypto/err/x509.errordata
index f4828ce..a1d49b7 100644
--- a/src/crypto/err/x509.errordata
+++ b/src/crypto/err/x509.errordata
@@ -10,28 +10,26 @@
 X509,109,INVALID_BIT_STRING_BITS_LEFT
 X509,110,INVALID_DIRECTORY
 X509,111,INVALID_FIELD_NAME
-X509,112,INVALID_TRUST
-X509,113,ISSUER_MISMATCH
-X509,114,KEY_TYPE_MISMATCH
-X509,115,KEY_VALUES_MISMATCH
-X509,116,LOADING_CERT_DIR
-X509,117,LOADING_DEFAULTS
-X509,118,METHOD_NOT_SUPPORTED
+X509,112,INVALID_PSS_PARAMETERS
+X509,113,INVALID_TRUST
+X509,114,ISSUER_MISMATCH
+X509,115,KEY_TYPE_MISMATCH
+X509,116,KEY_VALUES_MISMATCH
+X509,117,LOADING_CERT_DIR
+X509,118,LOADING_DEFAULTS
 X509,119,NEWER_CRL_NOT_NEWER
 X509,120,NOT_PKCS7_SIGNED_DATA
 X509,121,NO_CERTIFICATES_INCLUDED
 X509,122,NO_CERT_SET_FOR_US_TO_VERIFY
-X509,136,NO_CRLS_INCLUDED
-X509,123,NO_CRL_NUMBER
-X509,124,PUBLIC_KEY_DECODE_ERROR
-X509,125,PUBLIC_KEY_ENCODE_ERROR
-X509,126,SHOULD_RETRY
-X509,127,UNABLE_TO_FIND_PARAMETERS_IN_CHAIN
-X509,128,UNABLE_TO_GET_CERTS_PUBLIC_KEY
-X509,129,UNKNOWN_KEY_TYPE
-X509,130,UNKNOWN_NID
-X509,131,UNKNOWN_PURPOSE_ID
-X509,132,UNKNOWN_TRUST_ID
-X509,133,UNSUPPORTED_ALGORITHM
-X509,134,WRONG_LOOKUP_TYPE
-X509,135,WRONG_TYPE
+X509,123,NO_CRLS_INCLUDED
+X509,124,NO_CRL_NUMBER
+X509,125,PUBLIC_KEY_DECODE_ERROR
+X509,126,PUBLIC_KEY_ENCODE_ERROR
+X509,127,SHOULD_RETRY
+X509,128,UNKNOWN_KEY_TYPE
+X509,129,UNKNOWN_NID
+X509,130,UNKNOWN_PURPOSE_ID
+X509,131,UNKNOWN_TRUST_ID
+X509,132,UNSUPPORTED_ALGORITHM
+X509,133,WRONG_LOOKUP_TYPE
+X509,134,WRONG_TYPE
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 000f076..ca1b511 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -5,7 +5,6 @@
 
   OBJECT
 
-  algorithm.c
   digestsign.c
   evp.c
   evp_asn1.c
@@ -16,6 +15,7 @@
   p_rsa.c
   p_rsa_asn1.c
   pbkdf.c
+  print.c
   sign.c
 )
 
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index afe5c38..79993aa 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -59,12 +59,11 @@
 #include <assert.h>
 #include <string.h>
 
-#include <openssl/bio.h>
 #include <openssl/dsa.h>
 #include <openssl/ec.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rsa.h>
 #include <openssl/thread.h>
 
@@ -195,11 +194,12 @@
   return pkey->type;
 }
 
-/* TODO(fork): remove the first argument. */
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
+/* evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which
+ * should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
+ * unknown. */
+static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
   switch (nid) {
     case EVP_PKEY_RSA:
-    case EVP_PKEY_RSA2:
       return &rsa_asn1_meth;
     case EVP_PKEY_EC:
       return &ec_asn1_meth;
@@ -211,7 +211,7 @@
 }
 
 int EVP_PKEY_type(int nid) {
-  const EVP_PKEY_ASN1_METHOD *meth = EVP_PKEY_asn1_find(NULL, nid);
+  const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid);
   if (meth == NULL) {
     return NID_undef;
   }
@@ -310,19 +310,6 @@
   return key != NULL;
 }
 
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
-                                                   const char *name,
-                                                   size_t len) {
-  if (len == 3 && memcmp(name, "RSA", 3) == 0) {
-    return &rsa_asn1_meth;
-  } if (len == 2 && memcmp(name, "EC", 2) == 0) {
-    return &ec_asn1_meth;
-  } else if (len == 3 && memcmp(name, "DSA", 3) == 0) {
-    return &dsa_asn1_meth;
-  }
-  return NULL;
-}
-
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
   const EVP_PKEY_ASN1_METHOD *ameth;
 
@@ -330,10 +317,10 @@
     free_it(pkey);
   }
 
-  ameth = EVP_PKEY_asn1_find(NULL, type);
+  ameth = evp_pkey_asn1_find(type);
   if (ameth == NULL) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
-    ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type));
+    ERR_add_error_dataf("algorithm %d", type);
     return 0;
   }
 
@@ -357,41 +344,6 @@
   return -2;
 }
 
-static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
-                             const char *kstr) {
-  BIO_indent(out, indent, 128);
-  BIO_printf(out, "%s algorithm \"%s\" unsupported\n", kstr,
-             OBJ_nid2ln(pkey->type));
-  return 1;
-}
-
-int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *pctx) {
-  if (pkey->ameth && pkey->ameth->pub_print) {
-    return pkey->ameth->pub_print(out, pkey, indent, pctx);
-  }
-
-  return print_unsupported(out, pkey, indent, "Public Key");
-}
-
-int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
-                           ASN1_PCTX *pctx) {
-  if (pkey->ameth && pkey->ameth->priv_print) {
-    return pkey->ameth->priv_print(out, pkey, indent, pctx);
-  }
-
-  return print_unsupported(out, pkey, indent, "Private Key");
-}
-
-int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *pctx) {
-  if (pkey->ameth && pkey->ameth->param_print) {
-    return pkey->ameth->param_print(out, pkey, indent, pctx);
-  }
-
-  return print_unsupported(out, pkey, indent, "Parameters");
-}
-
 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
   return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
                            (void *)md);
diff --git a/src/crypto/evp/evp_asn1.c b/src/crypto/evp/evp_asn1.c
index c57f411..3681d4f 100644
--- a/src/crypto/evp/evp_asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -56,112 +56,269 @@
 
 #include <openssl/evp.h>
 
-#include <openssl/asn1.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/dsa.h>
+#include <openssl/ec_key.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
+#include <openssl/rsa.h>
 
 #include "internal.h"
 
 
-EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
-                         long len) {
-  EVP_PKEY *ret;
+static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
+    &rsa_asn1_meth,
+    &ec_asn1_meth,
+    &dsa_asn1_meth,
+};
 
-  if (out == NULL || *out == NULL) {
-    ret = EVP_PKEY_new();
-    if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
-      return NULL;
-    }
-  } else {
-    ret = *out;
+static int parse_key_type(CBS *cbs, int *out_type) {
+  CBS oid;
+  if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
+    return 0;
   }
 
-  if (!EVP_PKEY_set_type(ret, type)) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
+  unsigned i;
+  for (i = 0; i < sizeof(kASN1Methods)/sizeof(kASN1Methods[0]); i++) {
+    const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
+    if (CBS_len(&oid) == method->oid_len &&
+        memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {
+      *out_type = method->pkey_id;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
+  /* Parse the SubjectPublicKeyInfo. */
+  CBS spki, algorithm, key;
+  int type;
+  uint8_t padding;
+  if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !parse_key_type(&algorithm, &type) ||
+      !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
+      CBS_len(&spki) != 0 ||
+      /* Every key type defined encodes the key as a byte string with the same
+       * conversion to BIT STRING. */
+      !CBS_get_u8(&key, &padding) ||
+      padding != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    return NULL;
+  }
+
+  /* Set up an |EVP_PKEY| of the appropriate type. */
+  EVP_PKEY *ret = EVP_PKEY_new();
+  if (ret == NULL ||
+      !EVP_PKEY_set_type(ret, type)) {
     goto err;
   }
 
-  const uint8_t *in = *inp;
-  if (!ret->ameth->old_priv_decode ||
-      !ret->ameth->old_priv_decode(ret, &in, len)) {
-    if (ret->ameth->priv_decode) {
-      /* Reset |in| in case |old_priv_decode| advanced it on error. */
-      in = *inp;
-      PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len);
-      if (!p8) {
+  /* Call into the type-specific SPKI decoding function. */
+  if (ret->ameth->pub_decode == NULL) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+    goto err;
+  }
+  if (!ret->ameth->pub_decode(ret, &algorithm, &key)) {
+    goto err;
+  }
+
+  return ret;
+
+err:
+  EVP_PKEY_free(ret);
+  return NULL;
+}
+
+int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
+  if (key->ameth == NULL || key->ameth->pub_encode == NULL) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+    return 0;
+  }
+
+  return key->ameth->pub_encode(cbb, key);
+}
+
+EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
+  /* Parse the PrivateKeyInfo. */
+  CBS pkcs8, algorithm, key;
+  uint64_t version;
+  int type;
+  if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
+      !CBS_get_asn1_uint64(&pkcs8, &version) ||
+      version != 0 ||
+      !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !parse_key_type(&algorithm, &type) ||
+      !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    return NULL;
+  }
+
+  /* A PrivateKeyInfo ends with a SET of Attributes which we ignore. */
+
+  /* Set up an |EVP_PKEY| of the appropriate type. */
+  EVP_PKEY *ret = EVP_PKEY_new();
+  if (ret == NULL ||
+      !EVP_PKEY_set_type(ret, type)) {
+    goto err;
+  }
+
+  /* Call into the type-specific PrivateKeyInfo decoding function. */
+  if (ret->ameth->priv_decode == NULL) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+    goto err;
+  }
+  if (!ret->ameth->priv_decode(ret, &algorithm, &key)) {
+    goto err;
+  }
+
+  return ret;
+
+err:
+  EVP_PKEY_free(ret);
+  return NULL;
+}
+
+int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
+  if (key->ameth == NULL || key->ameth->priv_encode == NULL) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+    return 0;
+  }
+
+  return key->ameth->priv_encode(cbb, key);
+}
+
+static EVP_PKEY *old_priv_decode(CBS *cbs, int type) {
+  EVP_PKEY *ret = EVP_PKEY_new();
+  if (ret == NULL) {
+    return NULL;
+  }
+
+  switch (type) {
+    case EVP_PKEY_EC: {
+      EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL);
+      if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) {
+        EC_KEY_free(ec_key);
         goto err;
       }
-      EVP_PKEY_free(ret);
-      ret = EVP_PKCS82PKEY(p8);
-      PKCS8_PRIV_KEY_INFO_free(p8);
-      if (ret == NULL) {
+      return ret;
+    }
+    case EVP_PKEY_DSA: {
+      DSA *dsa = DSA_parse_private_key(cbs);
+      if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) {
+        DSA_free(dsa);
         goto err;
       }
-    } else {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
+      return ret;
+    }
+    case EVP_PKEY_RSA: {
+      RSA *rsa = RSA_parse_private_key(cbs);
+      if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) {
+        RSA_free(rsa);
+        goto err;
+      }
+      return ret;
+    }
+    default:
+      OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
       goto err;
+  }
+
+err:
+  EVP_PKEY_free(ret);
+  return NULL;
+}
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
+                         long len) {
+  if (len < 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    return NULL;
+  }
+
+  /* Parse with the legacy format. */
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  EVP_PKEY *ret = old_priv_decode(&cbs, type);
+  if (ret == NULL) {
+    /* Try again with PKCS#8. */
+    ERR_clear_error();
+    CBS_init(&cbs, *inp, (size_t)len);
+    ret = EVP_parse_private_key(&cbs);
+    if (ret == NULL) {
+      return NULL;
+    }
+    if (ret->type != type) {
+      OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
+      EVP_PKEY_free(ret);
+      return NULL;
     }
   }
 
   if (out != NULL) {
+    EVP_PKEY_free(*out);
     *out = ret;
   }
-  *inp = in;
+  *inp = CBS_data(&cbs);
   return ret;
+}
 
-err:
-  if (out == NULL || *out != ret) {
-    EVP_PKEY_free(ret);
+/* num_elements parses one SEQUENCE from |in| and returns the number of elements
+ * in it. On parse error, it returns zero. */
+static size_t num_elements(const uint8_t *in, size_t in_len) {
+  CBS cbs, sequence;
+  CBS_init(&cbs, in, (size_t)in_len);
+
+  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) {
+    return 0;
   }
-  return NULL;
+
+  size_t count = 0;
+  while (CBS_len(&sequence) > 0) {
+    if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) {
+      return 0;
+    }
+
+    count++;
+  }
+
+  return count;
 }
 
 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
-  STACK_OF(ASN1_TYPE) *inkey;
-  const uint8_t *p;
-  int keytype;
-  p = *inp;
-
-  /* Dirty trick: read in the ASN1 data into out STACK_OF(ASN1_TYPE):
-   * by analyzing it we can determine the passed structure: this
-   * assumes the input is surrounded by an ASN1 SEQUENCE. */
-  inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, len);
-  /* Since we only need to discern "traditional format" RSA and DSA
-   * keys we can just count the elements. */
-  if (sk_ASN1_TYPE_num(inkey) == 6) {
-    keytype = EVP_PKEY_DSA;
-  } else if (sk_ASN1_TYPE_num(inkey) == 4) {
-    keytype = EVP_PKEY_EC;
-  } else if (sk_ASN1_TYPE_num(inkey) == 3) {
-    /* This seems to be PKCS8, not traditional format */
-    p = *inp;
-    PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
-    EVP_PKEY *ret;
-
-    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
-    if (!p8) {
-      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
-      return NULL;
-    }
-    ret = EVP_PKCS82PKEY(p8);
-    PKCS8_PRIV_KEY_INFO_free(p8);
-    if (ret == NULL) {
-      return NULL;
-    }
-
-    *inp = p;
-    if (out) {
-      *out = ret;
-    }
-    return ret;
-  } else {
-    keytype = EVP_PKEY_RSA;
+  if (len < 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    return NULL;
   }
 
-  sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
-  return d2i_PrivateKey(keytype, out, inp, len);
+  /* Parse the input as a PKCS#8 PrivateKeyInfo. */
+  CBS cbs;
+  CBS_init(&cbs, *inp, (size_t)len);
+  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
+  if (ret != NULL) {
+    if (out != NULL) {
+      EVP_PKEY_free(*out);
+      *out = ret;
+    }
+    *inp = CBS_data(&cbs);
+    return ret;
+  }
+  ERR_clear_error();
+
+  /* Count the elements to determine the legacy key format. */
+  switch (num_elements(*inp, (size_t)len)) {
+    case 4:
+      return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
+
+    case 6:
+      return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len);
+
+    default:
+      return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len);
+  }
 }
 
 int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) {
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index 9e038cd..f510f6c 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -56,12 +56,10 @@
 
 #include <openssl/evp.h>
 
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 
 #include "internal.h"
 
@@ -98,8 +96,7 @@
 
   if (pmeth == NULL) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
-    const char *name = OBJ_nid2sn(id);
-    ERR_add_error_dataf("algorithm %d (%s)", id, name);
+    ERR_add_error_dataf("algorithm %d", id);
     return NULL;
   }
 
@@ -193,12 +190,6 @@
 
 EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; }
 
-void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) {
-  ctx->app_data = data;
-}
-
-void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; }
-
 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
                       int p1, void *p2) {
   if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
@@ -229,15 +220,6 @@
   }
 
   ctx->operation = EVP_PKEY_OP_SIGN;
-  if (!ctx->pmeth->sign_init) {
-    return 1;
-  }
-
-  if (!ctx->pmeth->sign_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
-
   return 1;
 }
 
@@ -260,14 +242,6 @@
     return 0;
   }
   ctx->operation = EVP_PKEY_OP_VERIFY;
-  if (!ctx->pmeth->verify_init) {
-    return 1;
-  }
-  if (!ctx->pmeth->verify_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
-
   return 1;
 }
 
@@ -290,13 +264,6 @@
     return 0;
   }
   ctx->operation = EVP_PKEY_OP_ENCRYPT;
-  if (!ctx->pmeth->encrypt_init) {
-    return 1;
-  }
-  if (!ctx->pmeth->encrypt_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
   return 1;
 }
 
@@ -319,13 +286,6 @@
     return 0;
   }
   ctx->operation = EVP_PKEY_OP_DECRYPT;
-  if (!ctx->pmeth->decrypt_init) {
-    return 1;
-  }
-  if (!ctx->pmeth->decrypt_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
   return 1;
 }
 
@@ -342,19 +302,34 @@
   return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
 }
 
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) {
+  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+    return 0;
+  }
+  ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+  return 1;
+}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
+                            const uint8_t *sig, size_t sig_len) {
+  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+    return 0;
+  }
+  if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
+    return 0;
+  }
+  return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len);
+}
+
 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
   if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
   ctx->operation = EVP_PKEY_OP_DERIVE;
-  if (!ctx->pmeth->derive_init) {
-    return 1;
-  }
-  if (!ctx->pmeth->derive_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
   return 1;
 }
 
@@ -436,13 +411,6 @@
     return 0;
   }
   ctx->operation = EVP_PKEY_OP_KEYGEN;
-  if (!ctx->pmeth->keygen_init) {
-    return 1;
-  }
-  if (!ctx->pmeth->keygen_init(ctx)) {
-    ctx->operation = EVP_PKEY_OP_UNDEFINED;
-    return 0;
-  }
   return 1;
 }
 
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index fe7a002..9bc36ad 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -15,6 +15,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <utility>
 #include <vector>
@@ -25,7 +26,6 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/rsa.h>
-#include <openssl/x509.h>
 
 #include "../test/scoped_types.h"
 
@@ -177,142 +177,6 @@
     0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42,
 };
 
-// kExamplePSSCert is an example self-signed certificate, signed with
-// kExampleRSAKeyDER using RSA-PSS with default hash functions.
-static const uint8_t kExamplePSSCert[] = {
-    0x30, 0x82, 0x02, 0x62, 0x30, 0x82, 0x01, 0xc6, 0xa0, 0x03, 0x02, 0x01,
-    0x02, 0x02, 0x09, 0x00, 0x8d, 0xea, 0x53, 0x24, 0xfa, 0x48, 0x87, 0xf3,
-    0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-    0x0a, 0x30, 0x05, 0xa2, 0x03, 0x02, 0x01, 0x6a, 0x30, 0x45, 0x31, 0x0b,
-    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31,
-    0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f,
-    0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f,
-    0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
-    0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20,
-    0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31,
-    0x34, 0x31, 0x30, 0x30, 0x39, 0x31, 0x39, 0x30, 0x39, 0x35, 0x35, 0x5a,
-    0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x30, 0x39, 0x31, 0x39, 0x30, 0x39,
-    0x35, 0x35, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-    0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
-    0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
-    0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
-    0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
-    0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
-    0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
-    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
-    0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4,
-    0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59, 0x76, 0x8c, 0x54, 0x1d,
-    0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e, 0xd3, 0x37, 0xeb, 0x41, 0xfd, 0x83,
-    0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34, 0x75, 0x71, 0x5a, 0x84, 0xa8, 0x3c,
-    0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde, 0x97, 0x8a, 0xdd, 0xff, 0xbb, 0xcf,
-    0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8, 0x50, 0xe4, 0xcd, 0x6f, 0x80, 0x33,
-    0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b, 0xdc, 0xec, 0x5a, 0xca, 0x63, 0xc7,
-    0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83, 0x58, 0x76, 0x20, 0xfa, 0x16, 0x77,
-    0xd7, 0x79, 0x92, 0x63, 0x01, 0x48, 0x1a, 0xd8, 0x7b, 0x67, 0xf1, 0x52,
-    0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a, 0x5c, 0xd7, 0x7a, 0x37, 0x36, 0x0c,
-    0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2, 0xa7, 0x2c, 0x2b, 0xb5, 0xaf, 0x64,
-    0x4b, 0x61, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e,
-    0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd0,
-    0x41, 0xfb, 0x89, 0x41, 0x1e, 0xa7, 0xad, 0x5a, 0xec, 0x34, 0x5d, 0x49,
-    0x11, 0xf9, 0x55, 0x81, 0x78, 0x1f, 0x13, 0x30, 0x1f, 0x06, 0x03, 0x55,
-    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd0, 0x41, 0xfb, 0x89,
-    0x41, 0x1e, 0xa7, 0xad, 0x5a, 0xec, 0x34, 0x5d, 0x49, 0x11, 0xf9, 0x55,
-    0x81, 0x78, 0x1f, 0x13, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
-    0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86,
-    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x05, 0xa2, 0x03, 0x02,
-    0x01, 0x6a, 0x03, 0x81, 0x81, 0x00, 0x49, 0x4c, 0xb6, 0x45, 0x97, 0x20,
-    0x35, 0xb3, 0x50, 0x64, 0x0d, 0x3f, 0xec, 0x5f, 0x95, 0xd5, 0x84, 0xcb,
-    0x11, 0x7c, 0x03, 0xd7, 0xa6, 0xe6, 0xfa, 0x24, 0x95, 0x9f, 0x31, 0xb0,
-    0xb5, 0xec, 0x66, 0x41, 0x51, 0x18, 0x21, 0x91, 0xbb, 0xe0, 0xaf, 0xf0,
-    0xc5, 0xb7, 0x59, 0x41, 0xd4, 0xdb, 0xa4, 0xd2, 0x64, 0xa7, 0x54, 0x0f,
-    0x8c, 0xf7, 0xe1, 0xd3, 0x3b, 0x1a, 0xb7, 0x0e, 0x9d, 0x9a, 0xde, 0x50,
-    0xa1, 0x9f, 0x0a, 0xf0, 0xda, 0x34, 0x0e, 0x34, 0x7d, 0x76, 0x07, 0xfe,
-    0x5a, 0xfb, 0xf9, 0x58, 0x9b, 0xc9, 0x50, 0x84, 0x01, 0xa0, 0x05, 0x4d,
-    0x67, 0x42, 0x0b, 0xf8, 0xe4, 0x05, 0xcf, 0xaf, 0x8b, 0x71, 0x31, 0xf1,
-    0x0f, 0x6e, 0xc9, 0x24, 0x27, 0x9b, 0xac, 0x04, 0xd7, 0x64, 0x0d, 0x30,
-    0x4e, 0x11, 0x93, 0x40, 0x39, 0xbb, 0x72, 0xb2, 0xfe, 0x6b, 0xe4, 0xae,
-    0x8c, 0x16,
-};
-
-// kBadPSSCert is an example RSA-PSS certificate with bad parameters.
-static const uint8_t kBadPSSCert[] = {
-    0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01,
-    0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3,
-    0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-    0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48,
-    0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09,
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06,
-    0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04,
-    0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
-    0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
-    0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65,
-    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17,
-    0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33,
-    0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36,
-    0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06,
-    0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49,
-    0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63,
-    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82,
-    0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
-    0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87,
-    0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef,
-    0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c,
-    0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1,
-    0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb,
-    0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f,
-    0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0,
-    0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86,
-    0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3,
-    0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa,
-    0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4,
-    0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51,
-    0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4,
-    0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e,
-    0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18,
-    0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46,
-    0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a,
-    0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad,
-    0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62,
-    0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9,
-    0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda,
-    0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02,
-    0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03,
-    0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78,
-    0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6,
-    0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
-    0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d,
-    0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b,
-    0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
-    0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-    0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
-    0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b,
-    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2,
-    0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1,
-    0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf,
-    0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6,
-    0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb,
-    0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f,
-    0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09,
-    0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80,
-    0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7,
-    0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9,
-    0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca,
-    0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d,
-    0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98,
-    0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca,
-    0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a,
-    0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21,
-    0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69,
-    0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49,
-    0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1,
-    0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b,
-    0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59,
-    0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80,
-    0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b,
-    0x68, 0x9f,
-};
-
 // kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
 // PrivateKeyInfo.
 static const uint8_t kExampleRSAKeyPKCS8[] = {
@@ -387,6 +251,61 @@
     0xc1,
 };
 
+// kExampleECKeyPKCS8 is a sample EC private key encoded as a PKCS#8
+// PrivateKeyInfo.
+static const uint8_t kExampleECKeyPKCS8[] = {
+    0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
+    0x43, 0x09, 0xc0, 0x67, 0x75, 0x21, 0x47, 0x9d, 0xa8, 0xfa, 0x16, 0xdf,
+    0x15, 0x73, 0x61, 0x34, 0x68, 0x6f, 0xe3, 0x8e, 0x47, 0x91, 0x95, 0xab,
+    0x79, 0x4a, 0x72, 0x14, 0xcb, 0xe2, 0x49, 0x4f, 0xa1, 0x44, 0x03, 0x42,
+    0x00, 0x04, 0xde, 0x09, 0x08, 0x07, 0x03, 0x2e, 0x8f, 0x37, 0x9a, 0xd5,
+    0xad, 0xe5, 0xc6, 0x9d, 0xd4, 0x63, 0xc7, 0x4a, 0xe7, 0x20, 0xcb, 0x90,
+    0xa0, 0x1f, 0x18, 0x18, 0x72, 0xb5, 0x21, 0x88, 0x38, 0xc0, 0xdb, 0xba,
+    0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9, 0xe3, 0xd5, 0x61, 0x99, 0x73,
+    0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40, 0x41, 0x3b, 0x0d, 0x10, 0xa7,
+    0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec,
+};
+
+// kExampleECKeySpecifiedCurvePKCS8 is a sample EC private key encoded as a
+// PKCS#8 PrivateKeyInfo with P-256's parameters spelled out rather than using
+// the curve OID.
+static const uint8_t kExampleECKeySpecifiedCurvePKCS8[] = {
+    0x30, 0x82, 0x01, 0x79, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x03, 0x06,
+    0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x30, 0x81, 0xf7, 0x02,
+    0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
+    0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+    0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
+    0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+    0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
+    0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
+    0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
+    0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
+    0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+    0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
+    0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+    0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+    0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
+    0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
+    0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
+    0x63, 0x25, 0x51, 0x02, 0x01, 0x01, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01,
+    0x01, 0x04, 0x20, 0x43, 0x09, 0xc0, 0x67, 0x75, 0x21, 0x47, 0x9d, 0xa8,
+    0xfa, 0x16, 0xdf, 0x15, 0x73, 0x61, 0x34, 0x68, 0x6f, 0xe3, 0x8e, 0x47,
+    0x91, 0x95, 0xab, 0x79, 0x4a, 0x72, 0x14, 0xcb, 0xe2, 0x49, 0x4f, 0xa1,
+    0x44, 0x03, 0x42, 0x00, 0x04, 0xde, 0x09, 0x08, 0x07, 0x03, 0x2e, 0x8f,
+    0x37, 0x9a, 0xd5, 0xad, 0xe5, 0xc6, 0x9d, 0xd4, 0x63, 0xc7, 0x4a, 0xe7,
+    0x20, 0xcb, 0x90, 0xa0, 0x1f, 0x18, 0x18, 0x72, 0xb5, 0x21, 0x88, 0x38,
+    0xc0, 0xdb, 0xba, 0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9, 0xe3, 0xd5,
+    0x61, 0x99, 0x73, 0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40, 0x41, 0x3b,
+    0x0d, 0x10, 0xa7, 0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec,
+};
+
 // kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
 // structure. The private key is equal to the order and will fail to import.
 static const uint8_t kExampleBadECKeyDER[] = {
@@ -502,179 +421,81 @@
   return true;
 }
 
-// TestAlgorithmRoundtrip signs a message using an already-initialized
-// |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the
-// AlgorithmIdentifier to verify the signature.
-static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
-  if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) {
-    return false;
-  }
-
-  // Save the algorithm.
-  ScopedX509_ALGOR algor(X509_ALGOR_new());
-  if (!algor || !EVP_DigestSignAlgorithm(md_ctx, algor.get())) {
-    return false;
-  }
-
-  // Determine the size of the signature.
-  size_t sig_len = 0;
-  if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) {
-    return false;
-  }
-  // Sanity check for testing.
-  if (sig_len != (size_t)EVP_PKEY_size(pkey)) {
-    fprintf(stderr, "sig_len mismatch\n");
-    return false;
-  }
-
-  std::vector<uint8_t> sig;
-  sig.resize(sig_len);
-  if (!EVP_DigestSignFinal(md_ctx, sig.data(), &sig_len)) {
-    return false;
-  }
-  sig.resize(sig_len);
-
-  // Ensure that the signature round-trips.
-  ScopedEVP_MD_CTX md_ctx_verify;
-  if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(),
-                                         pkey) ||
-      !EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) ||
-      !EVP_DigestVerifyFinal(md_ctx_verify.get(), sig.data(), sig_len)) {
-    return false;
-  }
-
-  return true;
-}
-
-static bool TestEVP_DigestSignAlgorithm(void) {
+static bool TestVerifyRecover() {
   ScopedEVP_PKEY pkey = LoadExampleRSAKey();
-
-  // Test a simple AlgorithmIdentifier.
-  ScopedEVP_MD_CTX md_ctx;
-  if (!pkey ||
-      !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
-      !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
-    fprintf(stderr, "RSA with SHA-256 failed\n");
+  if (!pkey) {
     return false;
   }
 
-  // Test RSA-PSS with custom parameters.
-  md_ctx.Reset();
-  EVP_PKEY_CTX *pkey_ctx;
-  if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
-                          pkey.get()) ||
-      !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
-      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
-      !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
-    fprintf(stderr, "RSA-PSS failed\n");
+  ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
+  if (!rsa) {
     return false;
   }
 
-  return true;
-}
+  const uint8_t kDummyHash[32] = {0};
+  uint8_t sig[2048/8];
+  unsigned sig_len = sizeof(sig);
 
-static bool ParseCertificate(CBS *out_tbs_cert,
-                             ScopedEVP_PKEY *out_pubkey,
-                             ScopedX509_ALGOR *out_algor,
-                             CBS *out_signature,
-                             const CBS *in_) {
-  CBS in = *in_;
-  CBS cert_body, tbs_cert, algorithm, signature;
-  if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) ||
-      CBS_len(&in) != 0 ||
-      !CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) ||
-      !CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
-      CBS_len(&cert_body) != 0) {
+  if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, &sig_len,
+                rsa.get())) {
+    fprintf(stderr, "RSA_sign failed.\n");
+    ERR_print_errors_fp(stderr);
     return false;
   }
 
-  CBS tbs_cert_copy = tbs_cert;
-  CBS tbs_cert_body, discard, spki;
-  if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) ||
-      CBS_len(&tbs_cert_copy) != 0 ||
-      !CBS_get_optional_asn1(
-          &tbs_cert_body, &discard, NULL,
-          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
-      !CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */,
-                    CBS_ASN1_INTEGER) ||
-      !CBS_get_asn1(&tbs_cert_body, &discard /* signature */,
-                    CBS_ASN1_SEQUENCE) ||
-      !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */,
-                                NULL, NULL) ||
-      !CBS_get_asn1(&tbs_cert_body, &discard /* validity */,
-                    CBS_ASN1_SEQUENCE) ||
-      !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */,
-                                NULL, NULL) ||
-      !CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) {
+  size_t out_len;
+  ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
+  if (!EVP_PKEY_verify_recover_init(ctx.get()) ||
+      !EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) ||
+      !EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) ||
+      !EVP_PKEY_verify_recover(ctx.get(), nullptr, &out_len, sig, sig_len)) {
+    fprintf(stderr, "verify_recover failed will nullptr buffer.\n");
+    ERR_print_errors_fp(stderr);
     return false;
   }
 
-  const uint8_t *derp = CBS_data(&spki);
-  ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki)));
-  if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) {
+  std::vector<uint8_t> recovered;
+  recovered.resize(out_len);
+
+  if (!EVP_PKEY_verify_recover(ctx.get(), recovered.data(), &out_len, sig,
+                               sig_len)) {
+    fprintf(stderr, "verify_recover failed.\n");
+    ERR_print_errors_fp(stderr);
     return false;
   }
 
-  derp = CBS_data(&algorithm);
-  ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
-  if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
+  if (out_len != sizeof(kDummyHash)) {
+    fprintf(stderr, "verify_recover length is %u, expected %u.\n",
+            static_cast<unsigned>(out_len),
+            static_cast<unsigned>(sizeof(kDummyHash)));
     return false;
   }
 
-  // Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the
-  // leading phase byte is just a zero.
-  uint8_t padding;
-  if (!CBS_get_u8(&signature, &padding) || padding != 0) {
+  if (memcmp(recovered.data(), kDummyHash, sizeof(kDummyHash)) != 0) {
+    fprintf(stderr, "verify_recover got wrong value.\n");
+    ERR_print_errors_fp(stderr);
     return false;
   }
 
-  *out_tbs_cert = tbs_cert;
-  *out_pubkey = std::move(pubkey);
-  *out_algor = std::move(algor);
-  *out_signature = signature;
-  return true;
-}
-
-static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
-  CBS in, tbs_cert, signature;
-  ScopedEVP_PKEY pkey;
-  ScopedX509_ALGOR algor;
-  CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert));
-  if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
-    fprintf(stderr, "Failed to parse certificate\n");
+  out_len = recovered.size();
+  if (!EVP_PKEY_CTX_set_signature_md(ctx.get(), nullptr) ||
+      !EVP_PKEY_verify_recover(ctx.get(), recovered.data(), &out_len, sig,
+                               sig_len)) {
+    fprintf(stderr, "verify_recover failed with NULL MD.\n");
+    ERR_print_errors_fp(stderr);
     return false;
   }
 
-  ScopedEVP_MD_CTX md_ctx;
-  if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
-                                         pkey.get()) ||
-      !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
-                              CBS_len(&tbs_cert)) ||
-      !EVP_DigestVerifyFinal(md_ctx.get(), CBS_data(&signature),
-                             CBS_len(&signature))) {
-    return false;
-  }
-  return true;
-}
-
-static bool TestBadPSSParameters(void) {
-  CBS in, tbs_cert, signature;
-  ScopedEVP_PKEY pkey;
-  ScopedX509_ALGOR algor;
-  CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert));
-  if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
-    fprintf(stderr, "Failed to parse certificate\n");
+  /* The size of a SHA-256 hash plus PKCS#1 v1.5 ASN.1 stuff happens to be 51
+   * bytes. */
+  static const size_t kExpectedASN1Size = 51;
+  if (out_len != kExpectedASN1Size) {
+    fprintf(stderr, "verify_recover length without MD is %u, expected %u.\n",
+            static_cast<unsigned>(out_len),
+            static_cast<unsigned>(kExpectedASN1Size));
     return false;
   }
 
-  ScopedEVP_MD_CTX md_ctx;
-  if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
-                                        pkey.get())) {
-    fprintf(stderr, "Unexpectedly processed bad signature parameters\n");
-    return false;
-  }
-  ERR_clear_error();
   return true;
 }
 
@@ -714,6 +535,20 @@
     return false;
   }
 
+  if (!TestValidPrivateKey(kExampleECKeyPKCS8, sizeof(kExampleECKeyPKCS8),
+                           EVP_PKEY_EC)) {
+    fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyPKCS8) failed\n");
+    return false;
+  }
+
+  if (!TestValidPrivateKey(kExampleECKeySpecifiedCurvePKCS8,
+                           sizeof(kExampleECKeySpecifiedCurvePKCS8),
+                           EVP_PKEY_EC)) {
+    fprintf(stderr,
+            "d2i_AutoPrivateKey(kExampleECKeySpecifiedCurvePKCS8) failed\n");
+    return false;
+  }
+
   if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
                            EVP_PKEY_DSA)) {
     fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
@@ -751,6 +586,25 @@
   return true;
 }
 
+// TestEVPMarshalEmptyPublicKey tests |EVP_marshal_public_key| on an empty key.
+static bool TestEVPMarshalEmptyPublicKey(void) {
+  ScopedEVP_PKEY empty(EVP_PKEY_new());
+  if (!empty) {
+    return false;
+  }
+  ScopedCBB cbb;
+  if (EVP_marshal_public_key(cbb.get(), empty.get())) {
+    fprintf(stderr, "Marshalled empty public key.\n");
+    return false;
+  }
+  if (ERR_GET_REASON(ERR_peek_last_error()) != EVP_R_UNSUPPORTED_ALGORITHM) {
+    fprintf(stderr, "Marshalling an empty public key gave wrong error.\n");
+    return false;
+  }
+  ERR_clear_error();
+  return true;
+}
+
 // Testd2i_PrivateKey tests |d2i_PrivateKey|.
 static bool Testd2i_PrivateKey(void) {
   const uint8_t *derp = kExampleRSAKeyDER;
@@ -805,12 +659,20 @@
   }
   ERR_clear_error();
 
+  derp = kExampleRSAKeyPKCS8;
+  pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+             sizeof(kExampleRSAKeyPKCS8)));
+  if (pkey) {
+    fprintf(stderr, "Imported RSA key as EC key.\n");
+    return false;
+  }
+  ERR_clear_error();
+
   return true;
 }
 
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!TestEVP_DigestSignInit()) {
     fprintf(stderr, "EVP_DigestSignInit failed\n");
@@ -824,20 +686,8 @@
     return 1;
   }
 
-  if (!TestEVP_DigestSignAlgorithm()) {
-    fprintf(stderr, "EVP_DigestSignInit failed\n");
-    ERR_print_errors_fp(stderr);
-    return 1;
-  }
-
-  if (!TestEVP_DigestVerifyInitFromAlgorithm()) {
-    fprintf(stderr, "EVP_DigestVerifyInitFromAlgorithm failed\n");
-    ERR_print_errors_fp(stderr);
-    return 1;
-  }
-
-  if (!TestBadPSSParameters()) {
-    fprintf(stderr, "TestBadPSSParameters failed\n");
+  if (!TestVerifyRecover()) {
+    fprintf(stderr, "EVP_PKEY_verify_recover failed\n");
     ERR_print_errors_fp(stderr);
     return 1;
   }
@@ -854,6 +704,12 @@
     return 1;
   }
 
+  if (!TestEVPMarshalEmptyPublicKey()) {
+    fprintf(stderr, "TestEVPMarshalEmptyPublicKey failed\n");
+    ERR_print_errors_fp(stderr);
+    return 1;
+  }
+
   if (!Testd2i_PrivateKey()) {
     fprintf(stderr, "Testd2i_PrivateKey failed\n");
     ERR_print_errors_fp(stderr);
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index 7fedc15..a7dac2b 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -63,18 +63,18 @@
 
 #include <map>
 #include <string>
+#include <utility>
 #include <vector>
 
 #if defined(_MSC_VER)
 #pragma warning(pop)
 #endif
 
-#include <openssl/bio.h>
+#include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
-#include <openssl/pem.h>
 
 #include "../test/file_test.h"
 #include "../test/scoped_types.h"
@@ -103,34 +103,86 @@
   return nullptr;
 }
 
-using KeyMap = std::map<std::string, EVP_PKEY*>;
+static int GetKeyType(FileTest *t, const std::string &name) {
+  if (name == "RSA") {
+    return EVP_PKEY_RSA;
+  }
+  if (name == "EC") {
+    return EVP_PKEY_EC;
+  }
+  if (name == "DSA") {
+    return EVP_PKEY_DSA;
+  }
+  t->PrintLine("Unknown key type: '%s'", name.c_str());
+  return EVP_PKEY_NONE;
+}
 
-// ImportPrivateKey evaluates a PrivateKey test in |t| and writes the resulting
-// private key to |key_map|.
-static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) {
+using KeyMap = std::map<std::string, ScopedEVP_PKEY>;
+
+static bool ImportKey(FileTest *t, KeyMap *key_map,
+                      EVP_PKEY *(*parse_func)(CBS *cbs),
+                      int (*marshal_func)(CBB *cbb, const EVP_PKEY *key)) {
+  std::vector<uint8_t> input;
+  if (!t->GetBytes(&input, "Input")) {
+    return false;
+  }
+
+  CBS cbs;
+  CBS_init(&cbs, input.data(), input.size());
+  ScopedEVP_PKEY pkey(parse_func(&cbs));
+  if (!pkey) {
+    return false;
+  }
+
+  std::string key_type;
+  if (!t->GetAttribute(&key_type, "Type")) {
+    return false;
+  }
+  if (EVP_PKEY_id(pkey.get()) != GetKeyType(t, key_type)) {
+    t->PrintLine("Bad key type.");
+    return false;
+  }
+
+  // The key must re-encode correctly.
+  ScopedCBB cbb;
+  uint8_t *der;
+  size_t der_len;
+  if (!CBB_init(cbb.get(), 0) ||
+      !marshal_func(cbb.get(), pkey.get()) ||
+      !CBB_finish(cbb.get(), &der, &der_len)) {
+    return false;
+  }
+  ScopedOpenSSLBytes free_der(der);
+
+  std::vector<uint8_t> output = input;
+  if (t->HasAttribute("Output") &&
+      !t->GetBytes(&output, "Output")) {
+    return false;
+  }
+  if (!t->ExpectBytesEqual(output.data(), output.size(), der, der_len)) {
+    t->PrintLine("Re-encoding the key did not match.");
+    return false;
+  }
+
+  // Save the key for future tests.
   const std::string &key_name = t->GetParameter();
   if (key_map->count(key_name) > 0) {
     t->PrintLine("Duplicate key '%s'.", key_name.c_str());
     return false;
   }
-  const std::string &block = t->GetBlock();
-  ScopedBIO bio(BIO_new_mem_buf(const_cast<char*>(block.data()), block.size()));
-  if (!bio) {
-    return false;
-  }
-  ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, 0, nullptr));
-  if (!pkey) {
-    t->PrintLine("Error reading private key.");
-    return false;
-  }
-  (*key_map)[key_name] = pkey.release();
+  (*key_map)[key_name] = std::move(pkey);
   return true;
 }
 
 static bool TestEVP(FileTest *t, void *arg) {
   KeyMap *key_map = reinterpret_cast<KeyMap*>(arg);
   if (t->GetType() == "PrivateKey") {
-    return ImportPrivateKey(t, key_map);
+    return ImportKey(t, key_map, EVP_parse_private_key,
+                     EVP_marshal_private_key);
+  }
+
+  if (t->GetType() == "PublicKey") {
+    return ImportKey(t, key_map, EVP_parse_public_key, EVP_marshal_public_key);
   }
 
   int (*key_op_init)(EVP_PKEY_CTX *ctx);
@@ -156,7 +208,7 @@
     t->PrintLine("Could not find key '%s'.", key_name.c_str());
     return false;
   }
-  EVP_PKEY *key = (*key_map)[key_name];
+  EVP_PKEY *key = (*key_map)[key_name].get();
 
   std::vector<uint8_t> input, output;
   if (!t->GetBytes(&input, "Input") ||
@@ -212,11 +264,5 @@
   }
 
   KeyMap map;
-  int ret = FileTestMain(TestEVP, &map, argv[1]);
-  // TODO(davidben): When we can rely on a move-aware std::map, make KeyMap a
-  // map of ScopedEVP_PKEY instead.
-  for (const auto &pair : map) {
-    EVP_PKEY_free(pair.second);
-  }
-  return ret;
+  return FileTestMain(TestEVP, &map, argv[1]);
 }
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index 97ddaa0..7c316d8 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -1,47 +1,79 @@
 # Public key algorithm tests
 
-# Private keys used for PKEY operations.
+# Keys used for PKEY operations.
 
 # RSA 2048 bit key.
-
 PrivateKey = RSA-2048
------BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV
-n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW
-B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP
-6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr
-LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7
-yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt
-A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X
-ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS
-IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W
-glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo
-qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC
-XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe
-hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv
-6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK
-hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY
-eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A
-RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg
-T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR
-2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK
-HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ
-qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg
-esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq
-IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7
-aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu
-SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH
-fMkTd7GabVourqIZdgvu1Q==
------END PRIVATE KEY-----
+Type = RSA
+Input = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5
+
+# The public half of the same key encoded as a SubjectPublicKeyInfo.
+PublicKey = RSA-2048-SPKI
+Type = RSA
+Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+
+# The same key but with missing parameters rather than a NULL.
+PublicKey = RSA-2048-SPKI-Invalid
+Input = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+Error = DECODE_ERROR
+
+# The same key but with an incorrectly-encoded length prefix.
+PublicKey = RSA-2048-SPKI-Invalid2
+Input = 3083000122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+Error = DECODE_ERROR
 
 # EC P-256 key
-
 PrivateKey = P-256
------BEGIN PRIVATE KEY-----
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiocvtiiTxNH/xbnw
-+RdYBp+DUuCPoFpJ+NuSbLVyhyWhRANCAAQsFQ9CnOcPIWwlLPXgYs4fY5zV0WXH
-+JQkBywnGX14szuSDpXNtmTpkNzwz+oNlOKo5q+dDlgFbmUxBJJbn+bJ
------END PRIVATE KEY-----
+Type = EC
+Input = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same key as above with the optional public key omitted.
+PrivateKey = P-256-MissingPublic
+Type = EC
+Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725
+
+# The same key as above with redundant parameters.
+PrivateKey = P-256-ExtraParameters
+Type = EC
+Input = 308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00a06082a8648ce3d030107a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+# The key re-encodes with the parameters removed.
+Output = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same key, but with the redundant parameters in the ECPrivateKey mismatched.
+PrivateKey = P-256-BadInnerParameters
+Input = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = GROUP_MISMATCH
+
+# The public half of the same key encoded as a PublicKey.
+PublicKey = P-256-SPKI
+Type = EC
+Input = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same as above, but with the curve explicitly spelled out.
+PublicKey = P-256-SPKI
+Input = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = DECODE_ERROR
+
+# The same as above, but with trailing data after the curve name.
+PublicKey = P-256-SPKI
+Input = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = DECODE_ERROR
+
+# A DSA private key.
+PrivateKey = DSA-1024
+Type = DSA
+Input = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e
+
+# A DSA public key.
+PublicKey = DSA-1024-SPKI
+Type = DSA
+Input = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc5598303818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a
+
+# The same key as above, but without the parameters.
+PublicKey = DSA-1024-SPKI-No-Params
+Type = DSA
+Input = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a
+
 
 # RSA tests
 
@@ -55,6 +87,11 @@
 Input = "0123456789ABCDEF1234"
 Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
 
+Verify = RSA-2048-SPKI
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+
 # Digest too long
 Sign = RSA-2048
 Digest = SHA1
@@ -125,6 +162,11 @@
 Input = "0123456789ABCDEF1234"
 Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
 
+Verify = P-256-SPKI
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+
 # Digest too long
 Verify = P-256
 Digest = SHA1
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index aa52d53..0783143 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -59,47 +59,42 @@
 
 #include <openssl/base.h>
 
+#include <openssl/rsa.h>
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 
-/* These values are flags for EVP_PKEY_ASN1_METHOD.flags. */
-
-/* ASN1_PKEY_SIGPARAM_NULL controls whether the default behavior of
- * EVP_DigestSignAlgorithm writes an explicit NULL parameter in the
- * AlgorithmIdentifier. */
-#define ASN1_PKEY_SIGPARAM_NULL 0x1
-
-/* evp_digest_sign_algorithm_result_t is the return value of the
- * digest_sign_algorithm function in EVP_PKEY_ASN1_METHOD. */
-typedef enum {
-  /* EVP_DIGEST_SIGN_ALGORITHM_ERROR signals an error. */
-  EVP_DIGEST_SIGN_ALGORITHM_ERROR = 0,
-  /* EVP_DIGEST_SIGN_ALGORITHM_SUCCESS signals that the parameters were
-   * serialized in the AlgorithmIdentifier. */
-  EVP_DIGEST_SIGN_ALGORITHM_SUCCESS = 1,
-  /* EVP_DIGEST_SIGN_ALGORITHM_DEFAULT signals that the parameters are
-   * serialized using the default behavior. */
-  EVP_DIGEST_SIGN_ALGORITHM_DEFAULT = 2,
-} evp_digest_sign_algorithm_result_t;
-
 struct evp_pkey_asn1_method_st {
   int pkey_id;
-  int pkey_base_id;
-  unsigned long pkey_flags;
+  uint8_t oid[9];
+  uint8_t oid_len;
 
-  const char *pem_str;
+  /* pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo
+   * and writes the result into |out|. It returns one on success and zero on
+   * error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER
+   * type field, and |key| is the contents of the subjectPublicKey with the
+   * leading padding byte checked and removed. Although X.509 uses BIT STRINGs
+   * to represent SubjectPublicKeyInfo, every key type defined encodes the key
+   * as a byte string with the same conversion to BIT STRING. */
+  int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key);
 
-  int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
-  int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
+  /* pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result
+   * to |out|. It returns one on success and zero on error. */
+  int (*pub_encode)(CBB *out, const EVP_PKEY *key);
+
   int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
-  int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
 
-  int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
-  int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
-  int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
-                    ASN1_PCTX *pctx);
+  /* priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the
+   * result into |out|. It returns one on success and zero on error. |params| is
+   * the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key|
+   * is the contents of the OCTET STRING privateKey field. */
+  int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key);
+
+  /* priv_encode encodes |key| as a PrivateKeyInfo and appends the result to
+   * |out|. It returns one on success and zero on error. */
+  int (*priv_encode)(CBB *out, const EVP_PKEY *key);
 
   /* pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by
    * custom implementations which do not expose key material and parameters.*/
@@ -114,40 +109,15 @@
   int (*pkey_size)(const EVP_PKEY *pk);
   int (*pkey_bits)(const EVP_PKEY *pk);
 
-  int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, int derlen);
-  int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder);
   int (*param_missing)(const EVP_PKEY *pk);
   int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
   int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
-  int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
-                     ASN1_PCTX *pctx);
-  int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
-                   int indent, ASN1_PCTX *pctx);
-
 
   void (*pkey_free)(EVP_PKEY *pkey);
-
-  /* Legacy functions for old PEM */
-
-  int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder,
-                         int derlen);
-  int (*old_priv_encode)(const EVP_PKEY *pkey, uint8_t **pder);
-
-  /* Converting parameters to/from AlgorithmIdentifier (X509_ALGOR). */
-  int (*digest_verify_init_from_algorithm)(EVP_MD_CTX *ctx,
-                                           X509_ALGOR *algor,
-                                           EVP_PKEY *pkey);
-  evp_digest_sign_algorithm_result_t (*digest_sign_algorithm)(
-      EVP_MD_CTX *ctx,
-      X509_ALGOR *algor);
-
 } /* EVP_PKEY_ASN1_METHOD */;
 
 
-typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
-
 #define EVP_PKEY_OP_UNDEFINED 0
-#define EVP_PKEY_OP_PARAMGEN (1 << 1)
 #define EVP_PKEY_OP_KEYGEN (1 << 2)
 #define EVP_PKEY_OP_SIGN (1 << 3)
 #define EVP_PKEY_OP_VERIFY (1 << 4)
@@ -156,7 +126,7 @@
 #define EVP_PKEY_OP_DECRYPT (1 << 7)
 #define EVP_PKEY_OP_DERIVE (1 << 8)
 
-#define EVP_PKEY_OP_TYPE_SIG                                           \
+#define EVP_PKEY_OP_TYPE_SIG \
   (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER)
 
 #define EVP_PKEY_OP_TYPE_CRYPT (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
@@ -164,7 +134,7 @@
 #define EVP_PKEY_OP_TYPE_NOGEN \
   (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
 
-#define EVP_PKEY_OP_TYPE_GEN (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+#define EVP_PKEY_OP_TYPE_GEN EVP_PKEY_OP_KEYGEN
 
 /* EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype|
  * arguments can be -1 to specify that any type and operation are acceptable,
@@ -208,8 +178,6 @@
 #define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11)
 #define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)
 
-#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
-
 struct evp_pkey_ctx_st {
   /* Method associated with this operation */
   const EVP_PKEY_METHOD *pmeth;
@@ -223,41 +191,32 @@
   int operation;
   /* Algorithm specific data */
   void *data;
-  /* Application specific data */
-  void *app_data;
 } /* EVP_PKEY_CTX */;
 
 struct evp_pkey_method_st {
   int pkey_id;
-  int flags;
 
   int (*init)(EVP_PKEY_CTX *ctx);
   int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
   void (*cleanup)(EVP_PKEY_CTX *ctx);
 
-  int (*paramgen_init)(EVP_PKEY_CTX *ctx);
-  int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
-
-  int (*keygen_init)(EVP_PKEY_CTX *ctx);
   int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
 
-  int (*sign_init)(EVP_PKEY_CTX *ctx);
   int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
               const uint8_t *tbs, size_t tbslen);
 
-  int (*verify_init)(EVP_PKEY_CTX *ctx);
   int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
                 const uint8_t *tbs, size_t tbslen);
 
-  int (*encrypt_init)(EVP_PKEY_CTX *ctx);
+  int (*verify_recover)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
+                        const uint8_t *sig, size_t sig_len);
+
   int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
                  const uint8_t *in, size_t inlen);
 
-  int (*decrypt_init)(EVP_PKEY_CTX *ctx);
   int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
                  const uint8_t *in, size_t inlen);
 
-  int (*derive_init)(EVP_PKEY_CTX *ctx);
   int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen);
 
   int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c
index c92068f..1f022f1 100644
--- a/src/crypto/evp/p_dsa_asn1.c
+++ b/src/crypto/evp/p_dsa_asn1.c
@@ -55,290 +55,139 @@
 
 #include <openssl/evp.h>
 
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
 #include <openssl/digest.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/dsa.h>
 #include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
 
-#include "../dsa/internal.h"
 #include "internal.h"
 
 
-static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
-  const uint8_t *p, *pm;
-  int pklen, pmlen;
-  int ptype;
-  void *pval;
-  ASN1_STRING *pstr;
-  X509_ALGOR *palg;
-  ASN1_INTEGER *public_key = NULL;
+static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* See RFC 3279, section 2.3.2. */
 
-  DSA *dsa = NULL;
-
-  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
-    return 0;
-  }
-  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
-  if (ptype == V_ASN1_SEQUENCE) {
-    pstr = pval;
-    pm = pstr->data;
-    pmlen = pstr->length;
-
-    dsa = d2i_DSAparams(NULL, &pm, pmlen);
+  /* Parameters may or may not be present. */
+  DSA *dsa;
+  if (CBS_len(params) == 0) {
+    dsa = DSA_new();
     if (dsa == NULL) {
+      return 0;
+    }
+  } else {
+    dsa = DSA_parse_parameters(params);
+    if (dsa == NULL || CBS_len(params) != 0) {
       OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
       goto err;
     }
-  } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
-    dsa = DSA_new();
-    if (dsa == NULL) {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-  } else {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR);
+  }
+
+  dsa->pub_key = BN_new();
+  if (dsa->pub_key == NULL) {
     goto err;
   }
 
-  public_key = d2i_ASN1_INTEGER(NULL, &p, pklen);
-  if (public_key == NULL) {
+  if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
+      CBS_len(key) != 0) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     goto err;
   }
 
-  dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL);
-  if (dsa->pub_key == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR);
-    goto err;
-  }
-
-  ASN1_INTEGER_free(public_key);
-  EVP_PKEY_assign_DSA(pkey, dsa);
+  EVP_PKEY_assign_DSA(out, dsa);
   return 1;
 
 err:
-  ASN1_INTEGER_free(public_key);
   DSA_free(dsa);
   return 0;
 }
 
-static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
-  DSA *dsa;
-  ASN1_STRING *pval = NULL;
-  uint8_t *penc = NULL;
-  int penclen;
+static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
+  const DSA *dsa = key->pkey.dsa;
+  const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
 
-  dsa = pkey->pkey.dsa;
-  dsa->write_params = 0;
-
-  int ptype;
-  if (dsa->p && dsa->q && dsa->g) {
-    pval = ASN1_STRING_new();
-    if (!pval) {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-    pval->length = i2d_DSAparams(dsa, &pval->data);
-    if (pval->length <= 0) {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-    ptype = V_ASN1_SEQUENCE;
-  } else {
-    ptype = V_ASN1_UNDEF;
-  }
-
-  penclen = i2d_DSAPublicKey(dsa, &penc);
-  if (penclen <= 0) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
-                             penc, penclen)) {
-    return 1;
-  }
-
-err:
-  OPENSSL_free(penc);
-  ASN1_STRING_free(pval);
-
-  return 0;
-}
-
-static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
-  const uint8_t *p, *pm;
-  int pklen, pmlen;
-  int ptype;
-  void *pval;
-  ASN1_STRING *pstr;
-  X509_ALGOR *palg;
-  ASN1_INTEGER *privkey = NULL;
-  BN_CTX *ctx = NULL;
-
-  /* In PKCS#8 DSA: you just get a private key integer and parameters in the
-   * AlgorithmIdentifier the pubkey must be recalculated. */
-
-  STACK_OF(ASN1_TYPE) *ndsa = NULL;
-  DSA *dsa = NULL;
-
-  if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
+  /* See RFC 5480, section 2. */
+  CBB spki, algorithm, oid, key_bitstring;
+  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
+      (has_params &&
+       !DSA_marshal_parameters(&algorithm, dsa)) ||
+      !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+      !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
     return 0;
   }
-  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
-  /* Check for broken DSA PKCS#8, UGH! */
-  if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
-    ASN1_TYPE *t1, *t2;
-    ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen);
-    if (ndsa == NULL) {
-      goto decerr;
-    }
-    if (sk_ASN1_TYPE_num(ndsa) != 2) {
-      goto decerr;
-    }
-
-    /* Handle Two broken types:
-     * SEQUENCE {parameters, priv_key}
-     * SEQUENCE {pub_key, priv_key}. */
-
-    t1 = sk_ASN1_TYPE_value(ndsa, 0);
-    t2 = sk_ASN1_TYPE_value(ndsa, 1);
-    if (t1->type == V_ASN1_SEQUENCE) {
-      p8->broken = PKCS8_EMBEDDED_PARAM;
-      pval = t1->value.ptr;
-    } else if (ptype == V_ASN1_SEQUENCE) {
-      p8->broken = PKCS8_NS_DB;
-    } else {
-      goto decerr;
-    }
-
-    if (t2->type != V_ASN1_INTEGER) {
-      goto decerr;
-    }
-
-    privkey = t2->value.integer;
-  } else {
-    const uint8_t *q = p;
-    privkey = d2i_ASN1_INTEGER(NULL, &p, pklen);
-    if (privkey == NULL) {
-      goto decerr;
-    }
-    if (privkey->type == V_ASN1_NEG_INTEGER) {
-      p8->broken = PKCS8_NEG_PRIVKEY;
-      ASN1_INTEGER_free(privkey);
-      privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen);
-      if (privkey == NULL) {
-        goto decerr;
-      }
-    }
-    if (ptype != V_ASN1_SEQUENCE) {
-      goto decerr;
-    }
-  }
-
-  pstr = pval;
-  pm = pstr->data;
-  pmlen = pstr->length;
-  dsa = d2i_DSAparams(NULL, &pm, pmlen);
-  if (dsa == NULL) {
-    goto decerr;
-  }
-  /* We have parameters. Now set private key */
-  dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL);
-  if (dsa->priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
-    goto dsaerr;
-  }
-  /* Calculate public key. */
-  dsa->pub_key = BN_new();
-  if (dsa->pub_key == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto dsaerr;
-  }
-  ctx = BN_CTX_new();
-  if (ctx == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto dsaerr;
-  }
-
-  if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
-    OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
-    goto dsaerr;
-  }
-
-  EVP_PKEY_assign_DSA(pkey, dsa);
-  BN_CTX_free(ctx);
-  sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-  ASN1_INTEGER_free(privkey);
 
   return 1;
+}
 
-decerr:
-  OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* See PKCS#11, v2.40, section 2.5. */
 
-dsaerr:
+  /* Decode parameters. */
+  BN_CTX *ctx = NULL;
+  DSA *dsa = DSA_parse_parameters(params);
+  if (dsa == NULL || CBS_len(params) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    goto err;
+  }
+
+  dsa->priv_key = BN_new();
+  dsa->pub_key = BN_new();
+  if (dsa->priv_key == NULL || dsa->pub_key == NULL) {
+    goto err;
+  }
+
+  /* Decode the key. */
+  if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
+      CBS_len(key) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    goto err;
+  }
+
+  /* Calculate the public key. */
+  ctx = BN_CTX_new();
+  if (ctx == NULL ||
+      !BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
+    goto err;
+  }
+
   BN_CTX_free(ctx);
-  ASN1_INTEGER_free(privkey);
-  sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+  EVP_PKEY_assign_DSA(out, dsa);
+  return 1;
+
+err:
+  BN_CTX_free(ctx);
   DSA_free(dsa);
   return 0;
 }
 
-static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
-  ASN1_STRING *params = NULL;
-  ASN1_INTEGER *prkey = NULL;
-  uint8_t *dp = NULL;
-  int dplen;
-
-  if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
+static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
+  const DSA *dsa = key->pkey.dsa;
+  if (dsa == NULL || dsa->priv_key == NULL) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
-    goto err;
+    return 0;
   }
 
-  params = ASN1_STRING_new();
-  if (!params) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
-  if (params->length <= 0) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-  params->type = V_ASN1_SEQUENCE;
-
-  /* Get private key into integer. */
-  prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
-
-  if (!prkey) {
-    OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
-    goto err;
-  }
-
-  dplen = i2d_ASN1_INTEGER(prkey, &dp);
-
-  ASN1_INTEGER_free(prkey);
-  prkey = NULL;
-
-  if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0,
-                       V_ASN1_SEQUENCE, params, dp, dplen)) {
-    goto err;
+  /* See PKCS#11, v2.40, section 2.5. */
+  CBB pkcs8, algorithm, oid, private_key;
+  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+      !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
+      !DSA_marshal_parameters(&algorithm, dsa) ||
+      !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+      !BN_marshal_asn1(&private_key, dsa->priv_key) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
+    return 0;
   }
 
   return 1;
-
-err:
-  OPENSSL_free(dp);
-  ASN1_STRING_free(params);
-  ASN1_INTEGER_free(prkey);
-  return 0;
 }
 
 static int int_dsa_size(const EVP_PKEY *pkey) {
@@ -393,177 +242,17 @@
 
 static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }
 
-static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
-  size_t i;
-
-  if (!b) {
-    return;
-  }
-  i = BN_num_bytes(b);
-  if (*pbuflen < i) {
-    *pbuflen = i;
-  }
-}
-
-static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
-  uint8_t *m = NULL;
-  int ret = 0;
-  size_t buf_len = 0;
-  const char *ktype = NULL;
-
-  const BIGNUM *priv_key, *pub_key;
-
-  priv_key = NULL;
-  if (ptype == 2) {
-    priv_key = x->priv_key;
-  }
-
-  pub_key = NULL;
-  if (ptype > 0) {
-    pub_key = x->pub_key;
-  }
-
-  ktype = "DSA-Parameters";
-  if (ptype == 2) {
-    ktype = "Private-Key";
-  } else if (ptype == 1) {
-    ktype = "Public-Key";
-  }
-
-  update_buflen(x->p, &buf_len);
-  update_buflen(x->q, &buf_len);
-  update_buflen(x->g, &buf_len);
-  update_buflen(priv_key, &buf_len);
-  update_buflen(pub_key, &buf_len);
-
-  m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
-  if (m == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (priv_key) {
-    if (!BIO_indent(bp, off, 128) ||
-        BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
-      goto err;
-    }
-  }
-
-  if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) ||
-      !ASN1_bn_print(bp, "pub: ", pub_key, m, off) ||
-      !ASN1_bn_print(bp, "P:   ", x->p, m, off) ||
-      !ASN1_bn_print(bp, "Q:   ", x->q, m, off) ||
-      !ASN1_bn_print(bp, "G:   ", x->g, m, off)) {
-    goto err;
-  }
-  ret = 1;
-
-err:
-  OPENSSL_free(m);
-  return ret;
-}
-
-static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) {
-  DSA *dsa;
-  dsa = d2i_DSAparams(NULL, pder, derlen);
-  if (dsa == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
-    return 0;
-  }
-  EVP_PKEY_assign_DSA(pkey, dsa);
-  return 1;
-}
-
-static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
-  return i2d_DSAparams(pkey->pkey.dsa, pder);
-}
-
-static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                           ASN1_PCTX *ctx) {
-  return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
-}
-
-static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                         ASN1_PCTX *ctx) {
-  return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
-}
-
-static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *ctx) {
-  return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
-}
-
-static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
-                               int derlen) {
-  DSA *dsa;
-  dsa = d2i_DSAPrivateKey(NULL, pder, derlen);
-  if (dsa == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
-    return 0;
-  }
-  EVP_PKEY_assign_DSA(pkey, dsa);
-  return 1;
-}
-
-static int old_dsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
-  return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
-}
-
-static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
-                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) {
-  DSA_SIG *dsa_sig;
-  const uint8_t *p;
-
-  if (!sig) {
-    return BIO_puts(bp, "\n") > 0;
-  }
-
-  p = sig->data;
-  dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
-  if (dsa_sig == NULL) {
-    return X509_signature_dump(bp, sig, indent);
-  }
-
-  int rv = 0;
-  size_t buf_len = 0;
-  uint8_t *m = NULL;
-
-  update_buflen(dsa_sig->r, &buf_len);
-  update_buflen(dsa_sig->s, &buf_len);
-  m = OPENSSL_malloc(buf_len + 10);
-  if (m == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (BIO_write(bp, "\n", 1) != 1 ||
-      !ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent) ||
-      !ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent)) {
-    goto err;
-  }
-  rv = 1;
-
-err:
-  OPENSSL_free(m);
-  DSA_SIG_free(dsa_sig);
-  return rv;
-}
-
 const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
   EVP_PKEY_DSA,
-  EVP_PKEY_DSA,
-  0,
-
-  "DSA",
+  /* 1.2.840.10040.4.1 */
+  {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7,
 
   dsa_pub_decode,
   dsa_pub_encode,
   dsa_pub_cmp,
-  dsa_pub_print,
 
   dsa_priv_decode,
   dsa_priv_encode,
-  dsa_priv_print,
 
   NULL /* pkey_opaque */,
   NULL /* pkey_supports_digest */,
@@ -571,18 +260,9 @@
   int_dsa_size,
   dsa_bits,
 
-  dsa_param_decode,
-  dsa_param_encode,
   dsa_missing_parameters,
   dsa_copy_parameters,
   dsa_cmp_parameters,
-  dsa_param_print,
-  dsa_sig_print,
 
   int_dsa_free,
-  old_dsa_priv_decode,
-  old_dsa_priv_encode,
-
-  NULL  /* digest_verify_init_from_algorithm */,
-  NULL  /* digest_sign_algorithm */,
 };
diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c
index 77f213d..f92c87c 100644
--- a/src/crypto/evp/p_ec.c
+++ b/src/crypto/evp/p_ec.c
@@ -57,7 +57,6 @@
 
 #include <string.h>
 
-#include <openssl/asn1.h>
 #include <openssl/bn.h>
 #include <openssl/buf.h>
 #include <openssl/digest.h>
@@ -67,15 +66,13 @@
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 #include "../ec/internal.h"
 
 
 typedef struct {
-  /* Key and paramgen group */
-  EC_GROUP *gen_group;
   /* message digest */
   const EVP_MD *md;
 } EC_PKEY_CTX;
@@ -102,12 +99,6 @@
   sctx = src->data;
   dctx = dst->data;
 
-  if (sctx->gen_group) {
-    dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
-    if (!dctx->gen_group) {
-      return 0;
-    }
-  }
   dctx->md = sctx->md;
 
   return 1;
@@ -119,7 +110,6 @@
     return;
   }
 
-  EC_GROUP_free(dctx->gen_group);
   OPENSSL_free(dctx);
 }
 
@@ -185,19 +175,8 @@
 
 static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
   EC_PKEY_CTX *dctx = ctx->data;
-  EC_GROUP *group;
 
   switch (type) {
-    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
-      group = EC_GROUP_new_by_curve_name(p1);
-      if (group == NULL) {
-        OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CURVE);
-        return 0;
-      }
-      EC_GROUP_free(dctx->gen_group);
-      dctx->gen_group = group;
-      return 1;
-
     case EVP_PKEY_CTRL_MD:
       if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
           EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
@@ -225,59 +204,33 @@
   }
 }
 
-static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
-  EC_KEY *ec = NULL;
-  EC_PKEY_CTX *dctx = ctx->data;
-  int ret = 0;
-
-  if (dctx->gen_group == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
-    return 0;
-  }
-  ec = EC_KEY_new();
-  if (!ec) {
-    return 0;
-  }
-  ret = EC_KEY_set_group(ec, dctx->gen_group);
-  if (ret) {
-    EVP_PKEY_assign_EC_KEY(pkey, ec);
-  } else {
-    EC_KEY_free(ec);
-  }
-  return ret;
-}
-
 static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
-  EC_KEY *ec = NULL;
-  EC_PKEY_CTX *dctx = ctx->data;
-  if (ctx->pkey == NULL && dctx->gen_group == NULL) {
+  if (ctx->pkey == NULL) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
     return 0;
   }
-  ec = EC_KEY_new();
-  if (!ec) {
+  EC_KEY *ec = EC_KEY_new();
+  if (ec == NULL ||
+      !EC_KEY_set_group(ec, EC_KEY_get0_group(ctx->pkey->pkey.ec)) ||
+      !EC_KEY_generate_key(ec)) {
+    EC_KEY_free(ec);
     return 0;
   }
   EVP_PKEY_assign_EC_KEY(pkey, ec);
-  if (ctx->pkey) {
-    /* Note: if error return, pkey is freed by parent routine */
-    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) {
-      return 0;
-    }
-  } else {
-    if (!EC_KEY_set_group(ec, dctx->gen_group)) {
-      return 0;
-    }
-  }
-  return EC_KEY_generate_key(pkey->pkey.ec);
+  return 1;
 }
 
 const EVP_PKEY_METHOD ec_pkey_meth = {
-    EVP_PKEY_EC,          0 /* flags */,        pkey_ec_init,
-    pkey_ec_copy,         pkey_ec_cleanup,      0 /* paramgen_init */,
-    pkey_ec_paramgen,     0 /* keygen_init */,  pkey_ec_keygen,
-    0 /* sign_init */,    pkey_ec_sign,         0 /* verify_init */,
-    pkey_ec_verify,       0 /* encrypt_init */, 0 /* encrypt */,
-    0 /* decrypt_init */, 0 /* decrypt */,      0 /* derive_init */,
-    pkey_ec_derive,       pkey_ec_ctrl,
+    EVP_PKEY_EC,
+    pkey_ec_init,
+    pkey_ec_copy,
+    pkey_ec_cleanup,
+    pkey_ec_keygen,
+    pkey_ec_sign,
+    pkey_ec_verify,
+    0 /* verify_recover */,
+    0 /* encrypt */,
+    0 /* decrypt */,
+    pkey_ec_derive,
+    pkey_ec_ctrl,
 };
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index f40b976..8d44dcd 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -55,145 +55,73 @@
 
 #include <openssl/evp.h>
 
-#include <openssl/asn1t.h>
 #include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
 #include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
 
 #include "internal.h"
 
 
-static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
-  const EC_GROUP *group;
-  int nid;
+static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) {
+  const EC_KEY *ec_key = key->pkey.ec;
+  const EC_GROUP *group = EC_KEY_get0_group(ec_key);
+  const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key);
 
-  if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
+  /* See RFC 5480, section 2. */
+  CBB spki, algorithm, oid, key_bitstring;
+  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
+      !EC_KEY_marshal_curve_name(&algorithm, group) ||
+      !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+      !EC_POINT_point2cbb(&key_bitstring, group, public_key,
+                          POINT_CONVERSION_UNCOMPRESSED, NULL) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
     return 0;
   }
 
-  nid = EC_GROUP_get_curve_name(group);
-  if (nid == NID_undef) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_NID_FOR_CURVE);
-    return 0;
-  }
-
-  *ppval = (void*) OBJ_nid2obj(nid);
-  *pptype = V_ASN1_OBJECT;
   return 1;
 }
 
-static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
-  EC_KEY *ec_key = pkey->pkey.ec;
-  void *pval = NULL;
-  int ptype;
-  uint8_t *penc = NULL, *p;
-  int penclen;
+static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* See RFC 5480, section 2. */
 
-  if (!eckey_param2type(&ptype, &pval, ec_key)) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-    return 0;
-  }
-  penclen = i2o_ECPublicKey(ec_key, NULL);
-  if (penclen <= 0) {
-    goto err;
-  }
-  penc = OPENSSL_malloc(penclen);
-  if (!penc) {
-    goto err;
-  }
-  p = penc;
-  penclen = i2o_ECPublicKey(ec_key, &p);
-  if (penclen <= 0) {
-    goto err;
-  }
-  if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc,
-                             penclen)) {
-    return 1;
-  }
-
-err:
-  if (ptype == V_ASN1_OBJECT) {
-    ASN1_OBJECT_free(pval);
-  } else {
-    ASN1_STRING_free(pval);
-  }
-  if (penc) {
-    OPENSSL_free(penc);
-  }
-  return 0;
-}
-
-static EC_KEY *eckey_type2param(int ptype, void *pval) {
+  /* The parameters are a named curve. */
+  EC_POINT *point = NULL;
   EC_KEY *eckey = NULL;
-
-  if (ptype == V_ASN1_SEQUENCE) {
-    ASN1_STRING *pstr = pval;
-    const uint8_t *pm = pstr->data;
-    int pmlen = pstr->length;
-
-    eckey = d2i_ECParameters(NULL, &pm, pmlen);
-    if (eckey == NULL) {
-      OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
-      goto err;
-    }
-  } else if (ptype == V_ASN1_OBJECT) {
-    ASN1_OBJECT *poid = pval;
-
-    /* type == V_ASN1_OBJECT => the parameters are given
-     * by an asn1 OID */
-    eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid));
-    if (eckey == NULL) {
-      goto err;
-    }
-  } else {
+  EC_GROUP *group = EC_KEY_parse_curve_name(params);
+  if (group == NULL || CBS_len(params) != 0) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     goto err;
   }
 
-  return eckey;
-
-err:
-  if (eckey) {
-    EC_KEY_free(eckey);
-  }
-  return NULL;
-}
-
-static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
-  const uint8_t *p = NULL;
-  void *pval;
-  int ptype, pklen;
-  EC_KEY *eckey = NULL;
-  X509_ALGOR *palg;
-
-  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
-    return 0;
-  }
-  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
-  eckey = eckey_type2param(ptype, pval);
-  if (!eckey) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-    return 0;
-  }
-
-  /* We have parameters now set public key */
-  if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+  eckey = EC_KEY_new();
+  if (eckey == NULL || !EC_KEY_set_group(eckey, group)) {
     goto err;
   }
 
-  EVP_PKEY_assign_EC_KEY(pkey, eckey);
+  point = EC_POINT_new(group);
+  if (point == NULL ||
+      !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) ||
+      !EC_KEY_set_public_key(eckey, point)) {
+    goto err;
+  }
+
+  EC_GROUP_free(group);
+  EC_POINT_free(point);
+  EVP_PKEY_assign_EC_KEY(out, eckey);
   return 1;
 
 err:
-  if (eckey) {
-    EC_KEY_free(eckey);
-  }
+  EC_GROUP_free(group);
+  EC_POINT_free(point);
+  EC_KEY_free(eckey);
   return 0;
 }
 
@@ -212,120 +140,48 @@
   }
 }
 
-static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
-  const uint8_t *p = NULL;
-  void *pval;
-  int ptype, pklen;
-  EC_KEY *eckey = NULL;
-  X509_ALGOR *palg;
-
-  if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
+static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* See RFC 5915. */
+  EC_GROUP *group = EC_KEY_parse_parameters(params);
+  if (group == NULL || CBS_len(params) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    EC_GROUP_free(group);
     return 0;
   }
-  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
 
-  eckey = eckey_type2param(ptype, pval);
-
-  if (!eckey) {
-    goto ecliberr;
-  }
-
-  /* We have parameters now set private key */
-  if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+  EC_KEY *ec_key = EC_KEY_parse_private_key(key, group);
+  EC_GROUP_free(group);
+  if (ec_key == NULL || CBS_len(key) != 0) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
-    goto ecerr;
+    EC_KEY_free(ec_key);
+    return 0;
   }
 
-  /* calculate public key (if necessary) */
-  if (EC_KEY_get0_public_key(eckey) == NULL) {
-    const BIGNUM *priv_key;
-    const EC_GROUP *group;
-    EC_POINT *pub_key;
-    /* the public key was not included in the SEC1 private
-     * key => calculate the public key */
-    group = EC_KEY_get0_group(eckey);
-    pub_key = EC_POINT_new(group);
-    if (pub_key == NULL) {
-      OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-      goto ecliberr;
-    }
-    if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
-      EC_POINT_free(pub_key);
-      OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-      goto ecliberr;
-    }
-    priv_key = EC_KEY_get0_private_key(eckey);
-    if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
-      EC_POINT_free(pub_key);
-      OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-      goto ecliberr;
-    }
-    if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
-      EC_POINT_free(pub_key);
-      OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-      goto ecliberr;
-    }
-    EC_POINT_free(pub_key);
-  }
-
-  EVP_PKEY_assign_EC_KEY(pkey, eckey);
+  EVP_PKEY_assign_EC_KEY(out, ec_key);
   return 1;
-
-ecliberr:
-  OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-ecerr:
-  if (eckey) {
-    EC_KEY_free(eckey);
-  }
-  return 0;
 }
 
-static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
-  EC_KEY *ec_key;
-  uint8_t *ep, *p;
-  int eplen, ptype;
-  void *pval;
-  unsigned int tmp_flags, old_flags;
+static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) {
+  const EC_KEY *ec_key = key->pkey.ec;
 
-  ec_key = pkey->pkey.ec;
+  /* Omit the redundant copy of the curve name. This contradicts RFC 5915 but
+   * aligns with PKCS #11. SEC 1 only says they may be omitted if known by other
+   * means. Both OpenSSL and NSS omit the redundant parameters, so we omit them
+   * as well. */
+  unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS;
 
-  if (!eckey_param2type(&ptype, &pval, ec_key)) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
-    return 0;
-  }
-
-  /* set the private key */
-
-  /* do not include the parameters in the SEC1 private key
-   * see PKCS#11 12.11 */
-  old_flags = EC_KEY_get_enc_flags(ec_key);
-  tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
-  EC_KEY_set_enc_flags(ec_key, tmp_flags);
-  eplen = i2d_ECPrivateKey(ec_key, NULL);
-  if (!eplen) {
-    EC_KEY_set_enc_flags(ec_key, old_flags);
-    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-    return 0;
-  }
-  ep = (uint8_t *)OPENSSL_malloc(eplen);
-  if (!ep) {
-    EC_KEY_set_enc_flags(ec_key, old_flags);
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    return 0;
-  }
-  p = ep;
-  if (!i2d_ECPrivateKey(ec_key, &p)) {
-    EC_KEY_set_enc_flags(ec_key, old_flags);
-    OPENSSL_free(ep);
-    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-    return 0;
-  }
-  /* restore old encoding flags */
-  EC_KEY_set_enc_flags(ec_key, old_flags);
-
-  if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
-                       0, ptype, pval, ep, eplen)) {
-    OPENSSL_free(ep);
+  /* See RFC 5915. */
+  CBB pkcs8, algorithm, oid, private_key;
+  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+      !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
+      !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) ||
+      !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+      !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
     return 0;
   }
 
@@ -371,173 +227,21 @@
 
 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
 
-static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
-  uint8_t *buffer = NULL;
-  const char *ecstr;
-  size_t buf_len = 0, i;
-  int ret = 0, reason = ERR_R_BIO_LIB;
-  BN_CTX *ctx = NULL;
-  const EC_GROUP *group;
-  const EC_POINT *public_key;
-  const BIGNUM *priv_key;
-  uint8_t *pub_key_bytes = NULL;
-  size_t pub_key_bytes_len = 0;
-
-  if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
-    reason = ERR_R_PASSED_NULL_PARAMETER;
-    goto err;
-  }
-
-  ctx = BN_CTX_new();
-  if (ctx == NULL) {
-    reason = ERR_R_MALLOC_FAILURE;
-    goto err;
-  }
-
-  if (ktype > 0) {
-    public_key = EC_KEY_get0_public_key(x);
-    if (public_key != NULL) {
-      pub_key_bytes_len = EC_POINT_point2oct(
-          group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
-      if (pub_key_bytes_len == 0) {
-        reason = ERR_R_MALLOC_FAILURE;
-        goto err;
-      }
-      pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
-      if (pub_key_bytes == NULL) {
-        reason = ERR_R_MALLOC_FAILURE;
-        goto err;
-      }
-      pub_key_bytes_len =
-          EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
-                             pub_key_bytes, pub_key_bytes_len, ctx);
-      if (pub_key_bytes_len == 0) {
-        reason = ERR_R_MALLOC_FAILURE;
-        goto err;
-      }
-      buf_len = pub_key_bytes_len;
-    }
-  }
-
-  if (ktype == 2) {
-    priv_key = EC_KEY_get0_private_key(x);
-    if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
-      buf_len = i;
-    }
-  } else {
-    priv_key = NULL;
-  }
-
-  if (ktype > 0) {
-    buf_len += 10;
-    if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
-      reason = ERR_R_MALLOC_FAILURE;
-      goto err;
-    }
-  }
-  if (ktype == 2) {
-    ecstr = "Private-Key";
-  } else if (ktype == 1) {
-    ecstr = "Public-Key";
-  } else {
-    ecstr = "ECDSA-Parameters";
-  }
-
-  if (!BIO_indent(bp, off, 128)) {
-    goto err;
-  }
-  const BIGNUM *order = EC_GROUP_get0_order(group);
-  if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
-    goto err;
-  }
-
-  if ((priv_key != NULL) &&
-      !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
-    goto err;
-  }
-  if (pub_key_bytes != NULL) {
-    BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
-  }
-  /* TODO(fork): implement */
-  /*
-  if (!ECPKParameters_print(bp, group, off))
-    goto err; */
-  ret = 1;
-
-err:
-  if (!ret) {
-    OPENSSL_PUT_ERROR(EVP, reason);
-  }
-  OPENSSL_free(pub_key_bytes);
-  BN_CTX_free(ctx);
-  OPENSSL_free(buffer);
-  return ret;
-}
-
-static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
-                              int derlen) {
-  EC_KEY *eckey;
-  if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-    return 0;
-  }
-  EVP_PKEY_assign_EC_KEY(pkey, eckey);
-  return 1;
-}
-
-static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
-  return i2d_ECParameters(pkey->pkey.ec, pder);
-}
-
-static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                             ASN1_PCTX *ctx) {
-  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
-}
-
-static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                           ASN1_PCTX *ctx) {
-  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
-}
-
-
-static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                            ASN1_PCTX *ctx) {
-  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
-}
-
 static int eckey_opaque(const EVP_PKEY *pkey) {
   return EC_KEY_is_opaque(pkey->pkey.ec);
 }
 
-static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
-                              int derlen) {
-  EC_KEY *ec;
-  if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
-    return 0;
-  }
-  EVP_PKEY_assign_EC_KEY(pkey, ec);
-  return 1;
-}
-
-static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
-  return i2d_ECPrivateKey(pkey->pkey.ec, pder);
-}
-
 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
   EVP_PKEY_EC,
-  EVP_PKEY_EC,
-  0,
-  "EC",
+  /* 1.2.840.10045.2.1 */
+  {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7,
 
   eckey_pub_decode,
   eckey_pub_encode,
   eckey_pub_cmp,
-  eckey_pub_print,
 
   eckey_priv_decode,
   eckey_priv_encode,
-  eckey_priv_print,
 
   eckey_opaque,
   0 /* pkey_supports_digest */,
@@ -545,18 +249,9 @@
   int_ec_size,
   ec_bits,
 
-  eckey_param_decode,
-  eckey_param_encode,
   ec_missing_parameters,
   ec_copy_parameters,
   ec_cmp_parameters,
-  eckey_param_print,
-  0,
 
   int_ec_free,
-  old_ec_priv_decode,
-  old_ec_priv_encode,
-
-  NULL /* digest_verify_init_from_algorithm */,
-  NULL /* digest_sign_algorithm */,
 };
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index 895d351..a210657 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -64,7 +64,7 @@
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rsa.h>
 
 #include "../rsa/internal.h"
@@ -256,6 +256,81 @@
   return 1;
 }
 
+static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
+                                   size_t *out_len, const uint8_t *sig,
+                                   size_t sig_len) {
+  RSA_PKEY_CTX *rctx = ctx->data;
+  RSA *rsa = ctx->pkey->pkey.rsa;
+  const size_t key_len = EVP_PKEY_size(ctx->pkey);
+
+  if (out == NULL) {
+    *out_len = key_len;
+    return 1;
+  }
+
+  if (*out_len < key_len) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
+    return 0;
+  }
+
+  if (!setup_tbuf(rctx, ctx)) {
+    return 0;
+  }
+
+  if (rctx->md == NULL) {
+    const int ret = RSA_public_decrypt(sig_len, sig, rctx->tbuf,
+                                       ctx->pkey->pkey.rsa, rctx->pad_mode);
+    if (ret < 0) {
+      return 0;
+    }
+    *out_len = ret;
+    memcpy(out, rctx->tbuf, *out_len);
+    return 1;
+  }
+
+  if (rctx->pad_mode != RSA_PKCS1_PADDING) {
+    return 0;
+  }
+
+  uint8_t *asn1_prefix;
+  size_t asn1_prefix_len;
+  int asn1_prefix_allocated;
+  if (!RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len,
+                            &asn1_prefix_allocated, EVP_MD_type(rctx->md), NULL,
+                            0)) {
+    return 0;
+  }
+
+  size_t rslen;
+  int ok = 1;
+  if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len,
+                      RSA_PKCS1_PADDING) ||
+      rslen < asn1_prefix_len ||
+      CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len) != 0) {
+    ok = 0;
+  }
+
+  if (asn1_prefix_allocated) {
+    OPENSSL_free(asn1_prefix);
+  }
+
+  if (!ok) {
+    return 0;
+  }
+
+  const size_t result_len = rslen - asn1_prefix_len;
+  if (result_len != EVP_MD_size(rctx->md)) {
+    return 0;
+  }
+
+  if (out != NULL) {
+    memcpy(out, rctx->tbuf + asn1_prefix_len, result_len);
+  }
+  *out_len = result_len;
+
+  return 1;
+}
+
 static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
                             const uint8_t *in, size_t inlen) {
   RSA_PKEY_CTX *rctx = ctx->data;
@@ -503,13 +578,18 @@
 }
 
 const EVP_PKEY_METHOD rsa_pkey_meth = {
-    EVP_PKEY_RSA,         0 /* flags */,        pkey_rsa_init,
-    pkey_rsa_copy,        pkey_rsa_cleanup,     0 /* paramgen_init */,
-    0 /* paramgen */,     0 /* keygen_init */,  pkey_rsa_keygen,
-    0 /* sign_init */,    pkey_rsa_sign,        0 /* verify_init */,
-    pkey_rsa_verify,      0 /* encrypt_init */, pkey_rsa_encrypt,
-    0 /* decrypt_init */, pkey_rsa_decrypt,     0 /* derive_init */,
-    0 /* derive */,       pkey_rsa_ctrl,
+    EVP_PKEY_RSA,
+    pkey_rsa_init,
+    pkey_rsa_copy,
+    pkey_rsa_cleanup,
+    pkey_rsa_keygen,
+    pkey_rsa_sign,
+    pkey_rsa_verify,
+    pkey_rsa_verify_recover,
+    pkey_rsa_encrypt,
+    pkey_rsa_decrypt,
+    0 /* derive */,
+    pkey_rsa_ctrl,
 };
 
 int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
@@ -566,15 +646,14 @@
                            EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md);
 }
 
-int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
+int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label,
                                      size_t label_len) {
-  int label_len_int = label_len;
-  if (((size_t) label_len_int) != label_len) {
+  if (label_len > INT_MAX) {
     return 0;
   }
 
   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                           EVP_PKEY_CTRL_RSA_OAEP_LABEL, label_len,
+                           EVP_PKEY_CTRL_RSA_OAEP_LABEL, (int)label_len,
                            (void *)label);
 }
 
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index db38d5c..2c4b266 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -55,40 +55,45 @@
 
 #include <openssl/evp.h>
 
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <openssl/bn.h>
 #include <openssl/bytestring.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rsa.h>
-#include <openssl/x509.h>
 
 #include "../rsa/internal.h"
 #include "internal.h"
 
 
-static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
-  uint8_t *encoded;
-  size_t encoded_len;
-  if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
-    return 0;
-  }
-
-  if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL,
-                              encoded, encoded_len)) {
-    OPENSSL_free(encoded);
+static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
+  /* See RFC 3279, section 2.3.1. */
+  CBB spki, algorithm, oid, null, key_bitstring;
+  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
+      !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
+      !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+      !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
     return 0;
   }
 
   return 1;
 }
 
-static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
-  const uint8_t *p;
-  int pklen;
-  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) {
+static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* See RFC 3279, section 2.3.1. */
+
+  /* The parameters must be NULL. */
+  CBS null;
+  if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
+      CBS_len(&null) != 0 ||
+      CBS_len(params) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     return 0;
   }
 
@@ -98,16 +103,14 @@
    * TODO(davidben): Switch this to the strict version in March 2016 or when
    * Chromium can force client certificates down a different codepath, whichever
    * comes first. */
-  CBS cbs;
-  CBS_init(&cbs, p, pklen);
-  RSA *rsa = RSA_parse_public_key_buggy(&cbs);
-  if (rsa == NULL || CBS_len(&cbs) != 0) {
+  RSA *rsa = RSA_parse_public_key_buggy(key);
+  if (rsa == NULL || CBS_len(key) != 0) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     RSA_free(rsa);
     return 0;
   }
 
-  EVP_PKEY_assign_RSA(pkey, rsa);
+  EVP_PKEY_assign_RSA(out, rsa);
   return 1;
 }
 
@@ -116,39 +119,42 @@
          BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0;
 }
 
-static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
-  uint8_t *encoded;
-  size_t encoded_len;
-  if (!RSA_private_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
-    return 0;
-  }
-
-  /* TODO(fork): const correctness in next line. */
-  if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_rsaEncryption), 0,
-                       V_ASN1_NULL, NULL, encoded, encoded_len)) {
-    OPENSSL_free(encoded);
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) {
+  CBB pkcs8, algorithm, oid, null, private_key;
+  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+      !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
+      !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
+      !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+      !RSA_marshal_private_key(&private_key, key->pkey.rsa) ||
+      !CBB_flush(out)) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
     return 0;
   }
 
   return 1;
 }
 
-static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
-  const uint8_t *p;
-  int pklen;
-  if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  /* Per RFC 3447, A.1, the parameters have type NULL. */
+  CBS null;
+  if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
+      CBS_len(&null) != 0 ||
+      CBS_len(params) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     return 0;
   }
 
-  RSA *rsa = RSA_private_key_from_bytes(p, pklen);
-  if (rsa == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
+  RSA *rsa = RSA_parse_private_key(key);
+  if (rsa == NULL || CBS_len(key) != 0) {
+    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+    RSA_free(rsa);
     return 0;
   }
 
-  EVP_PKEY_assign_RSA(pkey, rsa);
+  EVP_PKEY_assign_RSA(out, rsa);
   return 1;
 }
 
@@ -170,553 +176,17 @@
 
 static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); }
 
-static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
-  size_t i;
-
-  if (!b) {
-    return;
-  }
-
-  i = BN_num_bytes(b);
-  if (*pbuflen < i) {
-    *pbuflen = i;
-  }
-}
-
-static int do_rsa_print(BIO *out, const RSA *rsa, int off,
-                        int include_private) {
-  char *str;
-  const char *s;
-  uint8_t *m = NULL;
-  int ret = 0, mod_len = 0;
-  size_t buf_len = 0;
-
-  update_buflen(rsa->n, &buf_len);
-  update_buflen(rsa->e, &buf_len);
-
-  if (include_private) {
-    update_buflen(rsa->d, &buf_len);
-    update_buflen(rsa->p, &buf_len);
-    update_buflen(rsa->q, &buf_len);
-    update_buflen(rsa->dmp1, &buf_len);
-    update_buflen(rsa->dmq1, &buf_len);
-    update_buflen(rsa->iqmp, &buf_len);
-
-    if (rsa->additional_primes != NULL) {
-      size_t i;
-
-      for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
-           i++) {
-        const RSA_additional_prime *ap =
-            sk_RSA_additional_prime_value(rsa->additional_primes, i);
-        update_buflen(ap->prime, &buf_len);
-        update_buflen(ap->exp, &buf_len);
-        update_buflen(ap->coeff, &buf_len);
-      }
-    }
-  }
-
-  m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
-  if (m == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (rsa->n != NULL) {
-    mod_len = BN_num_bits(rsa->n);
-  }
-
-  if (!BIO_indent(out, off, 128)) {
-    goto err;
-  }
-
-  if (include_private && rsa->d) {
-    if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
-      goto err;
-    }
-    str = "modulus:";
-    s = "publicExponent:";
-  } else {
-    if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
-      goto err;
-    }
-    str = "Modulus:";
-    s = "Exponent:";
-  }
-  if (!ASN1_bn_print(out, str, rsa->n, m, off) ||
-      !ASN1_bn_print(out, s, rsa->e, m, off)) {
-    goto err;
-  }
-
-  if (include_private) {
-    if (!ASN1_bn_print(out, "privateExponent:", rsa->d, m, off) ||
-        !ASN1_bn_print(out, "prime1:", rsa->p, m, off) ||
-        !ASN1_bn_print(out, "prime2:", rsa->q, m, off) ||
-        !ASN1_bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
-        !ASN1_bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
-        !ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
-      goto err;
-    }
-
-    if (rsa->additional_primes != NULL &&
-        sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
-      size_t i;
-
-      if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
-        goto err;
-      }
-      for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
-           i++) {
-        const RSA_additional_prime *ap =
-            sk_RSA_additional_prime_value(rsa->additional_primes, i);
-
-        if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
-                       (unsigned)(i + 3)) <= 0 ||
-            !ASN1_bn_print(out, "prime:", ap->prime, m, off) ||
-            !ASN1_bn_print(out, "exponent:", ap->exp, m, off) ||
-            !ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) {
-          goto err;
-        }
-      }
-    }
-  }
-  ret = 1;
-
-err:
-  OPENSSL_free(m);
-  return ret;
-}
-
-static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                         ASN1_PCTX *ctx) {
-  return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
-}
-
-
-static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *ctx) {
-  return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
-}
-
-/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
-static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
-  const uint8_t *p;
-  int plen;
-
-  if (alg == NULL || alg->parameter == NULL ||
-      OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
-      alg->parameter->type != V_ASN1_SEQUENCE) {
-    return NULL;
-  }
-
-  p = alg->parameter->value.sequence->data;
-  plen = alg->parameter->value.sequence->length;
-  return d2i_X509_ALGOR(NULL, &p, plen);
-}
-
-static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
-                                      X509_ALGOR **pmaskHash) {
-  const uint8_t *p;
-  int plen;
-  RSA_PSS_PARAMS *pss;
-
-  *pmaskHash = NULL;
-
-  if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) {
-    return NULL;
-  }
-  p = alg->parameter->value.sequence->data;
-  plen = alg->parameter->value.sequence->length;
-  pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
-
-  if (!pss) {
-    return NULL;
-  }
-
-  *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
-
-  return pss;
-}
-
-static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
-                               X509_ALGOR *maskHash, int indent) {
-  int rv = 0;
-
-  if (!pss) {
-    if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
-      return 0;
-    }
-    return 1;
-  }
-
-  if (BIO_puts(bp, "\n") <= 0 ||
-      !BIO_indent(bp, indent, 128) ||
-      BIO_puts(bp, "Hash Algorithm: ") <= 0) {
-    goto err;
-  }
-
-  if (pss->hashAlgorithm) {
-    if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
-      goto err;
-    }
-  } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
-    goto err;
-  }
-
-  if (BIO_puts(bp, "\n") <= 0 ||
-      !BIO_indent(bp, indent, 128) ||
-      BIO_puts(bp, "Mask Algorithm: ") <= 0) {
-    goto err;
-  }
-
-  if (pss->maskGenAlgorithm) {
-    if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
-        BIO_puts(bp, " with ") <= 0) {
-      goto err;
-    }
-
-    if (maskHash) {
-      if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
-        goto err;
-      }
-    } else if (BIO_puts(bp, "INVALID") <= 0) {
-      goto err;
-    }
-  } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
-    goto err;
-  }
-  BIO_puts(bp, "\n");
-
-  if (!BIO_indent(bp, indent, 128) ||
-      BIO_puts(bp, "Salt Length: 0x") <= 0) {
-    goto err;
-  }
-
-  if (pss->saltLength) {
-    if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
-      goto err;
-    }
-  } else if (BIO_puts(bp, "14 (default)") <= 0) {
-    goto err;
-  }
-  BIO_puts(bp, "\n");
-
-  if (!BIO_indent(bp, indent, 128) ||
-      BIO_puts(bp, "Trailer Field: 0x") <= 0) {
-    goto err;
-  }
-
-  if (pss->trailerField) {
-    if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
-      goto err;
-    }
-  } else if (BIO_puts(bp, "BC (default)") <= 0) {
-    goto err;
-  }
-  BIO_puts(bp, "\n");
-
-  rv = 1;
-
-err:
-  return rv;
-}
-
-static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
-                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) {
-  if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
-    int rv;
-    RSA_PSS_PARAMS *pss;
-    X509_ALGOR *maskHash;
-
-    pss = rsa_pss_decode(sigalg, &maskHash);
-    rv = rsa_pss_param_print(bp, pss, maskHash, indent);
-    RSA_PSS_PARAMS_free(pss);
-    X509_ALGOR_free(maskHash);
-    if (!rv) {
-      return 0;
-    }
-  } else if (!sig && BIO_puts(bp, "\n") <= 0) {
-    return 0;
-  }
-
-  if (sig) {
-    return X509_signature_dump(bp, sig, indent);
-  }
-  return 1;
-}
-
-static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
-                               int derlen) {
-  RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen);
-  if (rsa == NULL) {
-    OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
-    return 0;
-  }
-  EVP_PKEY_assign_RSA(pkey, rsa);
-  return 1;
-}
-
-static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
-  return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
-}
-
-/* allocate and set algorithm ID from EVP_MD, default SHA1 */
-static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) {
-  if (EVP_MD_type(md) == NID_sha1) {
-    return 1;
-  }
-  *palg = X509_ALGOR_new();
-  if (!*palg) {
-    return 0;
-  }
-  X509_ALGOR_set_md(*palg, md);
-  return 1;
-}
-
-/* Allocate and set MGF1 algorithm ID from EVP_MD */
-static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
-  X509_ALGOR *algtmp = NULL;
-  ASN1_STRING *stmp = NULL;
-  *palg = NULL;
-
-  if (EVP_MD_type(mgf1md) == NID_sha1) {
-    return 1;
-  }
-  /* need to embed algorithm ID inside another */
-  if (!rsa_md_to_algor(&algtmp, mgf1md) ||
-      !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) {
-    goto err;
-  }
-  *palg = X509_ALGOR_new();
-  if (!*palg) {
-    goto err;
-  }
-  X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
-  stmp = NULL;
-
-err:
-  ASN1_STRING_free(stmp);
-  X509_ALGOR_free(algtmp);
-  if (*palg) {
-    return 1;
-  }
-
-  return 0;
-}
-
-/* convert algorithm ID to EVP_MD, default SHA1 */
-static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
-  const EVP_MD *md;
-  if (!alg) {
-    return EVP_sha1();
-  }
-  md = EVP_get_digestbyobj(alg->algorithm);
-  if (md == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST);
-  }
-  return md;
-}
-
-/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
-static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
-  const EVP_MD *md;
-  if (!alg) {
-    return EVP_sha1();
-  }
-  /* Check mask and lookup mask hash algorithm */
-  if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
-    return NULL;
-  }
-  if (!maskHash) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER);
-    return NULL;
-  }
-  md = EVP_get_digestbyobj(maskHash->algorithm);
-  if (md == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST);
-    return NULL;
-  }
-  return md;
-}
-
-/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding
- * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */
-static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
-  const EVP_MD *sigmd, *mgf1md;
-  RSA_PSS_PARAMS *pss = NULL;
-  ASN1_STRING *os = NULL;
-  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
-  int saltlen, rv = 0;
-
-  if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) ||
-      !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) ||
-      !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) {
-    goto err;
-  }
-
-  if (saltlen == -1) {
-    saltlen = EVP_MD_size(sigmd);
-  } else if (saltlen == -2) {
-    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
-    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
-      saltlen--;
-    }
-  } else {
-    goto err;
-  }
-
-  pss = RSA_PSS_PARAMS_new();
-  if (!pss) {
-    goto err;
-  }
-
-  if (saltlen != 20) {
-    pss->saltLength = ASN1_INTEGER_new();
-    if (!pss->saltLength ||
-        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
-      goto err;
-    }
-  }
-
-  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
-      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
-    goto err;
-  }
-
-  /* Finally create string with pss parameter encoding. */
-  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
-    goto err;
-  }
-  rv = 1;
-
-err:
-  if (pss) {
-    RSA_PSS_PARAMS_free(pss);
-  }
-  if (rv) {
-    return os;
-  }
-  if (os) {
-    ASN1_STRING_free(os);
-  }
-  return NULL;
-}
-
-/* From PSS AlgorithmIdentifier set public key parameters. */
-static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
-  int ret = 0;
-  int saltlen;
-  const EVP_MD *mgf1md = NULL, *md = NULL;
-  RSA_PSS_PARAMS *pss;
-  X509_ALGOR *maskHash;
-  EVP_PKEY_CTX *pkctx;
-
-  /* Sanity check: make sure it is PSS */
-  if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
-    return 0;
-  }
-  /* Decode PSS parameters */
-  pss = rsa_pss_decode(sigalg, &maskHash);
-  if (pss == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_PARAMETERS);
-    goto err;
-  }
-
-  mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
-  if (!mgf1md) {
-    goto err;
-  }
-  md = rsa_algor_to_md(pss->hashAlgorithm);
-  if (!md) {
-    goto err;
-  }
-
-  saltlen = 20;
-  if (pss->saltLength) {
-    saltlen = ASN1_INTEGER_get(pss->saltLength);
-
-    /* Could perform more salt length sanity checks but the main
-     * RSA routines will trap other invalid values anyway. */
-    if (saltlen < 0) {
-      OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SALT_LENGTH);
-      goto err;
-    }
-  }
-
-  /* low-level routines support only trailer field 0xbc (value 1)
-   * and PKCS#1 says we should reject any other value anyway. */
-  if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_TRAILER);
-    goto err;
-  }
-
-  if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
-      !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
-      !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
-      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
-    goto err;
-  }
-
-  ret = 1;
-
-err:
-  RSA_PSS_PARAMS_free(pss);
-  if (maskHash) {
-    X509_ALGOR_free(maskHash);
-  }
-  return ret;
-}
-
-/* Customised RSA AlgorithmIdentifier handling. This is called when a signature
- * is encountered requiring special handling. We currently only handle PSS. */
-static int rsa_digest_verify_init_from_algorithm(EVP_MD_CTX *ctx,
-                                                 X509_ALGOR *sigalg,
-                                                 EVP_PKEY *pkey) {
-  /* Sanity check: make sure it is PSS */
-  if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
-    return 0;
-  }
-  return rsa_pss_to_ctx(ctx, sigalg, pkey);
-}
-
-static evp_digest_sign_algorithm_result_t rsa_digest_sign_algorithm(
-    EVP_MD_CTX *ctx, X509_ALGOR *sigalg) {
-  int pad_mode;
-  EVP_PKEY_CTX *pkctx = ctx->pctx;
-  if (!EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode)) {
-    return EVP_DIGEST_SIGN_ALGORITHM_ERROR;
-  }
-  if (pad_mode == RSA_PKCS1_PSS_PADDING) {
-    ASN1_STRING *os1 = rsa_ctx_to_pss(pkctx);
-    if (!os1) {
-      return EVP_DIGEST_SIGN_ALGORITHM_ERROR;
-    }
-    X509_ALGOR_set0(sigalg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1);
-    return EVP_DIGEST_SIGN_ALGORITHM_SUCCESS;
-  }
-
-  /* Other padding schemes use the default behavior. */
-  return EVP_DIGEST_SIGN_ALGORITHM_DEFAULT;
-}
-
 const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
   EVP_PKEY_RSA,
-  EVP_PKEY_RSA,
-  ASN1_PKEY_SIGPARAM_NULL,
-
-  "RSA",
+  /* 1.2.840.113549.1.1.1 */
+  {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9,
 
   rsa_pub_decode,
   rsa_pub_encode,
   rsa_pub_cmp,
-  rsa_pub_print,
 
   rsa_priv_decode,
   rsa_priv_encode,
-  rsa_priv_print,
 
   rsa_opaque,
   rsa_supports_digest,
@@ -724,14 +194,7 @@
   int_rsa_size,
   rsa_bits,
 
-  0,0,0,0,0,0,
+  0,0,0,
 
-  rsa_sig_print,
   int_rsa_free,
-
-  old_rsa_priv_decode,
-  old_rsa_priv_encode,
-
-  rsa_digest_verify_init_from_algorithm,
-  rsa_digest_sign_algorithm,
 };
diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc
index a39189f..438ab64 100644
--- a/src/crypto/evp/pbkdf_test.cc
+++ b/src/crypto/evp/pbkdf_test.cc
@@ -15,7 +15,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
@@ -189,7 +188,6 @@
 
 int main(void) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!TestEmptyPassword()) {
     fprintf(stderr, "TestEmptyPassword failed\n");
diff --git a/src/crypto/evp/print.c b/src/crypto/evp/print.c
new file mode 100644
index 0000000..56521ec
--- /dev/null
+++ b/src/crypto/evp/print.c
@@ -0,0 +1,527 @@
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/evp.h>
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/mem.h>
+#include <openssl/rsa.h>
+
+#include "../rsa/internal.h"
+
+
+static int bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                    uint8_t *buf, int off) {
+  if (num == NULL) {
+    return 1;
+  }
+
+  if (!BIO_indent(bp, off, 128)) {
+    return 0;
+  }
+  if (BN_is_zero(num)) {
+    if (BIO_printf(bp, "%s 0\n", number) <= 0) {
+      return 0;
+    }
+    return 1;
+  }
+
+  if (BN_num_bytes(num) <= sizeof(long)) {
+    const char *neg = BN_is_negative(num) ? "-" : "";
+    if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+                   (unsigned long)num->d[0], neg,
+                   (unsigned long)num->d[0]) <= 0) {
+      return 0;
+    }
+  } else {
+    buf[0] = 0;
+    if (BIO_printf(bp, "%s%s", number,
+                   (BN_is_negative(num)) ? " (Negative)" : "") <= 0) {
+      return 0;
+    }
+    int n = BN_bn2bin(num, &buf[1]);
+
+    if (buf[1] & 0x80) {
+      n++;
+    } else {
+      buf++;
+    }
+
+    int i;
+    for (i = 0; i < n; i++) {
+      if ((i % 15) == 0) {
+        if (BIO_puts(bp, "\n") <= 0 ||
+            !BIO_indent(bp, off + 4, 128)) {
+          return 0;
+        }
+      }
+      if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) {
+        return 0;
+      }
+    }
+    if (BIO_write(bp, "\n", 1) <= 0) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
+  size_t i;
+
+  if (!b) {
+    return;
+  }
+
+  i = BN_num_bytes(b);
+  if (*pbuflen < i) {
+    *pbuflen = i;
+  }
+}
+
+/* RSA keys. */
+
+static int do_rsa_print(BIO *out, const RSA *rsa, int off,
+                        int include_private) {
+  const char *s, *str;
+  uint8_t *m = NULL;
+  int ret = 0, mod_len = 0;
+  size_t buf_len = 0;
+
+  update_buflen(rsa->n, &buf_len);
+  update_buflen(rsa->e, &buf_len);
+
+  if (include_private) {
+    update_buflen(rsa->d, &buf_len);
+    update_buflen(rsa->p, &buf_len);
+    update_buflen(rsa->q, &buf_len);
+    update_buflen(rsa->dmp1, &buf_len);
+    update_buflen(rsa->dmq1, &buf_len);
+    update_buflen(rsa->iqmp, &buf_len);
+
+    if (rsa->additional_primes != NULL) {
+      size_t i;
+
+      for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+           i++) {
+        const RSA_additional_prime *ap =
+            sk_RSA_additional_prime_value(rsa->additional_primes, i);
+        update_buflen(ap->prime, &buf_len);
+        update_buflen(ap->exp, &buf_len);
+        update_buflen(ap->coeff, &buf_len);
+      }
+    }
+  }
+
+  m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
+  if (m == NULL) {
+    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
+
+  if (rsa->n != NULL) {
+    mod_len = BN_num_bits(rsa->n);
+  }
+
+  if (!BIO_indent(out, off, 128)) {
+    goto err;
+  }
+
+  if (include_private && rsa->d) {
+    if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
+      goto err;
+    }
+    str = "modulus:";
+    s = "publicExponent:";
+  } else {
+    if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
+      goto err;
+    }
+    str = "Modulus:";
+    s = "Exponent:";
+  }
+  if (!bn_print(out, str, rsa->n, m, off) ||
+      !bn_print(out, s, rsa->e, m, off)) {
+    goto err;
+  }
+
+  if (include_private) {
+    if (!bn_print(out, "privateExponent:", rsa->d, m, off) ||
+        !bn_print(out, "prime1:", rsa->p, m, off) ||
+        !bn_print(out, "prime2:", rsa->q, m, off) ||
+        !bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
+        !bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
+        !bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
+      goto err;
+    }
+
+    if (rsa->additional_primes != NULL &&
+        sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
+      size_t i;
+
+      if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
+        goto err;
+      }
+      for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+           i++) {
+        const RSA_additional_prime *ap =
+            sk_RSA_additional_prime_value(rsa->additional_primes, i);
+
+        if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
+                       (unsigned)(i + 3)) <= 0 ||
+            !bn_print(out, "prime:", ap->prime, m, off) ||
+            !bn_print(out, "exponent:", ap->exp, m, off) ||
+            !bn_print(out, "coeff:", ap->coeff, m, off)) {
+          goto err;
+        }
+      }
+    }
+  }
+  ret = 1;
+
+err:
+  OPENSSL_free(m);
+  return ret;
+}
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx) {
+  return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+}
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx) {
+  return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+}
+
+
+/* DSA keys. */
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
+  uint8_t *m = NULL;
+  int ret = 0;
+  size_t buf_len = 0;
+  const char *ktype = NULL;
+
+  const BIGNUM *priv_key, *pub_key;
+
+  priv_key = NULL;
+  if (ptype == 2) {
+    priv_key = x->priv_key;
+  }
+
+  pub_key = NULL;
+  if (ptype > 0) {
+    pub_key = x->pub_key;
+  }
+
+  ktype = "DSA-Parameters";
+  if (ptype == 2) {
+    ktype = "Private-Key";
+  } else if (ptype == 1) {
+    ktype = "Public-Key";
+  }
+
+  update_buflen(x->p, &buf_len);
+  update_buflen(x->q, &buf_len);
+  update_buflen(x->g, &buf_len);
+  update_buflen(priv_key, &buf_len);
+  update_buflen(pub_key, &buf_len);
+
+  m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
+  if (m == NULL) {
+    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
+
+  if (priv_key) {
+    if (!BIO_indent(bp, off, 128) ||
+        BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
+      goto err;
+    }
+  }
+
+  if (!bn_print(bp, "priv:", priv_key, m, off) ||
+      !bn_print(bp, "pub: ", pub_key, m, off) ||
+      !bn_print(bp, "P:   ", x->p, m, off) ||
+      !bn_print(bp, "Q:   ", x->q, m, off) ||
+      !bn_print(bp, "G:   ", x->g, m, off)) {
+    goto err;
+  }
+  ret = 1;
+
+err:
+  OPENSSL_free(m);
+  return ret;
+}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *ctx) {
+  return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx) {
+  return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+}
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx) {
+  return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+}
+
+
+/* EC keys. */
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
+  uint8_t *buffer = NULL;
+  const char *ecstr;
+  size_t buf_len = 0, i;
+  int ret = 0, reason = ERR_R_BIO_LIB;
+  BIGNUM *order = NULL;
+  BN_CTX *ctx = NULL;
+  const EC_GROUP *group;
+  const EC_POINT *public_key;
+  const BIGNUM *priv_key;
+  uint8_t *pub_key_bytes = NULL;
+  size_t pub_key_bytes_len = 0;
+
+  if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
+    reason = ERR_R_PASSED_NULL_PARAMETER;
+    goto err;
+  }
+
+  ctx = BN_CTX_new();
+  if (ctx == NULL) {
+    reason = ERR_R_MALLOC_FAILURE;
+    goto err;
+  }
+
+  if (ktype > 0) {
+    public_key = EC_KEY_get0_public_key(x);
+    if (public_key != NULL) {
+      pub_key_bytes_len = EC_POINT_point2oct(
+          group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
+      if (pub_key_bytes_len == 0) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+      }
+      pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
+      if (pub_key_bytes == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+      }
+      pub_key_bytes_len =
+          EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
+                             pub_key_bytes, pub_key_bytes_len, ctx);
+      if (pub_key_bytes_len == 0) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+      }
+      buf_len = pub_key_bytes_len;
+    }
+  }
+
+  if (ktype == 2) {
+    priv_key = EC_KEY_get0_private_key(x);
+    if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
+      buf_len = i;
+    }
+  } else {
+    priv_key = NULL;
+  }
+
+  if (ktype > 0) {
+    buf_len += 10;
+    if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
+      reason = ERR_R_MALLOC_FAILURE;
+      goto err;
+    }
+  }
+  if (ktype == 2) {
+    ecstr = "Private-Key";
+  } else if (ktype == 1) {
+    ecstr = "Public-Key";
+  } else {
+    ecstr = "ECDSA-Parameters";
+  }
+
+  if (!BIO_indent(bp, off, 128)) {
+    goto err;
+  }
+  order = BN_new();
+  if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
+      BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
+    goto err;
+  }
+
+  if ((priv_key != NULL) &&
+      !bn_print(bp, "priv:", priv_key, buffer, off)) {
+    goto err;
+  }
+  if (pub_key_bytes != NULL) {
+    BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
+  }
+  /* TODO(fork): implement */
+  /*
+  if (!ECPKParameters_print(bp, group, off))
+    goto err; */
+  ret = 1;
+
+err:
+  if (!ret) {
+    OPENSSL_PUT_ERROR(EVP, reason);
+  }
+  OPENSSL_free(pub_key_bytes);
+  BN_free(order);
+  BN_CTX_free(ctx);
+  OPENSSL_free(buffer);
+  return ret;
+}
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                             ASN1_PCTX *ctx) {
+  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+}
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *ctx) {
+  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+}
+
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                            ASN1_PCTX *ctx) {
+  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+}
+
+
+typedef struct {
+  int type;
+  int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
+  int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+                    ASN1_PCTX *pctx);
+  int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+                     ASN1_PCTX *pctx);
+} EVP_PKEY_PRINT_METHOD;
+
+static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
+    {
+        EVP_PKEY_RSA,
+        rsa_pub_print,
+        rsa_priv_print,
+        NULL /* param_print */,
+    },
+    {
+        EVP_PKEY_DSA,
+        dsa_pub_print,
+        dsa_priv_print,
+        dsa_param_print,
+    },
+    {
+        EVP_PKEY_EC,
+        eckey_pub_print,
+        eckey_priv_print,
+        eckey_param_print,
+    },
+};
+
+static size_t kPrintMethodsLen =
+    sizeof(kPrintMethods) / sizeof(kPrintMethods[0]);
+
+static EVP_PKEY_PRINT_METHOD *find_method(int type) {
+  size_t i;
+  for (i = 0; i < kPrintMethodsLen; i++) {
+    if (kPrintMethods[i].type == type) {
+      return &kPrintMethods[i];
+    }
+  }
+  return NULL;
+}
+
+static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
+                             const char *kstr) {
+  BIO_indent(out, indent, 128);
+  BIO_printf(out, "%s algorithm unsupported\n", kstr);
+  return 1;
+}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *pctx) {
+  EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+  if (method != NULL && method->pub_print != NULL) {
+    return method->pub_print(out, pkey, indent, pctx);
+  }
+  return print_unsupported(out, pkey, indent, "Public Key");
+}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *pctx) {
+  EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+  if (method != NULL && method->priv_print != NULL) {
+    return method->priv_print(out, pkey, indent, pctx);
+  }
+  return print_unsupported(out, pkey, indent, "Private Key");
+}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *pctx) {
+  EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+  if (method != NULL && method->param_print != NULL) {
+    return method->param_print(out, pkey, indent, pctx);
+  }
+  return print_unsupported(out, pkey, indent, "Parameters");
+}
diff --git a/src/crypto/hkdf/hkdf_test.c b/src/crypto/hkdf/hkdf_test.c
index 63070dc..b11061a 100644
--- a/src/crypto/hkdf/hkdf_test.c
+++ b/src/crypto/hkdf/hkdf_test.c
@@ -20,6 +20,8 @@
 #include <openssl/err.h>
 #include <openssl/hkdf.h>
 
+#include "../test/test_util.h"
+
 
 typedef struct {
   const EVP_MD *(*md_func)(void);
@@ -216,7 +218,6 @@
   size_t i;
 
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   for (i = 0; i < sizeof(kTests) / sizeof(kTests[0]); i++) {
     const hkdf_test_vector_t *test = &kTests[i];
@@ -227,8 +228,9 @@
       return 1;
     }
     if (memcmp(buf, test->out, test->out_len) != 0) {
-      fprintf(stderr, "%u: Resulting key material does not match test vector\n",
-              (unsigned)i);
+      fprintf(stderr, "%" OPENSSL_PR_SIZE_T
+                      ": Resulting key material does not match test vector\n",
+              i);
       return 1;
     }
   }
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index be2dcce..bccc5c0 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -59,6 +59,7 @@
 #include <assert.h>
 #include <string.h>
 
+#include <openssl/digest.h>
 #include <openssl/mem.h>
 
 
@@ -115,8 +116,8 @@
    * case. Fix to API to avoid this. */
   if (md != ctx->md || key != NULL) {
     size_t i;
-    uint8_t pad[HMAC_MAX_MD_CBLOCK];
-    uint8_t key_block[HMAC_MAX_MD_CBLOCK];
+    uint8_t pad[EVP_MAX_MD_BLOCK_SIZE];
+    uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE];
     unsigned key_block_len;
 
     size_t block_size = EVP_MD_block_size(md);
@@ -134,11 +135,11 @@
       key_block_len = (unsigned)key_len;
     }
     /* Keys are then padded with zeros. */
-    if (key_block_len != HMAC_MAX_MD_CBLOCK) {
+    if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) {
       memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len);
     }
 
-    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+    for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
       pad[i] = 0x36 ^ key_block[i];
     }
     if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) ||
@@ -146,7 +147,7 @@
       return 0;
     }
 
-    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+    for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
       pad[i] = 0x5c ^ key_block[i];
     }
     if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) ||
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index bf45349..ded43fe 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -112,6 +112,15 @@
 #include <openssl/ex_data.h>
 #include <openssl/thread.h>
 
+#if defined(_MSC_VER)
+#if !defined(__cplusplus) || _MSC_VER < 1900
+#define alignas(x) __declspec(align(x))
+#define alignof __alignof
+#endif
+#else
+#include <stdalign.h>
+#endif
+
 #if defined(OPENSSL_NO_THREADS)
 #elif defined(OPENSSL_WINDOWS)
 #pragma warning(push, 3)
@@ -126,48 +135,6 @@
 #endif
 
 
-/* MSVC's C4701 warning about the use of *potentially*--as opposed to
- * *definitely*--uninitialized values sometimes has false positives. Usually
- * the false positives can and should be worked around by simplifying the
- * control flow. When that is not practical, annotate the function containing
- * the code that triggers the warning with
- * OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS after its parameters:
- *
- *    void f() OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS {
- *       ...
- *    }
- *
- * Note that MSVC's control flow analysis seems to operate on a whole-function
- * basis, so the annotation must be placed on the entire function, not just a
- * block within the function. */
-#if defined(_MSC_VER)
-#define OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS \
-        __pragma(warning(suppress:4701))
-#else
-#define OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-#endif
-
-/* MSVC will sometimes correctly detect unreachable code and issue a warning,
- * which breaks the build since we treat errors as warnings, in some rare cases
- * where we want to allow the dead code to continue to exist. In these
- * situations, annotate the function containing the unreachable code with
- * OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS after its parameters:
- *
- *    void f() OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
- *       ...
- *    }
- *
- * Note that MSVC's reachability analysis seems to operate on a whole-function
- * basis, so the annotation must be placed on the entire function, not just a
- * block within the function. */
-#if defined(_MSC_VER)
-#define OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS \
-        __pragma(warning(suppress:4702))
-#else
-#define OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS
-#endif
-
-
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
     defined(OPENSSL_AARCH64)
 /* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
@@ -179,6 +146,12 @@
 #endif
 
 
+#if !defined(_MSC_VER) && defined(OPENSSL_64_BIT)
+typedef __int128_t int128_t;
+typedef __uint128_t uint128_t;
+#endif
+
+
 /* Constant-time utility functions.
  *
  * The following methods return a bitmask of all ones (0xff...f) for true and 0
@@ -321,12 +294,22 @@
 
 /* Thread-safe initialisation. */
 
+/* Android's mingw-w64 has some prototypes for INIT_ONCE, but is missing
+ * others. Work around the missing ones.
+ *
+ * TODO(davidben): Remove this once Android's mingw-w64 is upgraded. See
+ * b/26523949. */
+#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
+typedef RTL_RUN_ONCE INIT_ONCE;
+#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+#endif
+
 #if defined(OPENSSL_NO_THREADS)
 typedef uint32_t CRYPTO_once_t;
 #define CRYPTO_ONCE_INIT 0
 #elif defined(OPENSSL_WINDOWS)
-typedef LONG CRYPTO_once_t;
-#define CRYPTO_ONCE_INIT 0
+typedef INIT_ONCE CRYPTO_once_t;
+#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT
 #else
 typedef pthread_once_t CRYPTO_once_t;
 #define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT
@@ -380,8 +363,10 @@
  * automatically by |CRYPTO_STATIC_MUTEX_lock_*|. */
 
 #if defined(OPENSSL_NO_THREADS)
-struct CRYPTO_STATIC_MUTEX {};
-#define CRYPTO_STATIC_MUTEX_INIT {}
+struct CRYPTO_STATIC_MUTEX {
+  char padding;  /* Empty structs have different sizes in C and C++. */
+};
+#define CRYPTO_STATIC_MUTEX_INIT { 0 }
 #elif defined(OPENSSL_WINDOWS)
 struct CRYPTO_STATIC_MUTEX {
   CRYPTO_once_t once;
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index 86a540b..f79da9f 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -60,6 +60,15 @@
 #include <string.h>
 
 
+uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out) {
+  MD4_CTX ctx;
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, data, len);
+  MD4_Final(out, &ctx);
+
+  return out;
+}
+
 /* Implemented from RFC1186 The MD4 Message-Digest Algorithm. */
 
 int MD4_Init(MD4_CTX *md4) {
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index edd14a8..df8e0e3 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -104,9 +104,9 @@
 
 void OPENSSL_cleanse(void *ptr, size_t len) {
 #if defined(OPENSSL_WINDOWS)
-	SecureZeroMemory(ptr, len);
+  SecureZeroMemory(ptr, len);
 #else
-	memset(ptr, 0, len);
+  memset(ptr, 0, len);
 
 #if !defined(OPENSSL_NO_ASM)
   /* As best as we can tell, this is sufficient to break any optimisations that
diff --git a/src/crypto/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
index 0ca89c7..5d58bbb 100644
--- a/src/crypto/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
@@ -41,11 +41,12 @@
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
+# This must be kept in sync with |$avx| in ghash-x86_64.pl; otherwise tags will
+# be computed incorrectly.
+#
 # In upstream, this is controlled by shelling out to the compiler to check
 # versions, but BoringSSL is intended to be used with pre-generated perlasm
 # output, so this isn't useful anyway.
-#
-# TODO(davidben): Enable this after testing. $avx goes up to 2.
 $avx = 0;
 
 open OUT,"| \"$^X\" $xlate $flavour $output";
@@ -96,6 +97,23 @@
 	  vpxor		$rndkey,$inout3,$inout3
 	  vmovups	0x10-0x80($key),$T2	# borrow $T2 for $rndkey
 	vpclmulqdq	\$0x01,$Hkey,$Z3,$Z2
+
+	# At this point, the current block of 96 (0x60) bytes has already been
+	# loaded into registers. Concurrently with processing it, we want to
+	# load the next 96 bytes of input for the next round. Obviously, we can
+	# only do this if there are at least 96 more bytes of input beyond the
+	# input we're currently processing, or else we'd read past the end of
+	# the input buffer. Here, we set |%r12| to 96 if there are at least 96
+	# bytes of input beyond the 96 bytes we're already processing, and we
+	# set |%r12| to 0 otherwise. In the case where we set |%r12| to 96,
+	# we'll read in the next block so that it is in registers for the next
+	# loop iteration. In the case where we set |%r12| to 0, we'll re-read
+	# the current block and then ignore what we re-read.
+	#
+	# At this point, |$in0| points to the current (already read into
+	# registers) block, and |$end0| points to 2*96 bytes before the end of
+	# the input. Thus, |$in0| > |$end0| means that we do not have the next
+	# 96-byte block to read in, and |$in0| <= |$end0| means we do.
 	xor		%r12,%r12
 	cmp		$in0,$end0
 
@@ -388,6 +406,9 @@
 .align	32
 aesni_gcm_decrypt:
 	xor	$ret,$ret
+
+	# We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60)
+	# bytes of input.
 	cmp	\$0x60,$len			# minimal accepted length
 	jb	.Lgcm_dec_abort
 
@@ -442,7 +463,15 @@
 	vmovdqu		0x50($inp),$Z3		# I[5]
 	lea		($inp),$in0
 	vmovdqu		0x40($inp),$Z0
+
+	# |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+	# bytes before the end of the input. Note, in particular, that this is
+	# correct even if |$len| is not an even multiple of 96 or 16. XXX: This
+	# seems to require that |$inp| + |$len| >= 2*96 (0xc0); i.e. |$inp| must
+	# not be near the very beginning of the address space when |$len| < 2*96
+	# (0xc0).
 	lea		-0xc0($inp,$len),$end0
+
 	vmovdqu		0x30($inp),$Z1
 	shr		\$4,$len
 	xor		$ret,$ret
@@ -477,7 +506,7 @@
 ___
 $code.=<<___ if ($win64);
 	movaps	-0xd8(%rax),%xmm6
-	movaps	-0xd8(%rax),%xmm7
+	movaps	-0xc8(%rax),%xmm7
 	movaps	-0xb8(%rax),%xmm8
 	movaps	-0xa8(%rax),%xmm9
 	movaps	-0x98(%rax),%xmm10
@@ -598,6 +627,10 @@
 .align	32
 aesni_gcm_encrypt:
 	xor	$ret,$ret
+
+	# We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of
+	# input. Then we call |_aesni_ctr32_ghash_6x|, which requires at
+	# least 96 more bytes of input.
 	cmp	\$0x60*3,$len			# minimal accepted length
 	jb	.Lgcm_enc_abort
 
@@ -647,7 +680,16 @@
 .Lenc_no_key_aliasing:
 
 	lea		($out),$in0
+
+	# |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+	# bytes before the end of the input. Note, in particular, that this is
+	# correct even if |$len| is not an even multiple of 96 or 16. Unlike in
+	# the decryption case, there's no caveat that |$out| must not be near
+	# the very beginning of the address space, because we know that
+	# |$len| >= 3*96 from the check above, and so we know
+	# |$out| + |$len| >= 2*96 (0xc0).
 	lea		-0xc0($out,$len),$end0
+
 	shr		\$4,$len
 
 	call		_aesni_ctr32_6x
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index d328822..bb0dba5 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -163,7 +163,6 @@
 .size	rem_4bit_get,.-rem_4bit_get
 
 .global	gcm_ghash_4bit
-.hidden	gcm_ghash_4bit
 .type	gcm_ghash_4bit,%function
 gcm_ghash_4bit:
 	sub	r12,pc,#8
@@ -260,7 +259,6 @@
 .size	gcm_ghash_4bit,.-gcm_ghash_4bit
 
 .global	gcm_gmult_4bit
-.hidden	gcm_gmult_4bit
 .type	gcm_gmult_4bit,%function
 gcm_gmult_4bit:
 	stmdb	sp!,{r4-r11,lr}
@@ -391,7 +389,6 @@
 .fpu	neon
 
 .global	gcm_init_neon
-.hidden	gcm_init_neon
 .type	gcm_init_neon,%function
 .align	4
 gcm_init_neon:
@@ -413,7 +410,6 @@
 .size	gcm_init_neon,.-gcm_init_neon
 
 .global	gcm_gmult_neon
-.hidden	gcm_gmult_neon
 .type	gcm_gmult_neon,%function
 .align	4
 gcm_gmult_neon:
@@ -432,7 +428,6 @@
 .size	gcm_gmult_neon,.-gcm_gmult_neon
 
 .global	gcm_ghash_neon
-.hidden	gcm_ghash_neon
 .type	gcm_ghash_neon,%function
 .align	4
 gcm_ghash_neon:
diff --git a/src/crypto/modes/asm/ghash-x86_64.pl b/src/crypto/modes/asm/ghash-x86_64.pl
index e42ca32..5a11fb9 100644
--- a/src/crypto/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/modes/asm/ghash-x86_64.pl
@@ -90,11 +90,12 @@
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
+# This must be kept in sync with |$avx| in aesni-gcm-x86_64.pl; otherwise tags
+# will be computed incorrectly.
+#
 # In upstream, this is controlled by shelling out to the compiler to check
 # versions, but BoringSSL is intended to be used with pre-generated perlasm
 # output, so this isn't useful anyway.
-#
-# TODO(davidben): Enable this after testing. $avx goes up to 2.
 $avx = 0;
 
 open OUT,"| \"$^X\" $xlate $flavour $output";
diff --git a/src/crypto/modes/cfb.c b/src/crypto/modes/cfb.c
index c58614b..51b883e 100644
--- a/src/crypto/modes/cfb.c
+++ b/src/crypto/modes/cfb.c
@@ -57,14 +57,13 @@
 OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
 
 void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                           const void *key, uint8_t ivec[16], int *num, int enc,
-                           block128_f block) {
-  unsigned int n;
+                           const void *key, uint8_t ivec[16], unsigned *num,
+                           int enc, block128_f block) {
   size_t l = 0;
 
   assert(in && out && key && ivec && num);
 
-  n = *num;
+  unsigned n = *num;
 
   if (enc) {
     while (n && len) {
@@ -199,7 +198,7 @@
 
 /* N.B. This expects the input to be packed, MS bit first */
 void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
-                             const void *key, uint8_t ivec[16], int *num,
+                             const void *key, uint8_t ivec[16], unsigned *num,
                              int enc, block128_f block) {
   size_t n;
   uint8_t c[1], d[1];
@@ -217,7 +216,7 @@
 
 void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
                              size_t length, const void *key,
-                             unsigned char ivec[16], int *num, int enc,
+                             unsigned char ivec[16], unsigned *num, int enc,
                              block128_f block) {
   size_t n;
 
diff --git a/src/crypto/modes/ctr.c b/src/crypto/modes/ctr.c
index 52ff048..b84e72c 100644
--- a/src/crypto/modes/ctr.c
+++ b/src/crypto/modes/ctr.c
@@ -59,17 +59,13 @@
 
 /* increment counter (128-bit int) by 1 */
 static void ctr128_inc(uint8_t *counter) {
-  uint32_t n = 16;
-  uint8_t c;
+  uint32_t n = 16, c = 1;
 
   do {
     --n;
-    c = counter[n];
-    ++c;
-    counter[n] = c;
-    if (c) {
-      return;
-    }
+    c += counter[n];
+    counter[n] = (uint8_t) c;
+    c >>= 8;
   } while (n);
 }
 
@@ -104,7 +100,7 @@
   }
 
 #if STRICT_ALIGNMENT
-  if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+  if (((size_t)in | (size_t)out | (size_t)ecount_buf) % sizeof(size_t) != 0) {
     size_t l = 0;
     while (l < len) {
       if (n == 0) {
@@ -124,8 +120,9 @@
   while (len >= 16) {
     (*block)(ivec, ecount_buf, key);
     ctr128_inc(ivec);
-    for (; n < 16; n += sizeof(size_t)) {
-      *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
+    for (n = 0; n < 16; n += sizeof(size_t)) {
+      *(size_t *)(out + n) = *(const size_t *)(in + n) ^
+                             *(const size_t *)(ecount_buf + n);
     }
     len -= 16;
     out += 16;
@@ -145,17 +142,13 @@
 
 /* increment upper 96 bits of 128-bit counter by 1 */
 static void ctr96_inc(uint8_t *counter) {
-  uint32_t n = 12;
-  uint8_t c;
+  uint32_t n = 12, c = 1;
 
   do {
     --n;
-    c = counter[n];
-    ++c;
-    counter[n] = c;
-    if (c) {
-      return;
-    }
+    c += counter[n];
+    counter[n] = (uint8_t) c;
+    c >>= 8;
   } while (n);
 }
 
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index 65451a6..b857131 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -55,6 +55,7 @@
 #include <openssl/cpu.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 #if !defined(OPENSSL_NO_ASM) &&                         \
@@ -337,7 +338,18 @@
 #else
 void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]);
 void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]);
-void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, size_t len);
+void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
+                   size_t len);
+#define AESNI_GCM
+static int aesni_gcm_enabled(GCM128_CONTEXT *ctx, ctr128_f stream) {
+  return stream == aesni_ctr32_encrypt_blocks &&
+         ctx->ghash == gcm_ghash_avx;
+}
+
+size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+                         const void *key, uint8_t ivec[16], uint64_t *Xi);
+size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
+                         const void *key, uint8_t ivec[16], uint64_t *Xi);
 #endif
 
 #if defined(OPENSSL_X86)
@@ -380,14 +392,14 @@
 static int neon_capable(void) {
   return 0;
 }
-void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
+static void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
   abort();
 }
-void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) {
+static void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) {
   abort();
 }
-void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
-                    size_t len) {
+static void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16],
+                           const uint8_t *inp, size_t len) {
   abort();
 }
 #endif
@@ -405,17 +417,6 @@
 #endif
 #endif
 
-GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key, block128_f block) {
-  GCM128_CONTEXT *ret;
-
-  ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT));
-  if (ret != NULL) {
-    CRYPTO_gcm128_init(ret, key, block);
-  }
-
-  return ret;
-}
-
 void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
                         block128_f block) {
   const union {
@@ -606,7 +607,8 @@
   }
 
 #ifdef GHASH
-  if ((i = (len & (size_t) - 16))) {
+  i = len & kSizeTWithoutLower4Bits;
+  if (i != 0) {
     GHASH(ctx, aad, i);
     aad += i;
     len -= i;
@@ -895,7 +897,8 @@
     }
     len -= GHASH_CHUNK;
   }
-  if ((i = (len & (size_t) - 16))) {
+  i = len & kSizeTWithoutLower4Bits;
+  if (i != 0) {
     GHASH(ctx, in, i);
     while (len >= 16) {
       size_t *out_t = (size_t *)out;
@@ -989,12 +992,6 @@
     ctx->ares = 0;
   }
 
-  if (is_endian.little) {
-    ctr = GETU32(ctx->Yi.c + 12);
-  } else {
-    ctr = ctx->Yi.d[3];
-  }
-
   n = ctx->mres;
   if (n) {
     while (n && len) {
@@ -1009,6 +1006,24 @@
       return 1;
     }
   }
+
+#if defined(AESNI_GCM)
+  if (aesni_gcm_enabled(ctx, stream)) {
+    /* |aesni_gcm_encrypt| may not process all the input given to it. It may
+     * not process *any* of its input if it is deemed too small. */
+    size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
+    in += bulk;
+    out += bulk;
+    len -= bulk;
+  }
+#endif
+
+  if (is_endian.little) {
+    ctr = GETU32(ctx->Yi.c + 12);
+  } else {
+    ctr = ctx->Yi.d[3];
+  }
+
 #if defined(GHASH)
   while (len >= GHASH_CHUNK) {
     (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
@@ -1098,12 +1113,6 @@
     ctx->ares = 0;
   }
 
-  if (is_endian.little) {
-    ctr = GETU32(ctx->Yi.c + 12);
-  } else {
-    ctr = ctx->Yi.d[3];
-  }
-
   n = ctx->mres;
   if (n) {
     while (n && len) {
@@ -1120,6 +1129,24 @@
       return 1;
     }
   }
+
+#if defined(AESNI_GCM)
+  if (aesni_gcm_enabled(ctx, stream)) {
+    /* |aesni_gcm_decrypt| may not process all the input given to it. It may
+     * not process *any* of its input if it is deemed too small. */
+    size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
+    in += bulk;
+    out += bulk;
+    len -= bulk;
+  }
+#endif
+
+  if (is_endian.little) {
+    ctr = GETU32(ctx->Yi.c + 12);
+  } else {
+    ctr = ctx->Yi.d[3];
+  }
+
 #if defined(GHASH)
   while (len >= GHASH_CHUNK) {
     GHASH(ctx, in, GHASH_CHUNK);
@@ -1233,13 +1260,6 @@
   memcpy(tag, ctx->Xi.c, len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
 }
 
-void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) {
-  if (ctx) {
-    OPENSSL_cleanse(ctx, sizeof(*ctx));
-    OPENSSL_free(ctx);
-  }
-}
-
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
 int crypto_gcm_clmul_enabled(void) {
 #ifdef GHASH_ASM
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index 9414ac6..56639e6 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -282,8 +282,10 @@
     uint8_t v, v2;
     if (!from_hex(&v, in[i]) ||
         !from_hex(&v2, in[i+1])) {
-      fprintf(stderr, "%u: invalid hex digit in %s around offset %u.\n",
-              test_num, description, (unsigned)i);
+      fprintf(stderr,
+              "%u: invalid hex digit in %s around offset %" OPENSSL_PR_SIZE_T
+              ".\n",
+              test_num, description, i);
       goto err;
     }
     buf[i/2] = (v << 4) | v2;
@@ -336,7 +338,7 @@
   }
 
   out = OPENSSL_malloc(plaintext_len);
-  if (out == NULL) {
+  if (plaintext_len != 0 && out == NULL) {
     goto out;
   }
   if (AES_set_encrypt_key(key, key_len*8, &aes_key)) {
diff --git a/src/crypto/modes/internal.h b/src/crypto/modes/internal.h
index 7255a7c..b46e836 100644
--- a/src/crypto/modes/internal.h
+++ b/src/crypto/modes/internal.h
@@ -179,16 +179,6 @@
   block128_f block;
 };
 
-struct ccm128_context {
-  union {
-    uint64_t u[2];
-    uint8_t c[16];
-  } nonce, cmac;
-  uint64_t blocks;
-  block128_f block;
-  void *key;
-};
-
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
 /* crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is
  * used. */
@@ -210,7 +200,7 @@
  * incremented by this function. */
 void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
                            const void *key, uint8_t ivec[16],
-                           uint8_t ecount_buf[16], unsigned int *num,
+                           uint8_t ecount_buf[16], unsigned *num,
                            block128_f block);
 
 /* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
@@ -219,7 +209,7 @@
  * function. */
 void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len,
                                  const void *key, uint8_t ivec[16],
-                                 uint8_t ecount_buf[16], unsigned int *num,
+                                 uint8_t ecount_buf[16], unsigned *num,
                                  ctr128_f ctr);
 
 
@@ -232,11 +222,6 @@
 
 typedef struct gcm128_context GCM128_CONTEXT;
 
-/* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
- * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
-OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key,
-                                                 block128_f block);
-
 /* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with
  * the given key. */
 OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
@@ -297,9 +282,6 @@
 OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
                                       size_t len);
 
-/* CRYPTO_gcm128_release clears and frees |ctx|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
-
 
 /* CBC. */
 
@@ -331,7 +313,7 @@
  * call. */
 void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
                            size_t len, const void *key, uint8_t ivec[16],
-                           int *num, block128_f block);
+                           unsigned *num, block128_f block);
 
 
 /* CFB. */
@@ -341,21 +323,21 @@
  * |len| be a multiple of any value and any partial blocks are stored in |ivec|
  * and |*num|, the latter must be zero before the initial call. */
 void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                           const void *key, uint8_t ivec[16], int *num, int enc,
-                           block128_f block);
+                           const void *key, uint8_t ivec[16], unsigned *num,
+                           int enc, block128_f block);
 
 /* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
  * from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
  * |num| should be set to zero. */
 void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                             const void *key, uint8_t ivec[16], int *num,
+                             const void *key, uint8_t ivec[16], unsigned *num,
                              int enc, block128_f block);
 
 /* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
  * from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
  * |num| should be set to zero. */
 void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
-                             const void *key, uint8_t ivec[16], int *num,
+                             const void *key, uint8_t ivec[16], unsigned *num,
                              int enc, block128_f block);
 
 size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
@@ -363,6 +345,12 @@
                                    block128_f block);
 
 
+#if !defined(OPENSSL_NO_ASM) && \
+    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
+void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
+                                const void *key, const uint8_t *ivec);
+#endif
+
 #if defined(__cplusplus)
 } /* extern C */
 #endif
diff --git a/src/crypto/modes/ofb.c b/src/crypto/modes/ofb.c
index 63c3165..2c5bdc9 100644
--- a/src/crypto/modes/ofb.c
+++ b/src/crypto/modes/ofb.c
@@ -56,13 +56,11 @@
 OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
 
 void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                           const void *key, uint8_t ivec[16], int *num,
+                           const void *key, uint8_t ivec[16], unsigned *num,
                            block128_f block) {
-  unsigned int n;
-
   assert(in && out && key && ivec && num);
 
-  n = *num;
+  unsigned n = *num;
 
   while (n && len) {
     *(out++) = *(in++) ^ ivec[n];
diff --git a/src/crypto/newhope/CMakeLists.txt b/src/crypto/newhope/CMakeLists.txt
new file mode 100644
index 0000000..385cd6a
--- /dev/null
+++ b/src/crypto/newhope/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_library(
+  newhope
+
+  OBJECT
+
+  error_correction.c
+  newhope.c
+  ntt.c
+  poly.c
+  precomp.c
+  reduce.c
+)
+
+add_executable(
+  newhope_test
+
+  newhope_test.c
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(newhope_test crypto)
+add_dependencies(all_tests newhope_test)
diff --git a/src/crypto/newhope/error_correction.c b/src/crypto/newhope/error_correction.c
new file mode 100644
index 0000000..e4ac1c2
--- /dev/null
+++ b/src/crypto/newhope/error_correction.c
@@ -0,0 +1,134 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <string.h>
+
+#include <openssl/base.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+/* See paper for details on the error reconciliation */
+
+static int32_t abs_32(int32_t v) {
+  int32_t mask = v >> 31;
+  return (v ^ mask) - mask;
+}
+
+static int32_t f(int32_t* v0, int32_t* v1, int32_t x) {
+  int32_t xit, t, r, b;
+
+  /* Next 6 lines compute t = x/PARAM_Q */
+  b = x * 2730;
+  t = b >> 25;
+  b = x - t * 12289;
+  b = 12288 - b;
+  b >>= 31;
+  t -= b;
+
+  r = t & 1;
+  xit = (t >> 1);
+  *v0 = xit + r; /* v0 = round(x/(2*PARAM_Q)) */
+
+  t -= 1;
+  r = t & 1;
+  *v1 = (t >> 1) + r;
+
+  return abs_32(x - ((*v0) * 2 * PARAM_Q));
+}
+
+static int32_t g(int32_t x) {
+  int32_t t, c, b;
+
+  /* Next 6 lines compute t = x/(4*PARAM_Q); */
+  b = x * 2730;
+  t = b >> 27;
+  b = x - t * 49156;
+  b = 49155 - b;
+  b >>= 31;
+  t -= b;
+
+  c = t & 1;
+  t = (t >> 1) + c; /* t = round(x/(8*PARAM_Q)) */
+
+  t *= 8 * PARAM_Q;
+
+  return abs_32(t - x);
+}
+
+static int16_t LDDecode(int32_t xi0, int32_t xi1, int32_t xi2, int32_t xi3) {
+  int32_t t;
+
+  t = g(xi0);
+  t += g(xi1);
+  t += g(xi2);
+  t += g(xi3);
+
+  t -= 8 * PARAM_Q;
+  t >>= 31;
+  return t & 1;
+}
+
+void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v) {
+  int32_t v0[4], v1[4], v_tmp[4], k;
+  uint8_t rbit;
+  uint8_t rand[32];
+  unsigned i;
+
+  /* The reference implementation calls ChaCha20 here. */
+  RAND_bytes(rand, sizeof(rand));
+
+  for (i = 0; i < 256; i++) {
+    rbit = (rand[i >> 3] >> (i & 7)) & 1;
+
+    k = f(v0 + 0, v1 + 0, 8 * v->coeffs[0 + i] + 4 * rbit);
+    k += f(v0 + 1, v1 + 1, 8 * v->coeffs[256 + i] + 4 * rbit);
+    k += f(v0 + 2, v1 + 2, 8 * v->coeffs[512 + i] + 4 * rbit);
+    k += f(v0 + 3, v1 + 3, 8 * v->coeffs[768 + i] + 4 * rbit);
+
+    k = (2 * PARAM_Q - 1 - k) >> 31;
+
+    v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
+    v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
+    v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
+    v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
+
+    c->coeffs[0 + i] = (v_tmp[0] - v_tmp[3]) & 3;
+    c->coeffs[256 + i] = (v_tmp[1] - v_tmp[3]) & 3;
+    c->coeffs[512 + i] = (v_tmp[2] - v_tmp[3]) & 3;
+    c->coeffs[768 + i] = (-k + 2 * v_tmp[3]) & 3;
+  }
+}
+
+void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
+                       const NEWHOPE_POLY* c) {
+  int i;
+  int32_t tmp[4];
+
+  memset(key, 0, KEY_LENGTH);
+
+  for (i = 0; i < 256; i++) {
+    tmp[0] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[0 + i] -
+             PARAM_Q * (2 * c->coeffs[0 + i] + c->coeffs[768 + i]);
+    tmp[1] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[256 + i] -
+             PARAM_Q * (2 * c->coeffs[256 + i] + c->coeffs[768 + i]);
+    tmp[2] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[512 + i] -
+             PARAM_Q * (2 * c->coeffs[512 + i] + c->coeffs[768 + i]);
+    tmp[3] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[768 + i] -
+             PARAM_Q * (c->coeffs[768 + i]);
+
+    key[i >> 3] |= LDDecode(tmp[0], tmp[1], tmp[2], tmp[3]) << (i & 7);
+  }
+}
diff --git a/src/crypto/newhope/internal.h b/src/crypto/newhope/internal.h
new file mode 100644
index 0000000..a5473d8
--- /dev/null
+++ b/src/crypto/newhope/internal.h
@@ -0,0 +1,95 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_NEWHOPE_INTERNAL_H
+#define OPENSSL_HEADER_NEWHOPE_INTERNAL_H
+
+#include <openssl/newhope.h>
+#include <openssl/sha.h>
+
+#include "../internal.h"
+
+
+/* The number of polynomial coefficients. */
+#define PARAM_N 1024
+
+/* The width the noise distribution. */
+#define PARAM_K 16
+
+/* Modulus. */
+#define PARAM_Q 12289
+
+/* KEY_LENGTH is the size of the result of the key agreement. This result is
+ * not exposed to callers: instead, it is whitened with SHA-256, whose output
+ * happens to be the same size. */
+#define KEY_LENGTH 32
+
+/* Polynomial coefficients in unpacked form. */
+struct newhope_poly_st {
+  alignas(32) uint16_t coeffs[PARAM_N];
+};
+
+/* The packed form is 14 bits per coefficient, or 1792 bytes. */
+#define POLY_BYTES ((1024 * 14) / 8)
+
+/* SEED_LENGTH is the length of the AES-CTR seed used to derive a polynomial. */
+#define SEED_LENGTH 32
+
+/* newhope_poly_uniform generates the polynomial |a| using AES-CTR mode with the
+ * seed
+ * |seed|. (In the reference implementation this was done with SHAKE-128.) */
+void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed);
+
+/* newhope_poly_getnoise sets |r| to a random polynomial where the coefficients
+ * are
+ * sampled from the noise distribution. (In the reference implementation, this
+ * is given a random seed and a nonce.)*/
+void newhope_poly_getnoise(NEWHOPE_POLY* r);
+
+/* newhope_poly_frombytes unpacks the packed polynomial coefficients in |a| into
+ * |r|. */
+void newhope_poly_frombytes(NEWHOPE_POLY* r, const uint8_t* a);
+
+/* newhope_poly_tobytes packs the polynomial |p| into the compact representation
+ * |r|. */
+void newhope_poly_tobytes(uint8_t* r, const NEWHOPE_POLY* p);
+
+void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v);
+
+/* newhope_reconcile performs the error-reconciliation step using the input |v|
+ * and
+ * reconciliation data |c|, writing the resulting key to |key|. */
+void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
+                       const NEWHOPE_POLY* c);
+
+/* newhope_poly_ntt performs NTT(r) in-place. */
+void newhope_poly_ntt(NEWHOPE_POLY* r);
+
+/* newhope_poly_invntt performs the inverse of NTT(r) in-place. */
+void newhope_poly_invntt(NEWHOPE_POLY* r);
+
+void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+                      const NEWHOPE_POLY* b);
+void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+                            const NEWHOPE_POLY* b);
+
+uint16_t newhope_montgomery_reduce(uint32_t a);
+uint16_t newhope_barrett_reduce(uint16_t a);
+
+void newhope_bitrev_vector(uint16_t* poly);
+void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors);
+void newhope_ntt(uint16_t* poly, const uint16_t* omegas);
+
+
+#endif /* OPENSSL_HEADER_NEWHOPE_INTERNAL_H */
diff --git a/src/crypto/newhope/newhope.c b/src/crypto/newhope/newhope.c
new file mode 100644
index 0000000..29e189f
--- /dev/null
+++ b/src/crypto/newhope/newhope.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <string.h>
+
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+NEWHOPE_POLY *NEWHOPE_POLY_new(void) {
+  return (NEWHOPE_POLY *)OPENSSL_malloc(sizeof(NEWHOPE_POLY));
+}
+
+void NEWHOPE_POLY_free(NEWHOPE_POLY *p) { OPENSSL_free(p); }
+
+/* Encodes reconciliation data from |c| into |r|. */
+static void encode_rec(const NEWHOPE_POLY *c, uint8_t *r) {
+  int i;
+  for (i = 0; i < PARAM_N / 4; i++) {
+    r[i] = c->coeffs[4 * i] | (c->coeffs[4 * i + 1] << 2) |
+           (c->coeffs[4 * i + 2] << 4) | (c->coeffs[4 * i + 3] << 6);
+  }
+}
+
+/* Decodes reconciliation data from |r| into |c|. */
+static void decode_rec(const uint8_t *r, NEWHOPE_POLY *c) {
+  int i;
+  for (i = 0; i < PARAM_N / 4; i++) {
+    c->coeffs[4 * i + 0] = r[i] & 0x03;
+    c->coeffs[4 * i + 1] = (r[i] >> 2) & 0x03;
+    c->coeffs[4 * i + 2] = (r[i] >> 4) & 0x03;
+    c->coeffs[4 * i + 3] = (r[i] >> 6);
+  }
+}
+
+void NEWHOPE_keygen(uint8_t *servermsg, NEWHOPE_POLY *sk) {
+  newhope_poly_getnoise(sk);
+  newhope_poly_ntt(sk);
+
+  /* The first part of the server's message is the seed, which compactly encodes
+   * a. */
+  NEWHOPE_POLY a;
+  uint8_t *seed = &servermsg[POLY_BYTES];
+  RAND_bytes(seed, SEED_LENGTH);
+  newhope_poly_uniform(&a, seed);
+
+  NEWHOPE_POLY e;
+  newhope_poly_getnoise(&e);
+  newhope_poly_ntt(&e);
+
+  /* The second part of the server's message is the polynomial pk = a*sk+e */
+  NEWHOPE_POLY r, pk;
+  newhope_poly_pointwise(&r, sk, &a);
+  newhope_poly_add(&pk, &e, &r);
+  newhope_poly_tobytes(servermsg, &pk);
+}
+
+int NEWHOPE_client_compute_key(
+    uint8_t key[SHA256_DIGEST_LENGTH],
+    uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH],
+    const uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH], size_t msg_len) {
+  if (msg_len != NEWHOPE_SERVERMSG_LENGTH) {
+    return 0;
+  }
+
+  NEWHOPE_POLY sp;
+  newhope_poly_getnoise(&sp);
+  newhope_poly_ntt(&sp);
+
+  /* The first part of the client's message is the polynomial bp=e'+a*s' */
+  {
+    NEWHOPE_POLY ep;
+    newhope_poly_getnoise(&ep);
+    newhope_poly_ntt(&ep);
+
+    /* Generate the same |a| as the server, from the server's seed. */
+    NEWHOPE_POLY a;
+    const uint8_t *seed = &servermsg[POLY_BYTES];
+    newhope_poly_uniform(&a, seed);
+
+    NEWHOPE_POLY bp;
+    newhope_poly_pointwise(&bp, &a, &sp);
+    newhope_poly_add(&bp, &bp, &ep);
+    newhope_poly_tobytes(clientmsg, &bp);
+  }
+
+  /* v = pk * s' + e'' */
+  NEWHOPE_POLY v;
+  {
+    NEWHOPE_POLY pk;
+    newhope_poly_frombytes(&pk, servermsg);
+
+    NEWHOPE_POLY epp;
+    newhope_poly_getnoise(&epp);
+
+    newhope_poly_pointwise(&v, &pk, &sp);
+    newhope_poly_invntt(&v);
+    newhope_poly_add(&v, &v, &epp);
+  }
+
+  /* The second part of the client's message is the reconciliation data derived
+   * from v. */
+  NEWHOPE_POLY c;
+  uint8_t *reconciliation = &clientmsg[POLY_BYTES];
+  newhope_helprec(&c, &v);
+  encode_rec(&c, reconciliation);
+
+  uint8_t k[KEY_LENGTH];
+  newhope_reconcile(k, &v, &c);
+  SHA256_CTX ctx;
+  if (!SHA256_Init(&ctx) ||
+      !SHA256_Update(&ctx, k, KEY_LENGTH) ||
+      !SHA256_Final(key, &ctx)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+int NEWHOPE_server_compute_key(
+    uint8_t key[SHA256_DIGEST_LENGTH], const NEWHOPE_POLY *sk,
+    const uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH], size_t msg_len) {
+  if (msg_len != NEWHOPE_CLIENTMSG_LENGTH) {
+    return 0;
+  }
+  NEWHOPE_POLY bp;
+  newhope_poly_frombytes(&bp, clientmsg);
+
+  NEWHOPE_POLY v;
+  newhope_poly_pointwise(&v, sk, &bp);
+  newhope_poly_invntt(&v);
+
+  NEWHOPE_POLY c;
+  const uint8_t *reconciliation = &clientmsg[POLY_BYTES];
+  decode_rec(reconciliation, &c);
+
+  uint8_t k[KEY_LENGTH];
+  newhope_reconcile(k, &v, &c);
+  SHA256_CTX ctx;
+  if (!SHA256_Init(&ctx) ||
+      !SHA256_Update(&ctx, k, KEY_LENGTH) ||
+      !SHA256_Final(key, &ctx)) {
+    return 0;
+  }
+
+  return 1;
+}
diff --git a/src/crypto/newhope/newhope_test.c b/src/crypto/newhope/newhope_test.c
new file mode 100644
index 0000000..5d96007
--- /dev/null
+++ b/src/crypto/newhope/newhope_test.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+#define NTESTS 1000
+
+static int test_keys(void) {
+  NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+  uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+  uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+  uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+  int i;
+
+  for (i = 0; i < NTESTS; i++) {
+    /* Alice generates a public key */
+    NEWHOPE_keygen(servermsg, sk);
+
+    /* Bob derives a secret key and creates a response */
+    if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+                                    sizeof(servermsg))) {
+      fprintf(stderr, "ERROR client key exchange failed\n");
+      return 0;
+    }
+
+    /* Alice uses Bob's response to get her secret key */
+    if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+                                    sizeof(clientmsg))) {
+      fprintf(stderr, "ERROR server key exchange failed\n");
+      return 0;
+    }
+
+    if (memcmp(server_key, client_key, SHA256_DIGEST_LENGTH) != 0) {
+      fprintf(stderr, "ERROR keys did not agree\n");
+      return 0;
+    }
+  }
+
+  NEWHOPE_POLY_free(sk);
+  return 1;
+}
+
+static int test_invalid_sk_a(void) {
+  NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+  uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+  uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+  uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+  int i;
+
+  for (i = 0; i < NTESTS; i++) {
+    /* Alice generates a public key */
+    NEWHOPE_keygen(servermsg, sk);
+
+    /* Bob derives a secret key and creates a response */
+    if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+                                    sizeof(servermsg))) {
+      fprintf(stderr, "ERROR client key exchange failed\n");
+      return 0;
+    }
+
+    /* Corrupt the secret key */
+    NEWHOPE_keygen(servermsg /* not used below */, sk);
+
+    /* Alice uses Bob's response to get her secret key */
+    if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+                                    sizeof(clientmsg))) {
+      fprintf(stderr, "ERROR server key exchange failed\n");
+      return 0;
+    }
+
+    if (memcmp(server_key, client_key, SHA256_DIGEST_LENGTH) == 0) {
+      fprintf(stderr, "ERROR invalid sk_a\n");
+      return 0;
+    }
+  }
+
+  NEWHOPE_POLY_free(sk);
+  return 1;
+}
+
+static int test_invalid_ciphertext(void) {
+  NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+  uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+  uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+  uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+  int i;
+
+  for (i = 0; i < 10; i++) {
+    /* Alice generates a public key */
+    NEWHOPE_keygen(servermsg, sk);
+
+    /* Bob derives a secret key and creates a response */
+    if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+                                    sizeof(servermsg))) {
+      fprintf(stderr, "ERROR client key exchange failed\n");
+      return 0;
+    }
+
+    /* Change some byte in the "ciphertext" */
+    clientmsg[42] ^= 1;
+
+    /* Alice uses Bob's response to get her secret key */
+    if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+                                    sizeof(clientmsg))) {
+      fprintf(stderr, "ERROR server key exchange failed\n");
+      return 0;
+    }
+
+    if (!memcmp(server_key, client_key, SHA256_DIGEST_LENGTH)) {
+      fprintf(stderr, "ERROR invalid clientmsg\n");
+      return 0;
+    }
+  }
+
+  NEWHOPE_POLY_free(sk);
+  return 1;
+}
+
+int main(void) {
+  if (!test_keys() || !test_invalid_sk_a() || !test_invalid_ciphertext()) {
+    return 1;
+  }
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/newhope/ntt.c b/src/crypto/newhope/ntt.c
new file mode 100644
index 0000000..163a9d1
--- /dev/null
+++ b/src/crypto/newhope/ntt.c
@@ -0,0 +1,148 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+
+static uint16_t bitrev_table[1024] = {
+    0,   512,  256, 768,  128, 640,  384, 896,  64,  576,  320, 832,  192, 704,
+    448, 960,  32,  544,  288, 800,  160, 672,  416, 928,  96,  608,  352, 864,
+    224, 736,  480, 992,  16,  528,  272, 784,  144, 656,  400, 912,  80,  592,
+    336, 848,  208, 720,  464, 976,  48,  560,  304, 816,  176, 688,  432, 944,
+    112, 624,  368, 880,  240, 752,  496, 1008, 8,   520,  264, 776,  136, 648,
+    392, 904,  72,  584,  328, 840,  200, 712,  456, 968,  40,  552,  296, 808,
+    168, 680,  424, 936,  104, 616,  360, 872,  232, 744,  488, 1000, 24,  536,
+    280, 792,  152, 664,  408, 920,  88,  600,  344, 856,  216, 728,  472, 984,
+    56,  568,  312, 824,  184, 696,  440, 952,  120, 632,  376, 888,  248, 760,
+    504, 1016, 4,   516,  260, 772,  132, 644,  388, 900,  68,  580,  324, 836,
+    196, 708,  452, 964,  36,  548,  292, 804,  164, 676,  420, 932,  100, 612,
+    356, 868,  228, 740,  484, 996,  20,  532,  276, 788,  148, 660,  404, 916,
+    84,  596,  340, 852,  212, 724,  468, 980,  52,  564,  308, 820,  180, 692,
+    436, 948,  116, 628,  372, 884,  244, 756,  500, 1012, 12,  524,  268, 780,
+    140, 652,  396, 908,  76,  588,  332, 844,  204, 716,  460, 972,  44,  556,
+    300, 812,  172, 684,  428, 940,  108, 620,  364, 876,  236, 748,  492, 1004,
+    28,  540,  284, 796,  156, 668,  412, 924,  92,  604,  348, 860,  220, 732,
+    476, 988,  60,  572,  316, 828,  188, 700,  444, 956,  124, 636,  380, 892,
+    252, 764,  508, 1020, 2,   514,  258, 770,  130, 642,  386, 898,  66,  578,
+    322, 834,  194, 706,  450, 962,  34,  546,  290, 802,  162, 674,  418, 930,
+    98,  610,  354, 866,  226, 738,  482, 994,  18,  530,  274, 786,  146, 658,
+    402, 914,  82,  594,  338, 850,  210, 722,  466, 978,  50,  562,  306, 818,
+    178, 690,  434, 946,  114, 626,  370, 882,  242, 754,  498, 1010, 10,  522,
+    266, 778,  138, 650,  394, 906,  74,  586,  330, 842,  202, 714,  458, 970,
+    42,  554,  298, 810,  170, 682,  426, 938,  106, 618,  362, 874,  234, 746,
+    490, 1002, 26,  538,  282, 794,  154, 666,  410, 922,  90,  602,  346, 858,
+    218, 730,  474, 986,  58,  570,  314, 826,  186, 698,  442, 954,  122, 634,
+    378, 890,  250, 762,  506, 1018, 6,   518,  262, 774,  134, 646,  390, 902,
+    70,  582,  326, 838,  198, 710,  454, 966,  38,  550,  294, 806,  166, 678,
+    422, 934,  102, 614,  358, 870,  230, 742,  486, 998,  22,  534,  278, 790,
+    150, 662,  406, 918,  86,  598,  342, 854,  214, 726,  470, 982,  54,  566,
+    310, 822,  182, 694,  438, 950,  118, 630,  374, 886,  246, 758,  502, 1014,
+    14,  526,  270, 782,  142, 654,  398, 910,  78,  590,  334, 846,  206, 718,
+    462, 974,  46,  558,  302, 814,  174, 686,  430, 942,  110, 622,  366, 878,
+    238, 750,  494, 1006, 30,  542,  286, 798,  158, 670,  414, 926,  94,  606,
+    350, 862,  222, 734,  478, 990,  62,  574,  318, 830,  190, 702,  446, 958,
+    126, 638,  382, 894,  254, 766,  510, 1022, 1,   513,  257, 769,  129, 641,
+    385, 897,  65,  577,  321, 833,  193, 705,  449, 961,  33,  545,  289, 801,
+    161, 673,  417, 929,  97,  609,  353, 865,  225, 737,  481, 993,  17,  529,
+    273, 785,  145, 657,  401, 913,  81,  593,  337, 849,  209, 721,  465, 977,
+    49,  561,  305, 817,  177, 689,  433, 945,  113, 625,  369, 881,  241, 753,
+    497, 1009, 9,   521,  265, 777,  137, 649,  393, 905,  73,  585,  329, 841,
+    201, 713,  457, 969,  41,  553,  297, 809,  169, 681,  425, 937,  105, 617,
+    361, 873,  233, 745,  489, 1001, 25,  537,  281, 793,  153, 665,  409, 921,
+    89,  601,  345, 857,  217, 729,  473, 985,  57,  569,  313, 825,  185, 697,
+    441, 953,  121, 633,  377, 889,  249, 761,  505, 1017, 5,   517,  261, 773,
+    133, 645,  389, 901,  69,  581,  325, 837,  197, 709,  453, 965,  37,  549,
+    293, 805,  165, 677,  421, 933,  101, 613,  357, 869,  229, 741,  485, 997,
+    21,  533,  277, 789,  149, 661,  405, 917,  85,  597,  341, 853,  213, 725,
+    469, 981,  53,  565,  309, 821,  181, 693,  437, 949,  117, 629,  373, 885,
+    245, 757,  501, 1013, 13,  525,  269, 781,  141, 653,  397, 909,  77,  589,
+    333, 845,  205, 717,  461, 973,  45,  557,  301, 813,  173, 685,  429, 941,
+    109, 621,  365, 877,  237, 749,  493, 1005, 29,  541,  285, 797,  157, 669,
+    413, 925,  93,  605,  349, 861,  221, 733,  477, 989,  61,  573,  317, 829,
+    189, 701,  445, 957,  125, 637,  381, 893,  253, 765,  509, 1021, 3,   515,
+    259, 771,  131, 643,  387, 899,  67,  579,  323, 835,  195, 707,  451, 963,
+    35,  547,  291, 803,  163, 675,  419, 931,  99,  611,  355, 867,  227, 739,
+    483, 995,  19,  531,  275, 787,  147, 659,  403, 915,  83,  595,  339, 851,
+    211, 723,  467, 979,  51,  563,  307, 819,  179, 691,  435, 947,  115, 627,
+    371, 883,  243, 755,  499, 1011, 11,  523,  267, 779,  139, 651,  395, 907,
+    75,  587,  331, 843,  203, 715,  459, 971,  43,  555,  299, 811,  171, 683,
+    427, 939,  107, 619,  363, 875,  235, 747,  491, 1003, 27,  539,  283, 795,
+    155, 667,  411, 923,  91,  603,  347, 859,  219, 731,  475, 987,  59,  571,
+    315, 827,  187, 699,  443, 955,  123, 635,  379, 891,  251, 763,  507, 1019,
+    7,   519,  263, 775,  135, 647,  391, 903,  71,  583,  327, 839,  199, 711,
+    455, 967,  39,  551,  295, 807,  167, 679,  423, 935,  103, 615,  359, 871,
+    231, 743,  487, 999,  23,  535,  279, 791,  151, 663,  407, 919,  87,  599,
+    343, 855,  215, 727,  471, 983,  55,  567,  311, 823,  183, 695,  439, 951,
+    119, 631,  375, 887,  247, 759,  503, 1015, 15,  527,  271, 783,  143, 655,
+    399, 911,  79,  591,  335, 847,  207, 719,  463, 975,  47,  559,  303, 815,
+    175, 687,  431, 943,  111, 623,  367, 879,  239, 751,  495, 1007, 31,  543,
+    287, 799,  159, 671,  415, 927,  95,  607,  351, 863,  223, 735,  479, 991,
+    63,  575,  319, 831,  191, 703,  447, 959,  127, 639,  383, 895,  255, 767,
+    511, 1023};
+
+void newhope_bitrev_vector(uint16_t* poly) {
+  unsigned int i, r;
+  uint16_t tmp;
+
+  for (i = 0; i < PARAM_N; i++) {
+    r = bitrev_table[i];
+    if (i < r) {
+      tmp = poly[i];
+      poly[i] = poly[r];
+      poly[r] = tmp;
+    }
+  }
+}
+
+void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors) {
+  unsigned int i;
+
+  for (i = 0; i < PARAM_N; i++) {
+    poly[i] = newhope_montgomery_reduce((poly[i] * factors[i]));
+  }
+}
+
+/* GS_bo_to_no; omegas need to be in Montgomery domain */
+void newhope_ntt(uint16_t* a, const uint16_t* omega) {
+  int i, start, j, jTwiddle, distance;
+  uint16_t temp, W;
+
+  for (i = 0; i < 10; i += 2) {
+    /* Even level */
+    distance = (1 << i);
+    for (start = 0; start < distance; start++) {
+      jTwiddle = 0;
+      for (j = start; j < PARAM_N - 1; j += 2 * distance) {
+        W = omega[jTwiddle++];
+        temp = a[j];
+        a[j] = (temp + a[j + distance]); /* Omit reduction (be lazy) */
+        a[j + distance] = newhope_montgomery_reduce(
+            (W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
+      }
+    }
+
+    /* Odd level */
+    distance <<= 1;
+    for (start = 0; start < distance; start++) {
+      jTwiddle = 0;
+      for (j = start; j < PARAM_N - 1; j += 2 * distance) {
+        W = omega[jTwiddle++];
+        temp = a[j];
+        a[j] = newhope_barrett_reduce((temp + a[j + distance]));
+        a[j + distance] = newhope_montgomery_reduce(
+            (W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
+      }
+    }
+  }
+}
diff --git a/src/crypto/newhope/poly.c b/src/crypto/newhope/poly.c
new file mode 100644
index 0000000..a9839fa
--- /dev/null
+++ b/src/crypto/newhope/poly.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+extern uint16_t newhope_omegas_montgomery[];
+extern uint16_t newhope_omegas_inv_montgomery[];
+
+extern uint16_t newhope_psis_bitrev_montgomery[];
+extern uint16_t newhope_psis_inv_montgomery[];
+
+void newhope_poly_frombytes(NEWHOPE_POLY* r, const uint8_t* a) {
+  int i;
+  for (i = 0; i < PARAM_N / 4; i++) {
+    r->coeffs[4 * i + 0] =
+        a[7 * i + 0] | (((uint16_t)a[7 * i + 1] & 0x3f) << 8);
+    r->coeffs[4 * i + 1] = (a[7 * i + 1] >> 6) |
+                           (((uint16_t)a[7 * i + 2]) << 2) |
+                           (((uint16_t)a[7 * i + 3] & 0x0f) << 10);
+    r->coeffs[4 * i + 2] = (a[7 * i + 3] >> 4) |
+                           (((uint16_t)a[7 * i + 4]) << 4) |
+                           (((uint16_t)a[7 * i + 5] & 0x03) << 12);
+    r->coeffs[4 * i + 3] =
+        (a[7 * i + 5] >> 2) | (((uint16_t)a[7 * i + 6]) << 6);
+  }
+}
+
+void newhope_poly_tobytes(uint8_t* r, const NEWHOPE_POLY* p) {
+  int i;
+  uint16_t t0, t1, t2, t3, m;
+  int16_t c;
+  for (i = 0; i < PARAM_N / 4; i++) {
+    t0 = newhope_barrett_reduce(
+        p->coeffs[4 * i + 0]); /* Make sure that coefficients
+                          have only 14 bits */
+    t1 = newhope_barrett_reduce(p->coeffs[4 * i + 1]);
+    t2 = newhope_barrett_reduce(p->coeffs[4 * i + 2]);
+    t3 = newhope_barrett_reduce(p->coeffs[4 * i + 3]);
+
+    m = t0 - PARAM_Q;
+    c = m;
+    c >>= 15;
+    t0 = m ^ ((t0 ^ m) & c); /* Make sure that coefficients are in [0,q] */
+
+    m = t1 - PARAM_Q;
+    c = m;
+    c >>= 15;
+    t1 = m ^ ((t1 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
+
+    m = t2 - PARAM_Q;
+    c = m;
+    c >>= 15;
+    t2 = m ^ ((t2 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
+
+    m = t3 - PARAM_Q;
+    c = m;
+    c >>= 15;
+    t3 = m ^ ((t3 ^ m) & c); /* Make sure that coefficients are in [0,q] */
+
+    r[7 * i + 0] = t0 & 0xff;
+    r[7 * i + 1] = (t0 >> 8) | (t1 << 6);
+    r[7 * i + 2] = (t1 >> 2);
+    r[7 * i + 3] = (t1 >> 10) | (t2 << 4);
+    r[7 * i + 4] = (t2 >> 4);
+    r[7 * i + 5] = (t2 >> 12) | (t3 << 2);
+    r[7 * i + 6] = (t3 >> 6);
+  }
+}
+
+void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed) {
+/* The reference implementation uses SHAKE-128 here; this implementation uses
+ * AES-CTR. Use half the seed for the initialization vector and half for the
+ * key. */
+#if SEED_LENGTH != 2 * AES_BLOCK_SIZE
+#error "2 * seed length != AES_BLOCK_SIZE"
+#endif
+  uint8_t ivec[AES_BLOCK_SIZE];
+  memcpy(ivec, &seed[SEED_LENGTH / 2], SEED_LENGTH / 2);
+  AES_KEY key;
+  AES_set_encrypt_key(seed, 8 * SEED_LENGTH / 2, &key);
+
+  /* AES state. */
+  uint8_t ecount[AES_BLOCK_SIZE];
+  memset(ecount, 0, AES_BLOCK_SIZE);
+
+  /* Encrypt a block of zeros just to get the random bytes. With luck, 2688
+   * bytes is enough. */
+  uint8_t buf[AES_BLOCK_SIZE * 168];
+  memset(buf, 0, sizeof(buf));
+
+  unsigned int block_num = 0;
+  AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
+
+  size_t pos = 0, coeff_num = 0;
+  while (coeff_num < PARAM_N) {
+    /* Specialized for q = 12889 */
+    uint16_t val = (buf[pos] | ((uint16_t)buf[pos + 1] << 8)) & 0x3fff;
+    if (val < PARAM_Q) {
+      a->coeffs[coeff_num++] = val;
+    }
+
+    pos += 2;
+    if (pos > sizeof(buf) - 2) {
+      memset(buf, 0, sizeof(buf));
+      AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
+      pos = 0;
+    }
+  }
+}
+
+void newhope_poly_getnoise(NEWHOPE_POLY* r) {
+#if PARAM_K != 16
+#error "poly_getnoise in poly.c only supports k=16"
+#endif
+
+  uint32_t tp[PARAM_N];
+
+  /* The reference implementation calls ChaCha20 here. */
+  RAND_bytes((uint8_t *) tp, sizeof(tp));
+
+  size_t i;
+  for (i = 0; i < PARAM_N; i++) {
+    const uint32_t t = tp[i];
+
+    size_t j;
+    uint32_t d = 0;
+    for (j = 0; j < 8; j++) {
+      d += (t >> j) & 0x01010101;
+    }
+
+    const uint32_t a = ((d >> 8) & 0xff) + (d & 0xff);
+    const uint32_t b = (d >> 24) + ((d >> 16) & 0xff);
+    r->coeffs[i] = a + PARAM_Q - b;
+  }
+}
+
+void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+                            const NEWHOPE_POLY* b) {
+  size_t i;
+  for (i = 0; i < PARAM_N; i++) {
+    uint16_t t = newhope_montgomery_reduce(3186 * b->coeffs[i]);
+    /* t is now in Montgomery domain */
+    r->coeffs[i] = newhope_montgomery_reduce(a->coeffs[i] * t);
+    /* r->coeffs[i] is back in normal domain */
+  }
+}
+
+void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+                      const NEWHOPE_POLY* b) {
+  size_t i;
+  for (i = 0; i < PARAM_N; i++) {
+    r->coeffs[i] = newhope_barrett_reduce(a->coeffs[i] + b->coeffs[i]);
+  }
+}
+
+void newhope_poly_ntt(NEWHOPE_POLY* r) {
+  newhope_mul_coefficients(r->coeffs, newhope_psis_bitrev_montgomery);
+  newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_montgomery);
+}
+
+void newhope_poly_invntt(NEWHOPE_POLY* r) {
+  newhope_bitrev_vector(r->coeffs);
+  newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_inv_montgomery);
+  newhope_mul_coefficients(r->coeffs, newhope_psis_inv_montgomery);
+}
diff --git a/src/crypto/newhope/precomp.c b/src/crypto/newhope/precomp.c
new file mode 100644
index 0000000..d0c478e
--- /dev/null
+++ b/src/crypto/newhope/precomp.c
@@ -0,0 +1,306 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+
+uint16_t newhope_omegas_montgomery[PARAM_N / 2] = {
+    4075,  6974,  7373,  7965,  3262,  5079,  522,   2169,  6364,  1018,  1041,
+    8775,  2344,  11011, 5574,  1973,  4536,  1050,  6844,  3860,  3818,  6118,
+    2683,  1190,  4789,  7822,  7540,  6752,  5456,  4449,  3789,  12142, 11973,
+    382,   3988,  468,   6843,  5339,  6196,  3710,  11316, 1254,  5435,  10930,
+    3998,  10256, 10367, 3879,  11889, 1728,  6137,  4948,  5862,  6136,  3643,
+    6874,  8724,  654,   10302, 1702,  7083,  6760,  56,    3199,  9987,  605,
+    11785, 8076,  5594,  9260,  6403,  4782,  6212,  4624,  9026,  8689,  4080,
+    11868, 6221,  3602,  975,   8077,  8851,  9445,  5681,  3477,  1105,  142,
+    241,   12231, 1003,  3532,  5009,  1956,  6008,  11404, 7377,  2049,  10968,
+    12097, 7591,  5057,  3445,  4780,  2920,  7048,  3127,  8120,  11279, 6821,
+    11502, 8807,  12138, 2127,  2839,  3957,  431,   1579,  6383,  9784,  5874,
+    677,   3336,  6234,  2766,  1323,  9115,  12237, 2031,  6956,  6413,  2281,
+    3969,  3991,  12133, 9522,  4737,  10996, 4774,  5429,  11871, 3772,  453,
+    5908,  2882,  1805,  2051,  1954,  11713, 3963,  2447,  6142,  8174,  3030,
+    1843,  2361,  12071, 2908,  3529,  3434,  3202,  7796,  2057,  5369,  11939,
+    1512,  6906,  10474, 11026, 49,    10806, 5915,  1489,  9789,  5942,  10706,
+    10431, 7535,  426,   8974,  3757,  10314, 9364,  347,   5868,  9551,  9634,
+    6554,  10596, 9280,  11566, 174,   2948,  2503,  6507,  10723, 11606, 2459,
+    64,    3656,  8455,  5257,  5919,  7856,  1747,  9166,  5486,  9235,  6065,
+    835,   3570,  4240,  11580, 4046,  10970, 9139,  1058,  8210,  11848, 922,
+    7967,  1958,  10211, 1112,  3728,  4049,  11130, 5990,  1404,  325,   948,
+    11143, 6190,  295,   11637, 5766,  8212,  8273,  2919,  8527,  6119,  6992,
+    8333,  1360,  2555,  6167,  1200,  7105,  7991,  3329,  9597,  12121, 5106,
+    5961,  10695, 10327, 3051,  9923,  4896,  9326,  81,    3091,  1000,  7969,
+    4611,  726,   1853,  12149, 4255,  11112, 2768,  10654, 1062,  2294,  3553,
+    4805,  2747,  4846,  8577,  9154,  1170,  2319,  790,   11334, 9275,  9088,
+    1326,  5086,  9094,  6429,  11077, 10643, 3504,  3542,  8668,  9744,  1479,
+    1,     8246,  7143,  11567, 10984, 4134,  5736,  4978,  10938, 5777,  8961,
+    4591,  5728,  6461,  5023,  9650,  7468,  949,   9664,  2975,  11726, 2744,
+    9283,  10092, 5067,  12171, 2476,  3748,  11336, 6522,  827,   9452,  5374,
+    12159, 7935,  3296,  3949,  9893,  4452,  10908, 2525,  3584,  8112,  8011,
+    10616, 4989,  6958,  11809, 9447,  12280, 1022,  11950, 9821,  11745, 5791,
+    5092,  2089,  9005,  2881,  3289,  2013,  9048,  729,   7901,  1260,  5755,
+    4632,  11955, 2426,  10593, 1428,  4890,  5911,  3932,  9558,  8830,  3637,
+    5542,  145,   5179,  8595,  3707,  10530, 355,   3382,  4231,  9741,  1207,
+    9041,  7012,  1168,  10146, 11224, 4645,  11885, 10911, 10377, 435,   7952,
+    4096,  493,   9908,  6845,  6039,  2422,  2187,  9723,  8643,  9852,  9302,
+    6022,  7278,  1002,  4284,  5088,  1607,  7313,  875,   8509,  9430,  1045,
+    2481,  5012,  7428,  354,   6591,  9377,  11847, 2401,  1067,  7188,  11516,
+    390,   8511,  8456,  7270,  545,   8585,  9611,  12047, 1537,  4143,  4714,
+    4885,  1017,  5084,  1632,  3066,  27,    1440,  8526,  9273,  12046, 11618,
+    9289,  3400,  9890,  3136,  7098,  8758,  11813, 7384,  3985,  11869, 6730,
+    10745, 10111, 2249,  4048,  2884,  11136, 2126,  1630,  9103,  5407,  2686,
+    9042,  2969,  8311,  9424,  9919,  8779,  5332,  10626, 1777,  4654,  10863,
+    7351,  3636,  9585,  5291,  8374,  2166,  4919,  12176, 9140,  12129, 7852,
+    12286, 4895,  10805, 2780,  5195,  2305,  7247,  9644,  4053,  10600, 3364,
+    3271,  4057,  4414,  9442,  7917,  2174};
+
+uint16_t newhope_omegas_inv_montgomery[PARAM_N / 2] = {
+    4075,  5315,  4324,  4916,  10120, 11767, 7210,  9027,  10316, 6715,  1278,
+    9945,  3514,  11248, 11271, 5925,  147,   8500,  7840,  6833,  5537,  4749,
+    4467,  7500,  11099, 9606,  6171,  8471,  8429,  5445,  11239, 7753,  9090,
+    12233, 5529,  5206,  10587, 1987,  11635, 3565,  5415,  8646,  6153,  6427,
+    7341,  6152,  10561, 400,   8410,  1922,  2033,  8291,  1359,  6854,  11035,
+    973,   8579,  6093,  6950,  5446,  11821, 8301,  11907, 316,   52,    3174,
+    10966, 9523,  6055,  8953,  11612, 6415,  2505,  5906,  10710, 11858, 8332,
+    9450,  10162, 151,   3482,  787,   5468,  1010,  4169,  9162,  5241,  9369,
+    7509,  8844,  7232,  4698,  192,   1321,  10240, 4912,  885,   6281,  10333,
+    7280,  8757,  11286, 58,    12048, 12147, 11184, 8812,  6608,  2844,  3438,
+    4212,  11314, 8687,  6068,  421,   8209,  3600,  3263,  7665,  6077,  7507,
+    5886,  3029,  6695,  4213,  504,   11684, 2302,  1962,  1594,  6328,  7183,
+    168,   2692,  8960,  4298,  5184,  11089, 6122,  9734,  10929, 3956,  5297,
+    6170,  3762,  9370,  4016,  4077,  6523,  652,   11994, 6099,  1146,  11341,
+    11964, 10885, 6299,  1159,  8240,  8561,  11177, 2078,  10331, 4322,  11367,
+    441,   4079,  11231, 3150,  1319,  8243,  709,   8049,  8719,  11454, 6224,
+    3054,  6803,  3123,  10542, 4433,  6370,  7032,  3834,  8633,  12225, 9830,
+    683,   1566,  5782,  9786,  9341,  12115, 723,   3009,  1693,  5735,  2655,
+    2738,  6421,  11942, 2925,  1975,  8532,  3315,  11863, 4754,  1858,  1583,
+    6347,  2500,  10800, 6374,  1483,  12240, 1263,  1815,  5383,  10777, 350,
+    6920,  10232, 4493,  9087,  8855,  8760,  9381,  218,   9928,  10446, 9259,
+    4115,  6147,  9842,  8326,  576,   10335, 10238, 10484, 9407,  6381,  11836,
+    8517,  418,   6860,  7515,  1293,  7552,  2767,  156,   8298,  8320,  10008,
+    5876,  5333,  10258, 10115, 4372,  2847,  7875,  8232,  9018,  8925,  1689,
+    8236,  2645,  5042,  9984,  7094,  9509,  1484,  7394,  3,     4437,  160,
+    3149,  113,   7370,  10123, 3915,  6998,  2704,  8653,  4938,  1426,  7635,
+    10512, 1663,  6957,  3510,  2370,  2865,  3978,  9320,  3247,  9603,  6882,
+    3186,  10659, 10163, 1153,  9405,  8241,  10040, 2178,  1544,  5559,  420,
+    8304,  4905,  476,   3531,  5191,  9153,  2399,  8889,  3000,  671,   243,
+    3016,  3763,  10849, 12262, 9223,  10657, 7205,  11272, 7404,  7575,  8146,
+    10752, 242,   2678,  3704,  11744, 5019,  3833,  3778,  11899, 773,   5101,
+    11222, 9888,  442,   2912,  5698,  11935, 4861,  7277,  9808,  11244, 2859,
+    3780,  11414, 4976,  10682, 7201,  8005,  11287, 5011,  6267,  2987,  2437,
+    3646,  2566,  10102, 9867,  6250,  5444,  2381,  11796, 8193,  4337,  11854,
+    1912,  1378,  404,   7644,  1065,  2143,  11121, 5277,  3248,  11082, 2548,
+    8058,  8907,  11934, 1759,  8582,  3694,  7110,  12144, 6747,  8652,  3459,
+    2731,  8357,  6378,  7399,  10861, 1696,  9863,  334,   7657,  6534,  11029,
+    4388,  11560, 3241,  10276, 9000,  9408,  3284,  10200, 7197,  6498,  544,
+    2468,  339,   11267, 9,     2842,  480,   5331,  7300,  1673,  4278,  4177,
+    8705,  9764,  1381,  7837,  2396,  8340,  8993,  4354,  130,   6915,  2837,
+    11462, 5767,  953,   8541,  9813,  118,   7222,  2197,  3006,  9545,  563,
+    9314,  2625,  11340, 4821,  2639,  7266,  5828,  6561,  7698,  3328,  6512,
+    1351,  7311,  6553,  8155,  1305,  722,   5146,  4043,  12288, 10810, 2545,
+    3621,  8747,  8785,  1646,  1212,  5860,  3195,  7203,  10963, 3201,  3014,
+    955,   11499, 9970,  11119, 3135,  3712,  7443,  9542,  7484,  8736,  9995,
+    11227, 1635,  9521,  1177,  8034,  140,   10436, 11563, 7678,  4320,  11289,
+    9198,  12208, 2963,  7393,  2366,  9238};
+
+uint16_t newhope_psis_bitrev_montgomery[PARAM_N] = {
+    4075,  6974,  7373,  7965,  3262,  5079,  522,   2169,  6364,  1018,  1041,
+    8775,  2344,  11011, 5574,  1973,  4536,  1050,  6844,  3860,  3818,  6118,
+    2683,  1190,  4789,  7822,  7540,  6752,  5456,  4449,  3789,  12142, 11973,
+    382,   3988,  468,   6843,  5339,  6196,  3710,  11316, 1254,  5435,  10930,
+    3998,  10256, 10367, 3879,  11889, 1728,  6137,  4948,  5862,  6136,  3643,
+    6874,  8724,  654,   10302, 1702,  7083,  6760,  56,    3199,  9987,  605,
+    11785, 8076,  5594,  9260,  6403,  4782,  6212,  4624,  9026,  8689,  4080,
+    11868, 6221,  3602,  975,   8077,  8851,  9445,  5681,  3477,  1105,  142,
+    241,   12231, 1003,  3532,  5009,  1956,  6008,  11404, 7377,  2049,  10968,
+    12097, 7591,  5057,  3445,  4780,  2920,  7048,  3127,  8120,  11279, 6821,
+    11502, 8807,  12138, 2127,  2839,  3957,  431,   1579,  6383,  9784,  5874,
+    677,   3336,  6234,  2766,  1323,  9115,  12237, 2031,  6956,  6413,  2281,
+    3969,  3991,  12133, 9522,  4737,  10996, 4774,  5429,  11871, 3772,  453,
+    5908,  2882,  1805,  2051,  1954,  11713, 3963,  2447,  6142,  8174,  3030,
+    1843,  2361,  12071, 2908,  3529,  3434,  3202,  7796,  2057,  5369,  11939,
+    1512,  6906,  10474, 11026, 49,    10806, 5915,  1489,  9789,  5942,  10706,
+    10431, 7535,  426,   8974,  3757,  10314, 9364,  347,   5868,  9551,  9634,
+    6554,  10596, 9280,  11566, 174,   2948,  2503,  6507,  10723, 11606, 2459,
+    64,    3656,  8455,  5257,  5919,  7856,  1747,  9166,  5486,  9235,  6065,
+    835,   3570,  4240,  11580, 4046,  10970, 9139,  1058,  8210,  11848, 922,
+    7967,  1958,  10211, 1112,  3728,  4049,  11130, 5990,  1404,  325,   948,
+    11143, 6190,  295,   11637, 5766,  8212,  8273,  2919,  8527,  6119,  6992,
+    8333,  1360,  2555,  6167,  1200,  7105,  7991,  3329,  9597,  12121, 5106,
+    5961,  10695, 10327, 3051,  9923,  4896,  9326,  81,    3091,  1000,  7969,
+    4611,  726,   1853,  12149, 4255,  11112, 2768,  10654, 1062,  2294,  3553,
+    4805,  2747,  4846,  8577,  9154,  1170,  2319,  790,   11334, 9275,  9088,
+    1326,  5086,  9094,  6429,  11077, 10643, 3504,  3542,  8668,  9744,  1479,
+    1,     8246,  7143,  11567, 10984, 4134,  5736,  4978,  10938, 5777,  8961,
+    4591,  5728,  6461,  5023,  9650,  7468,  949,   9664,  2975,  11726, 2744,
+    9283,  10092, 5067,  12171, 2476,  3748,  11336, 6522,  827,   9452,  5374,
+    12159, 7935,  3296,  3949,  9893,  4452,  10908, 2525,  3584,  8112,  8011,
+    10616, 4989,  6958,  11809, 9447,  12280, 1022,  11950, 9821,  11745, 5791,
+    5092,  2089,  9005,  2881,  3289,  2013,  9048,  729,   7901,  1260,  5755,
+    4632,  11955, 2426,  10593, 1428,  4890,  5911,  3932,  9558,  8830,  3637,
+    5542,  145,   5179,  8595,  3707,  10530, 355,   3382,  4231,  9741,  1207,
+    9041,  7012,  1168,  10146, 11224, 4645,  11885, 10911, 10377, 435,   7952,
+    4096,  493,   9908,  6845,  6039,  2422,  2187,  9723,  8643,  9852,  9302,
+    6022,  7278,  1002,  4284,  5088,  1607,  7313,  875,   8509,  9430,  1045,
+    2481,  5012,  7428,  354,   6591,  9377,  11847, 2401,  1067,  7188,  11516,
+    390,   8511,  8456,  7270,  545,   8585,  9611,  12047, 1537,  4143,  4714,
+    4885,  1017,  5084,  1632,  3066,  27,    1440,  8526,  9273,  12046, 11618,
+    9289,  3400,  9890,  3136,  7098,  8758,  11813, 7384,  3985,  11869, 6730,
+    10745, 10111, 2249,  4048,  2884,  11136, 2126,  1630,  9103,  5407,  2686,
+    9042,  2969,  8311,  9424,  9919,  8779,  5332,  10626, 1777,  4654,  10863,
+    7351,  3636,  9585,  5291,  8374,  2166,  4919,  12176, 9140,  12129, 7852,
+    12286, 4895,  10805, 2780,  5195,  2305,  7247,  9644,  4053,  10600, 3364,
+    3271,  4057,  4414,  9442,  7917,  2174,  3947,  11951, 2455,  6599,  10545,
+    10975, 3654,  2894,  7681,  7126,  7287,  12269, 4119,  3343,  2151,  1522,
+    7174,  7350,  11041, 2442,  2148,  5959,  6492,  8330,  8945,  5598,  3624,
+    10397, 1325,  6565,  1945,  11260, 10077, 2674,  3338,  3276,  11034, 506,
+    6505,  1392,  5478,  8778,  1178,  2776,  3408,  10347, 11124, 2575,  9489,
+    12096, 6092,  10058, 4167,  6085,  923,   11251, 11912, 4578,  10669, 11914,
+    425,   10453, 392,   10104, 8464,  4235,  8761,  7376,  2291,  3375,  7954,
+    8896,  6617,  7790,  1737,  11667, 3982,  9342,  6680,  636,   6825,  7383,
+    512,   4670,  2900,  12050, 7735,  994,   1687,  11883, 7021,  146,   10485,
+    1403,  5189,  6094,  2483,  2054,  3042,  10945, 3981,  10821, 11826, 8882,
+    8151,  180,   9600,  7684,  5219,  10880, 6780,  204,   11232, 2600,  7584,
+    3121,  3017,  11053, 7814,  7043,  4251,  4739,  11063, 6771,  7073,  9261,
+    2360,  11925, 1928,  11825, 8024,  3678,  3205,  3359,  11197, 5209,  8581,
+    3238,  8840,  1136,  9363,  1826,  3171,  4489,  7885,  346,   2068,  1389,
+    8257,  3163,  4840,  6127,  8062,  8921,  612,   4238,  10763, 8067,  125,
+    11749, 10125, 5416,  2110,  716,   9839,  10584, 11475, 11873, 3448,  343,
+    1908,  4538,  10423, 7078,  4727,  1208,  11572, 3589,  2982,  1373,  1721,
+    10753, 4103,  2429,  4209,  5412,  5993,  9011,  438,   3515,  7228,  1218,
+    8347,  5232,  8682,  1327,  7508,  4924,  448,   1014,  10029, 12221, 4566,
+    5836,  12229, 2717,  1535,  3200,  5588,  5845,  412,   5102,  7326,  3744,
+    3056,  2528,  7406,  8314,  9202,  6454,  6613,  1417,  10032, 7784,  1518,
+    3765,  4176,  5063,  9828,  2275,  6636,  4267,  6463,  2065,  7725,  3495,
+    8328,  8755,  8144,  10533, 5966,  12077, 9175,  9520,  5596,  6302,  8400,
+    579,   6781,  11014, 5734,  11113, 11164, 4860,  1131,  10844, 9068,  8016,
+    9694,  3837,  567,   9348,  7000,  6627,  7699,  5082,  682,   11309, 5207,
+    4050,  7087,  844,   7434,  3769,  293,   9057,  6940,  9344,  10883, 2633,
+    8190,  3944,  5530,  5604,  3480,  2171,  9282,  11024, 2213,  8136,  3805,
+    767,   12239, 216,   11520, 6763,  10353, 7,     8566,  845,   7235,  3154,
+    4360,  3285,  10268, 2832,  3572,  1282,  7559,  3229,  8360,  10583, 6105,
+    3120,  6643,  6203,  8536,  8348,  6919,  3536,  9199,  10891, 11463, 5043,
+    1658,  5618,  8787,  5789,  4719,  751,   11379, 6389,  10783, 3065,  7806,
+    6586,  2622,  5386,  510,   7628,  6921,  578,   10345, 11839, 8929,  4684,
+    12226, 7154,  9916,  7302,  8481,  3670,  11066, 2334,  1590,  7878,  10734,
+    1802,  1891,  5103,  6151,  8820,  3418,  7846,  9951,  4693,  417,   9996,
+    9652,  4510,  2946,  5461,  365,   881,   1927,  1015,  11675, 11009, 1371,
+    12265, 2485,  11385, 5039,  6742,  8449,  1842,  12217, 8176,  9577,  4834,
+    7937,  9461,  2643,  11194, 3045,  6508,  4094,  3451,  7911,  11048, 5406,
+    4665,  3020,  6616,  11345, 7519,  3669,  5287,  1790,  7014,  5410,  11038,
+    11249, 2035,  6125,  10407, 4565,  7315,  5078,  10506, 2840,  2478,  9270,
+    4194,  9195,  4518,  7469,  1160,  6878,  2730,  10421, 10036, 1734,  3815,
+    10939, 5832,  10595, 10759, 4423,  8420,  9617,  7119,  11010, 11424, 9173,
+    189,   10080, 10526, 3466,  10588, 7592,  3578,  11511, 7785,  9663,  530,
+    12150, 8957,  2532,  3317,  9349,  10243, 1481,  9332,  3454,  3758,  7899,
+    4218,  2593,  11410, 2276,  982,   6513,  1849,  8494,  9021,  4523,  7988,
+    8,     457,   648,   150,   8000,  2307,  2301,  874,   5650,  170,   9462,
+    2873,  9855,  11498, 2535,  11169, 5808,  12268, 9687,  1901,  7171,  11787,
+    3846,  1573,  6063,  3793,  466,   11259, 10608, 3821,  6320,  4649,  6263,
+    2929};
+
+uint16_t newhope_psis_inv_montgomery[PARAM_N] = {
+    256,   10570, 1510,  7238,  1034,  7170,  6291,  7921,  11665, 3422,  4000,
+    2327,  2088,  5565,  795,   10647, 1521,  5484,  2539,  7385,  1055,  7173,
+    8047,  11683, 1669,  1994,  3796,  5809,  4341,  9398,  11876, 12230, 10525,
+    12037, 12253, 3506,  4012,  9351,  4847,  2448,  7372,  9831,  3160,  2207,
+    5582,  2553,  7387,  6322,  9681,  1383,  10731, 1533,  219,   5298,  4268,
+    7632,  6357,  9686,  8406,  4712,  9451,  10128, 4958,  5975,  11387, 8649,
+    11769, 6948,  11526, 12180, 1740,  10782, 6807,  2728,  7412,  4570,  4164,
+    4106,  11120, 12122, 8754,  11784, 3439,  5758,  11356, 6889,  9762,  11928,
+    1704,  1999,  10819, 12079, 12259, 7018,  11536, 1648,  1991,  2040,  2047,
+    2048,  10826, 12080, 8748,  8272,  8204,  1172,  1923,  7297,  2798,  7422,
+    6327,  4415,  7653,  6360,  11442, 12168, 7005,  8023,  9924,  8440,  8228,
+    2931,  7441,  1063,  3663,  5790,  9605,  10150, 1450,  8985,  11817, 10466,
+    10273, 12001, 3470,  7518,  1074,  1909,  7295,  9820,  4914,  702,   5367,
+    7789,  8135,  9940,  1420,  3714,  11064, 12114, 12264, 1752,  5517,  9566,
+    11900, 1700,  3754,  5803,  829,   1874,  7290,  2797,  10933, 5073,  7747,
+    8129,  6428,  6185,  11417, 1631,  233,   5300,  9535,  10140, 11982, 8734,
+    8270,  2937,  10953, 8587,  8249,  2934,  9197,  4825,  5956,  4362,  9401,
+    1343,  3703,  529,   10609, 12049, 6988,  6265,  895,   3639,  4031,  4087,
+    4095,  585,   10617, 8539,  4731,  4187,  9376,  3095,  9220,  10095, 10220,
+    1460,  10742, 12068, 1724,  5513,  11321, 6884,  2739,  5658,  6075,  4379,
+    11159, 10372, 8504,  4726,  9453,  3106,  7466,  11600, 10435, 8513,  9994,
+    8450,  9985,  3182,  10988, 8592,  2983,  9204,  4826,  2445,  5616,  6069,
+    867,   3635,  5786,  11360, 5134,  2489,  10889, 12089, 1727,  7269,  2794,
+    9177,  1311,  5454,  9557,  6632,  2703,  9164,  10087, 1441,  3717,  531,
+    3587,  2268,  324,   5313,  759,   1864,  5533,  2546,  7386,  9833,  8427,
+    4715,  11207, 1601,  7251,  4547,  11183, 12131, 1733,  10781, 10318, 1474,
+    10744, 5046,  4232,  11138, 10369, 6748,  964,   7160,  4534,  7670,  8118,
+    8182,  4680,  11202, 6867,  981,   8918,  1274,  182,   26,    7026,  8026,
+    11680, 12202, 10521, 1503,  7237,  4545,  5916,  9623,  8397,  11733, 10454,
+    3249,  9242,  6587,  941,   1890,  270,   10572, 6777,  9746,  6659,  6218,
+    6155,  6146,  878,   1881,  7291,  11575, 12187, 1741,  7271,  8061,  11685,
+    6936,  4502,  9421,  4857,  4205,  7623,  1089,  10689, 1527,  8996,  10063,
+    11971, 10488, 6765,  2722,  3900,  9335,  11867, 6962,  11528, 5158,  4248,
+    4118,  5855,  2592,  5637,  6072,  2623,  7397,  8079,  9932,  4930,  5971,
+    853,   3633,  519,   8852,  11798, 3441,  11025, 1575,  225,   8810,  11792,
+    12218, 3501,  9278,  3081,  9218,  4828,  7712,  8124,  11694, 12204, 3499,
+    4011,  573,   3593,  5780,  7848,  9899,  10192, 1456,  208,   7052,  2763,
+    7417,  11593, 10434, 12024, 8740,  11782, 10461, 3250,  5731,  7841,  9898,
+    1414,  202,   3540,  7528,  2831,  2160,  10842, 5060,  4234,  4116,  588,
+    84,    12,    7024,  2759,  9172,  6577,  11473, 1639,  9012,  3043,  7457,
+    6332,  11438, 1634,  1989,  9062,  11828, 8712,  11778, 12216, 10523, 6770,
+    9745,  10170, 4964,  9487,  6622,  946,   8913,  6540,  6201,  4397,  9406,
+    8366,  9973,  8447,  8229,  11709, 8695,  10020, 3187,  5722,  2573,  10901,
+    6824,  4486,  4152,  9371,  8361,  2950,  2177,  311,   1800,  9035,  8313,
+    11721, 3430,  490,   70,    10,    1757,  251,   3547,  7529,  11609, 3414,
+    7510,  4584,  4166,  9373,  1339,  5458,  7802,  11648, 1664,  7260,  9815,
+    10180, 6721,  9738,  10169, 8475,  8233,  9954,  1422,  8981,  1283,  5450,
+    11312, 1616,  3742,  11068, 10359, 4991,  713,   3613,  9294,  8350,  4704,
+    672,   96,    7036,  9783,  11931, 3460,  5761,  823,   10651, 12055, 10500,
+    1500,  5481,  783,   3623,  11051, 8601,  8251,  8201,  11705, 10450, 5004,
+    4226,  7626,  2845,  2162,  3820,  7568,  9859,  3164,  452,   10598, 1514,
+    5483,  6050,  6131,  4387,  7649,  8115,  6426,  918,   8909,  8295,  1185,
+    5436,  11310, 8638,  1234,  5443,  11311, 5127,  2488,  2111,  10835, 5059,
+    7745,  2862,  3920,  560,   80,    1767,  2008,  3798,  11076, 6849,  2734,
+    10924, 12094, 8750,  1250,  10712, 6797,  971,   7161,  1023,  8924,  4786,
+    7706,  4612,  4170,  7618,  6355,  4419,  5898,  11376, 10403, 10264, 6733,
+    4473,  639,   5358,  2521,  9138,  3061,  5704,  4326,  618,   5355,  765,
+    5376,  768,   7132,  4530,  9425,  3102,  9221,  6584,  11474, 10417, 10266,
+    12000, 6981,  6264,  4406,  2385,  7363,  4563,  4163,  7617,  9866,  3165,
+    9230,  11852, 10471, 5007,  5982,  11388, 5138,  734,   3616,  11050, 12112,
+    6997,  11533, 12181, 10518, 12036, 3475,  2252,  7344,  9827,  4915,  9480,
+    6621,  4457,  7659,  9872,  6677,  4465,  4149,  7615,  4599,  657,   3605,
+    515,   10607, 6782,  4480,  640,   1847,  3775,  5806,  2585,  5636,  9583,
+    1369,  10729, 8555,  10000, 11962, 5220,  7768,  8132,  8184,  9947,  1421,
+    203,   29,    8782,  11788, 1684,  10774, 10317, 4985,  9490,  8378,  4708,
+    11206, 5112,  5997,  7879,  11659, 12199, 8765,  10030, 4944,  5973,  6120,
+    6141,  6144,  7900,  11662, 1666,  238,   34,    3516,  5769,  9602,  8394,
+    9977,  6692,  956,   10670, 6791,  9748,  11926, 8726,  11780, 5194,  742,
+    106,   8793,  10034, 3189,  10989, 5081,  4237,  5872,  4350,  2377,  10873,
+    6820,  6241,  11425, 10410, 10265, 3222,  5727,  9596,  4882,  2453,  2106,
+    3812,  11078, 12116, 5242,  4260,  11142, 8614,  11764, 12214, 5256,  4262,
+    4120,  11122, 5100,  11262, 5120,  2487,  5622,  9581,  8391,  8221,  2930,
+    10952, 12098, 6995,  6266,  9673,  4893,  699,   3611,  4027,  5842,  11368,
+    1624,  232,   8811,  8281,  1183,  169,   8802,  3013,  2186,  5579,  797,
+    3625,  4029,  11109, 1587,  7249,  11569, 8675,  6506,  2685,  10917, 12093,
+    12261, 12285, 1755,  7273,  1039,  1904,  272,   3550,  9285,  3082,  5707,
+    6082,  4380,  7648,  11626, 5172,  4250,  9385,  8363,  8217,  4685,  5936,
+    848,   8899,  6538,  934,   1889,  3781,  9318,  10109, 10222, 6727,  961,
+    5404,  772,   5377,  9546,  8386,  1198,  8949,  3034,  2189,  7335,  4559,
+    5918,  2601,  10905, 5069,  9502,  3113,  7467,  8089,  11689, 5181,  9518,
+    8382,  2953,  3933,  4073,  4093,  7607,  8109,  2914,  5683,  4323,  11151,
+    1593,  10761, 6804,  972,   3650,  2277,  5592,  4310,  7638,  9869,  4921,
+    703,   1856,  9043,  4803,  9464,  1352,  8971,  11815, 5199,  7765,  6376,
+    4422,  7654,  2849,  407,   8836,  6529,  7955,  2892,  9191,  1313,  10721,
+    12065, 12257, 1751,  9028,  8312,  2943,  2176,  3822,  546,   78,    8789,
+    11789, 10462, 12028, 6985,  4509,  9422,  1346,  5459,  4291,  613,   10621,
+    6784,  9747,  3148,  7472,  2823,  5670,  810,   7138,  8042,  4660,  7688,
+    6365,  6176,  6149,  2634,  5643,  9584,  10147, 11983, 5223,  9524,  11894,
+    10477, 8519,  1217,  3685,  2282,  326,   10580, 3267,  7489,  4581,  2410,
+    5611,  11335, 6886,  8006,  8166,  11700, 3427,  11023, 8597,  10006, 3185,
+    455,   65,    5276,  7776,  4622,  5927,  7869,  9902,  11948, 5218,  2501,
+    5624,  2559,  10899, 1557,  1978,  10816, 10323, 8497,  4725,  675,   1852,
+    10798, 12076, 10503, 3256,  9243,  3076,  2195,  10847, 12083, 10504, 12034,
+    10497};
diff --git a/src/crypto/newhope/reduce.c b/src/crypto/newhope/reduce.c
new file mode 100644
index 0000000..e7f1364
--- /dev/null
+++ b/src/crypto/newhope/reduce.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+
+/* Incomplete-reduction routines; for details on allowed input ranges
+ * and produced output ranges, see the description in the paper:
+ * https://cryptojedi.org/papers/#newhope */
+
+static const uint32_t kQInv = 12287; /* -inverse_mod(p,2^18) */
+static const uint32_t kRLog = 18;
+
+uint16_t newhope_montgomery_reduce(uint32_t a) {
+  uint32_t u;
+
+  u = (a * kQInv);
+  u &= ((1 << kRLog) - 1);
+  u *= PARAM_Q;
+  a = a + u;
+  return a >> 18;
+}
+
+uint16_t newhope_barrett_reduce(uint16_t a) {
+  uint32_t u;
+
+  u = ((uint32_t)a * 5) >> 16;
+  u *= PARAM_Q;
+  a -= u;
+  return a;
+}
diff --git a/src/crypto/obj/CMakeLists.txt b/src/crypto/obj/CMakeLists.txt
index b8a4ef3..f49d499 100644
--- a/src/crypto/obj/CMakeLists.txt
+++ b/src/crypto/obj/CMakeLists.txt
@@ -8,3 +8,14 @@
   obj.c
   obj_xref.c
 )
+
+add_executable(
+  obj_test
+
+  obj_test.cc
+
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(obj_test crypto)
+add_dependencies(all_tests obj_test)
diff --git a/src/crypto/obj/README b/src/crypto/obj/README
index 8826e59..6199fb4 100644
--- a/src/crypto/obj/README
+++ b/src/crypto/obj/README
@@ -1,17 +1,17 @@
 OID information is generated via a series of perl scripts. In order, the full
 list of commands to run are:
 
-        perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h
-        perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h
+        perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h
+        perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h
         perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h
 
 objects.txt contains the list of all built-in OIDs. It is processed by
-objects.pl to output obj_mac.num and obj_mac.h. obj_mac.num is the list of NID
+objects.pl to output obj_mac.num and nid.h. obj_mac.num is the list of NID
 values for each OID. This is an input/output parameter so NID values are stable
-across regenerations. obj_mac.h is the header which defines macros for all the
+across regenerations. nid.h is the header which defines macros for all the
 built-in OIDs in C.
 
-obj_mac.h is read by obj_dat.pl to generate obj_dat.h. obj_dat.h contains the
+nid.h is read by obj_dat.pl to generate obj_dat.h. obj_dat.h contains the
 ASN1_OBJECTs corresponding to built-in OIDs themselves along with lookup tables
 for search by short name, OID, etc.
 
@@ -28,7 +28,7 @@
                        [objects.pl] <--+
                          /      \      |
                         V        V     |
-                  obj_mac.h    obj_mac.num  obj_xref.txt
+                     nid.h     obj_mac.num  obj_xref.txt
                       |              \      /
                       V               V    V
                  [obj_dat.pl]      [obj_xref.pl]
diff --git a/src/crypto/obj/obj_dat.h b/src/crypto/obj/obj_dat.h
index bf44c6d..1d779de 100644
--- a/src/crypto/obj/obj_dat.h
+++ b/src/crypto/obj/obj_dat.h
@@ -1,6 +1,6 @@
 /* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
  * following command:
- * perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
+ * perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h */
 
 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
@@ -61,7 +61,7 @@
 #define NUM_NID 949
 #define NUM_SN 941
 #define NUM_LN 941
-#define NUM_OBJ 882
+#define NUM_OBJ 876
 
 static const unsigned char lvalues[6176]={
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  0] OBJ_rsadsi */
@@ -2482,7 +2482,7 @@
 	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},
-{"X25519","x25519",NID_x25519,0,NULL,0},
+{"X25519","X25519",NID_X25519,0,NULL,0},
 };
 
 static const unsigned int kNIDsInShortNameOrder[NUM_SN]={
@@ -3538,6 +3538,7 @@
 129,	/* "TLS Web Server Authentication" */
 133,	/* "Time Stamping" */
 375,	/* "Trust Root" */
+948,	/* "X25519" */
 12,	/* "X509" */
 402,	/* "X509v3 AC Targeting" */
 746,	/* "X509v3 Any Policy" */
@@ -4366,7 +4367,6 @@
 742,	/* "wap-wsg-idm-ecid-wtls9" */
 804,	/* "whirlpool" */
 868,	/* "x121Address" */
-948,	/* "x25519" */
 503,	/* "x500UniqueIdentifier" */
 158,	/* "x509Certificate" */
 160,	/* "x509Crl" */
@@ -4374,12 +4374,6 @@
 };
 
 static const unsigned int kNIDsInOIDOrder[NUM_OBJ]={
- 0,	/* OBJ_undef                        0 */
-181,	/* OBJ_iso                          1 */
-393,	/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
-404,	/* OBJ_ccitt                        OBJ_itu_t */
-645,	/* OBJ_itu_t                        0 */
-646,	/* OBJ_joint_iso_itu_t              2 */
 434,	/* OBJ_data                         0 9 */
 182,	/* OBJ_member_body                  1 2 */
 379,	/* OBJ_org                          1 3 */
diff --git a/src/crypto/obj/obj_dat.pl b/src/crypto/obj/obj_dat.pl
index 201ec72..036ded5 100644
--- a/src/crypto/obj/obj_dat.pl
+++ b/src/crypto/obj/obj_dat.pl
@@ -6,7 +6,7 @@
 
 if (scalar @ARGV != 2)
 	{
-	print "Usage: perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h\n";
+	print "Usage: perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h\n";
 	exit 1;
 	}
 
@@ -163,7 +163,7 @@
 	push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
 	}
 
-@a=grep(defined($obj{$nid{$_}}),0 .. $n);
+@a=grep(defined($obj{$nid{$_}}) && $objd{$obj{$nid{$_}}} =~ /,/,0 .. $n);
 foreach (sort obj_cmp @a)
 	{
 	$m=$obj{$nid{$_}};
@@ -176,7 +176,7 @@
 print OUT <<'EOF';
 /* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
  * following command:
- * perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
+ * perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h */
 
 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
diff --git a/src/crypto/obj/obj_mac.num b/src/crypto/obj/obj_mac.num
index a0e09b8..074657a 100644
--- a/src/crypto/obj/obj_mac.num
+++ b/src/crypto/obj/obj_mac.num
@@ -945,4 +945,4 @@
 dhSinglePass_cofactorDH_sha512kdf_scheme		945
 dh_std_kdf		946
 dh_cofactor_kdf		947
-x25519		948
+X25519		948
diff --git a/src/crypto/obj/obj_test.cc b/src/crypto/obj/obj_test.cc
new file mode 100644
index 0000000..2948941
--- /dev/null
+++ b/src/crypto/obj/obj_test.cc
@@ -0,0 +1,106 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
+#include <openssl/obj.h>
+
+
+static bool TestBasic() {
+  static const int kNID = NID_sha256WithRSAEncryption;
+  static const char kShortName[] = "RSA-SHA256";
+  static const char kLongName[] = "sha256WithRSAEncryption";
+  static const char kText[] = "1.2.840.113549.1.1.11";
+  static const uint8_t kDER[] = {
+      0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+  };
+
+  CBS cbs;
+  CBS_init(&cbs, kDER, sizeof(kDER));
+  if (OBJ_cbs2nid(&cbs) != kNID ||
+      OBJ_sn2nid(kShortName) != kNID ||
+      OBJ_ln2nid(kLongName) != kNID ||
+      OBJ_txt2nid(kShortName) != kNID ||
+      OBJ_txt2nid(kLongName) != kNID ||
+      OBJ_txt2nid(kText) != kNID) {
+    return false;
+  }
+
+  if (strcmp(kShortName, OBJ_nid2sn(kNID)) != 0 ||
+      strcmp(kLongName, OBJ_nid2ln(kNID)) != 0) {
+    return false;
+  }
+
+  if (OBJ_sn2nid("this is not an OID") != NID_undef ||
+      OBJ_ln2nid("this is not an OID") != NID_undef ||
+      OBJ_txt2nid("this is not an OID") != NID_undef) {
+    return false;
+  }
+
+  CBS_init(&cbs, NULL, 0);
+  if (OBJ_cbs2nid(&cbs) != NID_undef) {
+    return false;
+  }
+
+  // 1.2.840.113554.4.1.72585.2 (https://davidben.net/oid).
+  static const uint8_t kUnknownDER[] = {
+      0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02,
+  };
+  CBS_init(&cbs, kUnknownDER, sizeof(kUnknownDER));
+  if (OBJ_cbs2nid(&cbs) != NID_undef) {
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestSignatureAlgorithms() {
+  int digest_nid, pkey_nid;
+  if (!OBJ_find_sigid_algs(NID_sha256WithRSAEncryption, &digest_nid,
+                           &pkey_nid) ||
+      digest_nid != NID_sha256 || pkey_nid != NID_rsaEncryption) {
+    return false;
+  }
+
+  if (OBJ_find_sigid_algs(NID_sha256, &digest_nid, &pkey_nid)) {
+    return false;
+  }
+
+  int sign_nid;
+  if (!OBJ_find_sigid_by_algs(&sign_nid, NID_sha256, NID_rsaEncryption) ||
+      sign_nid != NID_sha256WithRSAEncryption) {
+    return false;
+  }
+
+  if (OBJ_find_sigid_by_algs(&sign_nid, NID_dsa, NID_rsaEncryption)) {
+    return false;
+  }
+
+  return true;
+}
+
+int main() {
+  CRYPTO_library_init();
+
+  if (!TestBasic() ||
+      !TestSignatureAlgorithms()) {
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/obj/objects.pl b/src/crypto/obj/objects.pl
index 7073e85..165429b 100644
--- a/src/crypto/obj/objects.pl
+++ b/src/crypto/obj/objects.pl
@@ -2,7 +2,7 @@
 
 if (scalar @ARGV != 3)
 	{
-	print "Usage: perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h\n";
+	print "Usage: perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h\n";
 	exit 1;
 	}
 
@@ -127,7 +127,7 @@
 print OUT <<'EOF';
 /* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
  * following command:
- * perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h */
+ * perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h */
 
 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
@@ -186,23 +186,43 @@
  * [including the GNU Public Licence.]
  */
 
-#define SN_undef			"UNDEF"
-#define LN_undef			"undefined"
-#define NID_undef			0
-#define OBJ_undef			0L
+#ifndef OPENSSL_HEADER_NID_H
+#define OPENSSL_HEADER_NID_H
+
+
+/* The nid library provides numbered values for ASN.1 object identifiers and
+ * other symbols. These values are used by other libraries to identify
+ * cryptographic primitives.
+ *
+ * A separate objects library, obj.h, provides functions for converting between
+ * nids and object identifiers. However it depends on large internal tables with
+ * the encodings of every nid defind. Consumers concerned with binary size
+ * should instead embed the encodings of the few consumed OIDs and compare
+ * against those.
+ *
+ * These values should not be used outside of a single process; they are not
+ * stable identifiers. */
+
+
+#define SN_undef "UNDEF"
+#define LN_undef "undefined"
+#define NID_undef 0
+#define OBJ_undef 0L
 
 EOF
 
 foreach (sort { $a <=> $b } keys %ordern)
 	{
 	$Cname=$ordern{$_};
-	print OUT "#define SN_",$Cname,"\t\t\"",$sn{$Cname},"\"\n" if $sn{$Cname} ne "";
-	print OUT "#define LN_",$Cname,"\t\t\"",$ln{$Cname},"\"\n" if $ln{$Cname} ne "";
-	print OUT "#define NID_",$Cname,"\t\t",$nid{$Cname},"\n" if $nid{$Cname} ne "";
-	print OUT "#define OBJ_",$Cname,"\t\t",$obj{$Cname},"\n" if $obj{$Cname} ne "";
+	print OUT "#define SN_",$Cname," \"",$sn{$Cname},"\"\n" if $sn{$Cname} ne "";
+	print OUT "#define LN_",$Cname," \"",$ln{$Cname},"\"\n" if $ln{$Cname} ne "";
+	print OUT "#define NID_",$Cname," ",$nid{$Cname},"\n" if $nid{$Cname} ne "";
+	print OUT "#define OBJ_",$Cname," ",$obj{$Cname},"\n" if $obj{$Cname} ne "";
 	print OUT "\n";
 	}
 
+print OUT "\n#endif  /* OPENSSL_HEADER_NID_H */\n";
+
 close OUT;
 
 sub process_oid
diff --git a/src/crypto/obj/objects.txt b/src/crypto/obj/objects.txt
index 93cf53a..f3990d0 100644
--- a/src/crypto/obj/objects.txt
+++ b/src/crypto/obj/objects.txt
@@ -1332,4 +1332,4 @@
                  : dh-cofactor-kdf
 
 # NID for X25519 (no corresponding OID).
- : X25519 : x25519
+ : X25519
diff --git a/src/crypto/pem/pem_all.c b/src/crypto/pem/pem_all.c
index c9f8b6e..e94ff26 100644
--- a/src/crypto/pem/pem_all.c
+++ b/src/crypto/pem/pem_all.c
@@ -113,159 +113,150 @@
 #include <openssl/dsa.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
-/*#include <openssl/pkcs7.h> */
+/*
+ * #include <openssl/pkcs7.h>
+ */
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
 
-
 static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
 static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
 
-
 IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
 
 IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
-
 IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
 
-
-
-/* We treat RSA or DSA private keys as a special case.
- *
- * For private keys we read in an EVP_PKEY structure with
- * PEM_read_bio_PrivateKey() and extract the relevant private
- * key: this means can handle "traditional" and PKCS#8 formats
- * transparently.
+/*
+ * We treat RSA or DSA private keys as a special case. For private keys we
+ * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
+ * the relevant private key: this means can handle "traditional" and PKCS#8
+ * formats transparently.
  */
-
 static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
 {
-	RSA *rtmp;
-	if(!key) return NULL;
-	rtmp = EVP_PKEY_get1_RSA(key);
-	EVP_PKEY_free(key);
-	if(!rtmp) return NULL;
-	if(rsa) {
-		RSA_free(*rsa);
-		*rsa = rtmp;
-	}
-	return rtmp;
+    RSA *rtmp;
+    if (!key)
+        return NULL;
+    rtmp = EVP_PKEY_get1_RSA(key);
+    EVP_PKEY_free(key);
+    if (!rtmp)
+        return NULL;
+    if (rsa) {
+        RSA_free(*rsa);
+        *rsa = rtmp;
+    }
+    return rtmp;
 }
 
 RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
-								void *u)
+                                void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-	return pkey_get_rsa(pktmp, rsa);
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_rsa(pktmp, rsa);
 }
 
 #ifndef OPENSSL_NO_FP_API
 
-RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
-								void *u)
+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-	return pkey_get_rsa(pktmp, rsa);
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_rsa(pktmp, rsa);
 }
 
 #endif
 
-IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
+                             RSAPrivateKey)
 
-IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
-IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 
+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
+                       RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
+                                                      PEM_STRING_PUBLIC,
+                                                      RSA_PUBKEY)
 #ifndef OPENSSL_NO_DSA
-
 static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
 {
-	DSA *dtmp;
-	if(!key) return NULL;
-	dtmp = EVP_PKEY_get1_DSA(key);
-	EVP_PKEY_free(key);
-	if(!dtmp) return NULL;
-	if(dsa) {
-		DSA_free(*dsa);
-		*dsa = dtmp;
-	}
-	return dtmp;
+    DSA *dtmp;
+    if (!key)
+        return NULL;
+    dtmp = EVP_PKEY_get1_DSA(key);
+    EVP_PKEY_free(key);
+    if (!dtmp)
+        return NULL;
+    if (dsa) {
+        DSA_free(*dsa);
+        *dsa = dtmp;
+    }
+    return dtmp;
 }
 
 DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
-								void *u)
+                                void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
 }
 
+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
+                             DSAPrivateKey)
 
-IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
-
-IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
-
-#ifndef OPENSSL_NO_FP_API
-
-DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
-								void *u)
+    IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
+# ifndef OPENSSL_NO_FP_API
+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
 }
 
-#endif
+# endif
 
 IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
-
 #endif
-
-
 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
 {
-	EC_KEY *dtmp;
-	if(!key) return NULL;
-	dtmp = EVP_PKEY_get1_EC_KEY(key);
-	EVP_PKEY_free(key);
-	if(!dtmp) return NULL;
-	if(eckey) 
-	{
- 		EC_KEY_free(*eckey);
-		*eckey = dtmp;
-	}
-	return dtmp;
+    EC_KEY *dtmp;
+    if (!key)
+        return NULL;
+    dtmp = EVP_PKEY_get1_EC_KEY(key);
+    EVP_PKEY_free(key);
+    if (!dtmp)
+        return NULL;
+    if (eckey) {
+        EC_KEY_free(*eckey);
+        *eckey = dtmp;
+    }
+    return dtmp;
 }
 
 EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
-							void *u)
+                                  void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-	return pkey_get_eckey(pktmp, key);	/* will free pktmp */
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_eckey(pktmp, key); /* will free pktmp */
 }
 
-IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
+                       ECPrivateKey)
 
-
-IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
-
+    IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 #ifndef OPENSSL_NO_FP_API
- 
 EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
- 								void *u)
+                              void *u)
 {
-	EVP_PKEY *pktmp;
-	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-	return pkey_get_eckey(pktmp, eckey);	/* will free pktmp */
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
 }
 
 #endif
 
-
-
 IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
 
-IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
+    IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/src/crypto/pem/pem_info.c b/src/crypto/pem/pem_info.c
index 2a39a5b..57c87d4 100644
--- a/src/crypto/pem/pem_info.c
+++ b/src/crypto/pem/pem_info.c
@@ -5,21 +5,21 @@
  * 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:
@@ -34,10 +34,10 @@
  *     Eric Young (eay@cryptsoft.com)"
  *    The word 'cryptographic' can be left out if the rouines from the library
  *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
+ * 4. If you include any Windows specific code (or a derivative thereof) from
  *    the apps directory (application code) you must include an acknowledgement:
  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,7 +49,7 @@
  * 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
@@ -71,334 +71,311 @@
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
 
-
 #ifndef OPENSSL_NO_FP_API
-STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
-	{
-        BIO *b;
-        STACK_OF(X509_INFO) *ret;
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+                                        pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    STACK_OF(X509_INFO) *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_X509_INFO_read_bio(b,sk,cb,u);
-        BIO_free(b);
-        return(ret);
-	}
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
-STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
-	{
-	X509_INFO *xi=NULL;
-	char *name=NULL,*header=NULL;
-	void *pp;
-	unsigned char *data=NULL;
-	const unsigned char *p;
-	long len,error=0;
-	int ok=0;
-	STACK_OF(X509_INFO) *ret=NULL;
-	unsigned int i,raw,ptype;
-	d2i_of_void *d2i = 0;
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+                                            pem_password_cb *cb, void *u)
+{
+    X509_INFO *xi = NULL;
+    char *name = NULL, *header = NULL;
+    void *pp;
+    unsigned char *data = NULL;
+    const unsigned char *p;
+    long len, error = 0;
+    int ok = 0;
+    STACK_OF(X509_INFO) *ret = NULL;
+    unsigned int i, raw, ptype;
+    d2i_of_void *d2i = 0;
 
-	if (sk == NULL)
-		{
-		if ((ret=sk_X509_INFO_new_null()) == NULL)
-			{
-			OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-	else
-		ret=sk;
+    if (sk == NULL) {
+        if ((ret = sk_X509_INFO_new_null()) == NULL) {
+            OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else
+        ret = sk;
 
-	if ((xi=X509_INFO_new()) == NULL) goto err;
-	for (;;)
-		{
-		raw=0;
-		ptype = 0;
-		i=PEM_read_bio(bp,&name,&header,&data,&len);
-		if (i == 0)
-			{
-			error=ERR_GET_REASON(ERR_peek_last_error());
-			if (error == PEM_R_NO_START_LINE)
-				{
-				ERR_clear_error();
-				break;
-				}
-			goto err;
-			}
-start:
-		if (	(strcmp(name,PEM_STRING_X509) == 0) ||
-			(strcmp(name,PEM_STRING_X509_OLD) == 0))
-			{
-			d2i=(D2I_OF(void))d2i_X509;
-			if (xi->x509 != NULL)
-				{
-				if (!sk_X509_INFO_push(ret,xi)) goto err;
-				if ((xi=X509_INFO_new()) == NULL) goto err;
-				goto start;
-				}
-			pp=&(xi->x509);
-			}
-		else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))
-			{
-			d2i=(D2I_OF(void))d2i_X509_AUX;
-			if (xi->x509 != NULL)
-				{
-				if (!sk_X509_INFO_push(ret,xi)) goto err;
-				if ((xi=X509_INFO_new()) == NULL) goto err;
-				goto start;
-				}
-			pp=&(xi->x509);
-			}
-		else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
-			{
-			d2i=(D2I_OF(void))d2i_X509_CRL;
-			if (xi->crl != NULL)
-				{
-				if (!sk_X509_INFO_push(ret,xi)) goto err;
-				if ((xi=X509_INFO_new()) == NULL) goto err;
-				goto start;
-				}
-			pp=&(xi->crl);
-			}
-		else
-			if (strcmp(name,PEM_STRING_RSA) == 0)
-			{
-			d2i=(D2I_OF(void))d2i_RSAPrivateKey;
-			if (xi->x_pkey != NULL) 
-				{
-				if (!sk_X509_INFO_push(ret,xi)) goto err;
-				if ((xi=X509_INFO_new()) == NULL) goto err;
-				goto start;
-				}
+    if ((xi = X509_INFO_new()) == NULL)
+        goto err;
+    for (;;) {
+        raw = 0;
+        ptype = 0;
+        i = PEM_read_bio(bp, &name, &header, &data, &len);
+        if (i == 0) {
+            error = ERR_GET_REASON(ERR_peek_last_error());
+            if (error == PEM_R_NO_START_LINE) {
+                ERR_clear_error();
+                break;
+            }
+            goto err;
+        }
+ start:
+        if ((strcmp(name, PEM_STRING_X509) == 0) ||
+            (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
+            d2i = (D2I_OF(void)) d2i_X509;
+            if (xi->x509 != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->x509);
+        } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
+            d2i = (D2I_OF(void)) d2i_X509_AUX;
+            if (xi->x509 != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->x509);
+        } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
+            d2i = (D2I_OF(void)) d2i_X509_CRL;
+            if (xi->crl != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->crl);
+        } else if (strcmp(name, PEM_STRING_RSA) == 0) {
+            d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
 
-			xi->enc_data=NULL;
-			xi->enc_len=0;
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
 
-			xi->x_pkey=X509_PKEY_new();
-			ptype=EVP_PKEY_RSA;
-			pp=&xi->x_pkey->dec_pkey;
-			if ((int)strlen(header) > 10) /* assume encrypted */
-				raw=1;
-			}
-		else
+            xi->x_pkey = X509_PKEY_new();
+            ptype = EVP_PKEY_RSA;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else
 #ifndef OPENSSL_NO_DSA
-			if (strcmp(name,PEM_STRING_DSA) == 0)
-			{
-			d2i=(D2I_OF(void))d2i_DSAPrivateKey;
-			if (xi->x_pkey != NULL) 
-				{
-				if (!sk_X509_INFO_push(ret,xi)) goto err;
-				if ((xi=X509_INFO_new()) == NULL) goto err;
-				goto start;
-				}
+        if (strcmp(name, PEM_STRING_DSA) == 0) {
+            d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
 
-			xi->enc_data=NULL;
-			xi->enc_len=0;
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
 
-			xi->x_pkey=X509_PKEY_new();
-			ptype = EVP_PKEY_DSA;
-			pp=&xi->x_pkey->dec_pkey;
-			if ((int)strlen(header) > 10) /* assume encrypted */
-				raw=1;
-			}
-		else
+            xi->x_pkey = X509_PKEY_new();
+            ptype = EVP_PKEY_DSA;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else
 #endif
- 			if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0)
- 			{
- 				d2i=(D2I_OF(void))d2i_ECPrivateKey;
- 				if (xi->x_pkey != NULL) 
- 				{
- 					if (!sk_X509_INFO_push(ret,xi)) goto err;
- 					if ((xi=X509_INFO_new()) == NULL) goto err;
- 						goto start;
- 				}
- 
- 			xi->enc_data=NULL;
- 			xi->enc_len=0;
- 
- 			xi->x_pkey=X509_PKEY_new();
-			ptype = EVP_PKEY_EC;
- 			pp=&xi->x_pkey->dec_pkey;
- 			if ((int)strlen(header) > 10) /* assume encrypted */
- 				raw=1;
-			}
-		else
-			{
-			d2i=NULL;
-			pp=NULL;
-			}
+        if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
+            d2i = (D2I_OF(void)) d2i_ECPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
 
-		if (d2i != NULL)
-			{
-			if (!raw)
-				{
-				EVP_CIPHER_INFO cipher;
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
 
-				if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
-					goto err;
-				if (!PEM_do_header(&cipher,data,&len,cb,u))
-					goto err;
-				p=data;
-				if (ptype)
-					{
-					if (!d2i_PrivateKey(ptype, pp, &p, len))
-						{
-						OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-						goto err;
-						}
-					}
-				else if (d2i(pp,&p,len) == NULL)
-					{
-					OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-					goto err;
-					}
-				}
-			else
-				{ /* encrypted RSA data */
-				if (!PEM_get_EVP_CIPHER_INFO(header,
-					&xi->enc_cipher)) goto err;
-				xi->enc_data=(char *)data;
-				xi->enc_len=(int)len;
-				data=NULL;
-				}
-			}
-		else	{
-			/* unknown */
-			}
-		if (name != NULL) OPENSSL_free(name);
-		if (header != NULL) OPENSSL_free(header);
-		if (data != NULL) OPENSSL_free(data);
-		name=NULL;
-		header=NULL;
-		data=NULL;
-		}
+            xi->x_pkey = X509_PKEY_new();
+            ptype = EVP_PKEY_EC;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else {
+            d2i = NULL;
+            pp = NULL;
+        }
 
-	/* if the last one hasn't been pushed yet and there is anything
-	 * in it then add it to the stack ... 
-	 */
-	if ((xi->x509 != NULL) || (xi->crl != NULL) ||
-		(xi->x_pkey != NULL) || (xi->enc_data != NULL))
-		{
-		if (!sk_X509_INFO_push(ret,xi)) goto err;
-		xi=NULL;
-		}
-	ok=1;
-err:
-	if (xi != NULL) X509_INFO_free(xi);
-	if (!ok)
-		{
-		for (i=0; i<sk_X509_INFO_num(ret); i++)
-			{
-			xi=sk_X509_INFO_value(ret,i);
-			X509_INFO_free(xi);
-			}
-		if (ret != sk) sk_X509_INFO_free(ret);
-		ret=NULL;
-		}
-		
-	if (name != NULL) OPENSSL_free(name);
-	if (header != NULL) OPENSSL_free(header);
-	if (data != NULL) OPENSSL_free(data);
-	return(ret);
-	}
+        if (d2i != NULL) {
+            if (!raw) {
+                EVP_CIPHER_INFO cipher;
 
+                if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+                    goto err;
+                if (!PEM_do_header(&cipher, data, &len, cb, u))
+                    goto err;
+                p = data;
+                if (ptype) {
+                    if (!d2i_PrivateKey(ptype, pp, &p, len)) {
+                        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+                        goto err;
+                    }
+                } else if (d2i(pp, &p, len) == NULL) {
+                    OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+                    goto err;
+                }
+            } else {            /* encrypted RSA data */
+                if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
+                    goto err;
+                xi->enc_data = (char *)data;
+                xi->enc_len = (int)len;
+                data = NULL;
+            }
+        } else {
+            /* unknown */
+        }
+        if (name != NULL)
+            OPENSSL_free(name);
+        if (header != NULL)
+            OPENSSL_free(header);
+        if (data != NULL)
+            OPENSSL_free(data);
+        name = NULL;
+        header = NULL;
+        data = NULL;
+    }
+
+    /*
+     * if the last one hasn't been pushed yet and there is anything in it
+     * then add it to the stack ...
+     */
+    if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+        (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
+        if (!sk_X509_INFO_push(ret, xi))
+            goto err;
+        xi = NULL;
+    }
+    ok = 1;
+ err:
+    if (xi != NULL)
+        X509_INFO_free(xi);
+    if (!ok) {
+        for (i = 0; i < sk_X509_INFO_num(ret); i++) {
+            xi = sk_X509_INFO_value(ret, i);
+            X509_INFO_free(xi);
+        }
+        if (ret != sk)
+            sk_X509_INFO_free(ret);
+        ret = NULL;
+    }
+
+    if (name != NULL)
+        OPENSSL_free(name);
+    if (header != NULL)
+        OPENSSL_free(header);
+    if (data != NULL)
+        OPENSSL_free(data);
+    return (ret);
+}
 
 /* A TJH addition */
 int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
-	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
-	{
-	EVP_CIPHER_CTX ctx;
-	int i,ret=0;
-	unsigned char *data=NULL;
-	const char *objstr=NULL;
-	char buf[PEM_BUFSIZE];
-	unsigned char *iv=NULL;
-	unsigned iv_len = 0;
-	
-	if (enc != NULL)
-		{
-		iv_len = EVP_CIPHER_iv_length(enc);
-		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
-		if (objstr == NULL)
-			{
-			OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
-			goto err;
-			}
-		}
+                            unsigned char *kstr, int klen,
+                            pem_password_cb *cb, void *u)
+{
+    EVP_CIPHER_CTX ctx;
+    int i, ret = 0;
+    unsigned char *data = NULL;
+    const char *objstr = NULL;
+    char buf[PEM_BUFSIZE];
+    unsigned char *iv = NULL;
+    unsigned iv_len = 0;
 
-	/* now for the fun part ... if we have a private key then 
-	 * we have to be able to handle a not-yet-decrypted key
-	 * being written out correctly ... if it is decrypted or
-	 * it is non-encrypted then we use the base code
-	 */
-	if (xi->x_pkey!=NULL)
-		{
-		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
-			{
-			if (enc == NULL)
-				{
-				OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
-				goto err;
-				}
+    if (enc != NULL) {
+        iv_len = EVP_CIPHER_iv_length(enc);
+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+        if (objstr == NULL) {
+            OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+            goto err;
+        }
+    }
 
-			/* copy from weirdo names into more normal things */
-			iv=xi->enc_cipher.iv;
-			data=(unsigned char *)xi->enc_data;
-			i=xi->enc_len;
+    /*
+     * now for the fun part ... if we have a private key then we have to be
+     * able to handle a not-yet-decrypted key being written out correctly ...
+     * if it is decrypted or it is non-encrypted then we use the base code
+     */
+    if (xi->x_pkey != NULL) {
+        if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
+            if (enc == NULL) {
+                OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
+                goto err;
+            }
 
-			/* we take the encryption data from the
-			 * internal stuff rather than what the
-			 * user has passed us ... as we have to 
-			 * match exactly for some strange reason
-			 */
-			objstr=OBJ_nid2sn(
-				EVP_CIPHER_nid(xi->enc_cipher.cipher));
-			if (objstr == NULL)
-				{
-				OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
-				goto err;
-				}
+            /* copy from weirdo names into more normal things */
+            iv = xi->enc_cipher.iv;
+            data = (unsigned char *)xi->enc_data;
+            i = xi->enc_len;
 
-			/* create the right magic header stuff */
-			assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf);
-			buf[0]='\0';
-			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
-			PEM_dek_info(buf,objstr,iv_len,(char *)iv);
+            /*
+             * we take the encryption data from the internal stuff rather
+             * than what the user has passed us ... as we have to match
+             * exactly for some strange reason
+             */
+            objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
+            if (objstr == NULL) {
+                OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+                goto err;
+            }
 
-			/* use the normal code to write things out */
-			i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
-			if (i <= 0) goto err;
-			}
-		else
-			{
-			/* Add DSA/DH */
-			/* normal optionally encrypted stuff */
-			if (PEM_write_bio_RSAPrivateKey(bp,
-				xi->x_pkey->dec_pkey->pkey.rsa,
-				enc,kstr,klen,cb,u)<=0)
-				goto err;
-			}
-		}
+            /* create the right magic header stuff */
+            assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf);
+            buf[0] = '\0';
+            PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+            PEM_dek_info(buf, objstr, iv_len, (char *)iv);
 
-	/* if we have a certificate then write it out now */
-	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))
-		goto err;
+            /* use the normal code to write things out */
+            i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
+            if (i <= 0)
+                goto err;
+        } else {
+            /* Add DSA/DH */
+            /* normal optionally encrypted stuff */
+            if (PEM_write_bio_RSAPrivateKey(bp,
+                                            xi->x_pkey->dec_pkey->pkey.rsa,
+                                            enc, kstr, klen, cb, u) <= 0)
+                goto err;
+        }
+    }
 
-	/* we are ignoring anything else that is loaded into the X509_INFO
-	 * structure for the moment ... as I don't need it so I'm not
-	 * coding it here and Eric can do it when this makes it into the
-	 * base library --tjh
-	 */
+    /* if we have a certificate then write it out now */
+    if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
+        goto err;
 
-	ret=1;
+    /*
+     * we are ignoring anything else that is loaded into the X509_INFO
+     * structure for the moment ... as I don't need it so I'm not coding it
+     * here and Eric can do it when this makes it into the base library --tjh
+     */
 
-err:
-	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
-	OPENSSL_cleanse(buf,PEM_BUFSIZE);
-	return(ret);
-	}
+    ret = 1;
+
+ err:
+    OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
+    return (ret);
+}
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 12d9674..6e928a6 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -71,761 +71,708 @@
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
-#include "../evp/internal.h"
+#define MIN_LENGTH      4
 
-
-#define MIN_LENGTH	4
-
-static int load_iv(char **fromp,unsigned char *to, int num);
+static int load_iv(char **fromp, unsigned char *to, int num);
 static int check_pem(const char *nm, const char *name);
-int pem_check_suffix(const char *pem_str, const char *suffix);
 
 void PEM_proc_type(char *buf, int type)
-	{
-	const char *str;
+{
+    const char *str;
 
-	if (type == PEM_TYPE_ENCRYPTED)
-		str="ENCRYPTED";
-	else if (type == PEM_TYPE_MIC_CLEAR)
-		str="MIC-CLEAR";
-	else if (type == PEM_TYPE_MIC_ONLY)
-		str="MIC-ONLY";
-	else
-		str="BAD-TYPE";
-		
-	BUF_strlcat(buf,"Proc-Type: 4,",PEM_BUFSIZE);
-	BUF_strlcat(buf,str,PEM_BUFSIZE);
-	BUF_strlcat(buf,"\n",PEM_BUFSIZE);
-	}
+    if (type == PEM_TYPE_ENCRYPTED)
+        str = "ENCRYPTED";
+    else if (type == PEM_TYPE_MIC_CLEAR)
+        str = "MIC-CLEAR";
+    else if (type == PEM_TYPE_MIC_ONLY)
+        str = "MIC-ONLY";
+    else
+        str = "BAD-TYPE";
+
+    BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
+    BUF_strlcat(buf, str, PEM_BUFSIZE);
+    BUF_strlcat(buf, "\n", PEM_BUFSIZE);
+}
 
 void PEM_dek_info(char *buf, const char *type, int len, char *str)
-	{
-	static const unsigned char map[17]="0123456789ABCDEF";
-	long i;
-	int j;
+{
+    static const unsigned char map[17] = "0123456789ABCDEF";
+    long i;
+    int j;
 
-	BUF_strlcat(buf,"DEK-Info: ",PEM_BUFSIZE);
-	BUF_strlcat(buf,type,PEM_BUFSIZE);
-	BUF_strlcat(buf,",",PEM_BUFSIZE);
-	j=strlen(buf);
-	if (j + (len * 2) + 1 > PEM_BUFSIZE)
-        	return;
-	for (i=0; i<len; i++)
-		{
-		buf[j+i*2]  =map[(str[i]>>4)&0x0f];
-		buf[j+i*2+1]=map[(str[i]   )&0x0f];
-		}
-	buf[j+i*2]='\n';
-	buf[j+i*2+1]='\0';
-	}
+    BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+    BUF_strlcat(buf, type, PEM_BUFSIZE);
+    BUF_strlcat(buf, ",", PEM_BUFSIZE);
+    j = strlen(buf);
+    if (j + (len * 2) + 1 > PEM_BUFSIZE)
+        return;
+    for (i = 0; i < len; i++) {
+        buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+        buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+    }
+    buf[j + i * 2] = '\n';
+    buf[j + i * 2 + 1] = '\0';
+}
 
 #ifndef OPENSSL_NO_FP_API
 void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
-		    pem_password_cb *cb, void *u)
-	{
-        BIO *b;
-        void *ret;
+                    pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    void *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_ASN1_read_bio(d2i,name,b,x,cb,u);
-        BIO_free(b);
-        return(ret);
-	}
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 static int check_pem(const char *nm, const char *name)
 {
-	/* Normal matching nm and name */
-	if (!strcmp(nm,name)) return 1;
+    /* Normal matching nm and name */
+    if (!strcmp(nm, name))
+        return 1;
 
-	/* Make PEM_STRING_EVP_PKEY match any private key */
+    /* Make PEM_STRING_EVP_PKEY match any private key */
 
-	if(!strcmp(name,PEM_STRING_EVP_PKEY))
-		{
-		int slen;
-		const EVP_PKEY_ASN1_METHOD *ameth;
-		if(!strcmp(nm,PEM_STRING_PKCS8))
-			return 1;
-		if(!strcmp(nm,PEM_STRING_PKCS8INF))
-			return 1;
-		slen = pem_check_suffix(nm, "PRIVATE KEY"); 
-		if (slen > 0)
-			{
-			/* NB: ENGINE implementations wont contain
-			 * a deprecated old private key decode function
-			 * so don't look for them.
-			 */
-			ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
-			if (ameth && ameth->old_priv_decode)
-				return 1;
-			}
-		return 0;
-		}
+    if (!strcmp(name, PEM_STRING_EVP_PKEY)) {
+        return !strcmp(nm, PEM_STRING_PKCS8) ||
+               !strcmp(nm, PEM_STRING_PKCS8INF) ||
+               !strcmp(nm, PEM_STRING_RSA) ||
+               !strcmp(nm, PEM_STRING_EC) ||
+               !strcmp(nm, PEM_STRING_DSA);
+    }
 
-	if(!strcmp(name,PEM_STRING_PARAMETERS))
-		{
-		int slen;
-		const EVP_PKEY_ASN1_METHOD *ameth;
-		slen = pem_check_suffix(nm, "PARAMETERS"); 
-		if (slen > 0)
-			{
-			ENGINE *e;
-			ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
-			if (ameth)
-				{
-				int r;
-				if (ameth->param_decode)
-					r = 1;
-				else
-					r = 0;
-				return r;
-				}
-			}
-		return 0;
-		}
-	/* Permit older strings */
+    /* Permit older strings */
 
-	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
-		!strcmp(name,PEM_STRING_X509)) return 1;
+    if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509))
+        return 1;
 
-	if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
-		!strcmp(name,PEM_STRING_X509_REQ)) return 1;
+    if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
+        !strcmp(name, PEM_STRING_X509_REQ))
+        return 1;
 
-	/* Allow normal certs to be read as trusted certs */
-	if(!strcmp(nm,PEM_STRING_X509) &&
-		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+    /* Allow normal certs to be read as trusted certs */
+    if (!strcmp(nm, PEM_STRING_X509) &&
+        !strcmp(name, PEM_STRING_X509_TRUSTED))
+        return 1;
 
-	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
-		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+    if (!strcmp(nm, PEM_STRING_X509_OLD) &&
+        !strcmp(name, PEM_STRING_X509_TRUSTED))
+        return 1;
 
-	/* Some CAs use PKCS#7 with CERTIFICATE headers */
-	if(!strcmp(nm, PEM_STRING_X509) &&
-		!strcmp(name, PEM_STRING_PKCS7)) return 1;
+    /* Some CAs use PKCS#7 with CERTIFICATE headers */
+    if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7))
+        return 1;
 
-	if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
-		!strcmp(name, PEM_STRING_PKCS7)) return 1;
+    if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
+        !strcmp(name, PEM_STRING_PKCS7))
+        return 1;
 
 #ifndef OPENSSL_NO_CMS
-	if(!strcmp(nm, PEM_STRING_X509) &&
-		!strcmp(name, PEM_STRING_CMS)) return 1;
-	/* Allow CMS to be read from PKCS#7 headers */
-	if(!strcmp(nm, PEM_STRING_PKCS7) &&
-		!strcmp(name, PEM_STRING_CMS)) return 1;
+    if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS))
+        return 1;
+    /* Allow CMS to be read from PKCS#7 headers */
+    if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS))
+        return 1;
 #endif
 
-	return 0;
+    return 0;
 }
 
-int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
-	     pem_password_cb *cb, void *u)
-	{
-	EVP_CIPHER_INFO cipher;
-	char *nm=NULL,*header=NULL;
-	unsigned char *data=NULL;
-	long len;
-	int ret = 0;
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+                       const char *name, BIO *bp, pem_password_cb *cb,
+                       void *u)
+{
+    EVP_CIPHER_INFO cipher;
+    char *nm = NULL, *header = NULL;
+    unsigned char *data = NULL;
+    long len;
+    int ret = 0;
 
-	for (;;)
-		{
-		if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
-			if(ERR_GET_REASON(ERR_peek_error()) ==
-				PEM_R_NO_START_LINE)
-				ERR_add_error_data(2, "Expecting: ", name);
-			return 0;
-		}
-		if(check_pem(nm, name)) break;
-		OPENSSL_free(nm);
-		OPENSSL_free(header);
-		OPENSSL_free(data);
-		}
-	if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err;
-	if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err;
+    for (;;) {
+        if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
+            if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
+                ERR_add_error_data(2, "Expecting: ", name);
+            return 0;
+        }
+        if (check_pem(nm, name))
+            break;
+        OPENSSL_free(nm);
+        OPENSSL_free(header);
+        OPENSSL_free(data);
+    }
+    if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+        goto err;
+    if (!PEM_do_header(&cipher, data, &len, cb, u))
+        goto err;
 
-	*pdata = data;
-	*plen = len;
+    *pdata = data;
+    *plen = len;
 
-	if (pnm)
-		*pnm = nm;
+    if (pnm)
+        *pnm = nm;
 
-	ret = 1;
+    ret = 1;
 
-err:
-	if (!ret || !pnm) OPENSSL_free(nm);
-	OPENSSL_free(header);
-	if (!ret) OPENSSL_free(data);
-	return ret;
-	}
+ err:
+    if (!ret || !pnm)
+        OPENSSL_free(nm);
+    OPENSSL_free(header);
+    if (!ret)
+        OPENSSL_free(data);
+    return ret;
+}
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
-		   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
-		   int klen, pem_password_cb *callback, void *u)
-        {
-        BIO *b;
-        int ret;
+                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                   int klen, pem_password_cb *callback, void *u)
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
-		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
-		       int klen, pem_password_cb *callback, void *u)
-	{
-	EVP_CIPHER_CTX ctx;
-	int dsize=0,i,j,ret=0;
-	unsigned char *p,*data=NULL;
-	const char *objstr=NULL;
-	char buf[PEM_BUFSIZE];
-	unsigned char key[EVP_MAX_KEY_LENGTH];
-	unsigned char iv[EVP_MAX_IV_LENGTH];
-	
-	if (enc != NULL)
-		{
-		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
-		if (objstr == NULL)
-			{
-			OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
-			goto err;
-			}
-		}
+                       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                       int klen, pem_password_cb *callback, void *u)
+{
+    EVP_CIPHER_CTX ctx;
+    int dsize = 0, i, j, ret = 0;
+    unsigned char *p, *data = NULL;
+    const char *objstr = NULL;
+    char buf[PEM_BUFSIZE];
+    unsigned char key[EVP_MAX_KEY_LENGTH];
+    unsigned char iv[EVP_MAX_IV_LENGTH];
 
-	if ((dsize=i2d(x,NULL)) < 0)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-		dsize=0;
-		goto err;
-		}
-	/* dzise + 8 bytes are needed */
-	/* actually it needs the cipher block size extra... */
-	data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
-	if (data == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	p=data;
-	i=i2d(x,&p);
+    if (enc != NULL) {
+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+        if (objstr == NULL) {
+            OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+            goto err;
+        }
+    }
 
-	if (enc != NULL)
-		{
-		const unsigned iv_len = EVP_CIPHER_iv_length(enc);
+    if ((dsize = i2d(x, NULL)) < 0) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+        dsize = 0;
+        goto err;
+    }
+    /* dzise + 8 bytes are needed */
+    /* actually it needs the cipher block size extra... */
+    data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20);
+    if (data == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = data;
+    i = i2d(x, &p);
 
-		if (kstr == NULL)
-			{
-			klen = 0;
-			if (!callback)
-				callback = PEM_def_callback;
- 			klen=(*callback)(buf,PEM_BUFSIZE,1,u);
-			if (klen <= 0)
-				{
-				OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
-				goto err;
-				}
-			kstr=(unsigned char *)buf;
-			}
-		assert(iv_len <= (int)sizeof(iv));
-		if (!RAND_bytes(iv, iv_len)) /* Generate a salt */
-			goto err;
-		/* The 'iv' is used as the iv and as a salt.  It is
-		 * NOT taken from the BytesToKey function */
-		if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
-			goto err;
+    if (enc != NULL) {
+        const unsigned iv_len = EVP_CIPHER_iv_length(enc);
 
-		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
+        if (kstr == NULL) {
+            klen = 0;
+            if (!callback)
+                callback = PEM_def_callback;
+            klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
+            if (klen <= 0) {
+                OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
+                goto err;
+            }
+            kstr = (unsigned char *)buf;
+        }
+        assert(iv_len <= (int)sizeof(iv));
+        if (!RAND_bytes(iv, iv_len)) /* Generate a salt */
+            goto err;
+        /*
+         * The 'iv' is used as the iv and as a salt.  It is NOT taken from
+         * the BytesToKey function
+         */
+        if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
+            goto err;
 
-		assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf);
+        if (kstr == (unsigned char *)buf)
+            OPENSSL_cleanse(buf, PEM_BUFSIZE);
 
-		buf[0]='\0';
-		PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
-		PEM_dek_info(buf,objstr,iv_len,(char *)iv);
-		/* k=strlen(buf); */
+        assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf);
 
-		EVP_CIPHER_CTX_init(&ctx);
-		ret = 1;
-		if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
-			|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
-			|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
-			ret = 0;
-		else
-			i += j;
-		EVP_CIPHER_CTX_cleanup(&ctx);
-		if (ret == 0)
-			goto err;
-		}
-	else
-		{
-		ret=1;
-		buf[0]='\0';
-		}
-	i=PEM_write_bio(bp,name,buf,data,i);
-	if (i <= 0) ret=0;
-err:
-	OPENSSL_cleanse(key,sizeof(key));
-	OPENSSL_cleanse(iv,sizeof(iv));
-	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
-	OPENSSL_cleanse(buf,PEM_BUFSIZE);
-	if (data != NULL)
-		{
-		OPENSSL_cleanse(data,(unsigned int)dsize);
-		OPENSSL_free(data);
-		}
-	return(ret);
-	}
+        buf[0] = '\0';
+        PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+        PEM_dek_info(buf, objstr, iv_len, (char *)iv);
+        /* k=strlen(buf); */
+
+        EVP_CIPHER_CTX_init(&ctx);
+        ret = 1;
+        if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv)
+            || !EVP_EncryptUpdate(&ctx, data, &j, data, i)
+            || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
+            ret = 0;
+        else
+            i += j;
+        EVP_CIPHER_CTX_cleanup(&ctx);
+        if (ret == 0)
+            goto err;
+    } else {
+        ret = 1;
+        buf[0] = '\0';
+    }
+    i = PEM_write_bio(bp, name, buf, data, i);
+    if (i <= 0)
+        ret = 0;
+ err:
+    OPENSSL_cleanse(key, sizeof(key));
+    OPENSSL_cleanse(iv, sizeof(iv));
+    OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
+    if (data != NULL) {
+        OPENSSL_cleanse(data, (unsigned int)dsize);
+        OPENSSL_free(data);
+    }
+    return (ret);
+}
 
 int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
-	     pem_password_cb *callback,void *u)
-	{
-	int i=0,j,o,klen;
-	long len;
-	EVP_CIPHER_CTX ctx;
-	unsigned char key[EVP_MAX_KEY_LENGTH];
-	char buf[PEM_BUFSIZE];
+                  pem_password_cb *callback, void *u)
+{
+    int i = 0, j, o, klen;
+    long len;
+    EVP_CIPHER_CTX ctx;
+    unsigned char key[EVP_MAX_KEY_LENGTH];
+    char buf[PEM_BUFSIZE];
 
-	len= *plen;
+    len = *plen;
 
-	if (cipher->cipher == NULL) return(1);
+    if (cipher->cipher == NULL)
+        return (1);
 
-	klen = 0;
-	if (!callback) callback = PEM_def_callback;
-	klen=callback(buf,PEM_BUFSIZE,0,u);
-	if (klen <= 0)
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
-		return(0);
-		}
+    klen = 0;
+    if (!callback)
+        callback = PEM_def_callback;
+    klen = callback(buf, PEM_BUFSIZE, 0, u);
+    if (klen <= 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+        return (0);
+    }
 
-	if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
-		(unsigned char *)buf,klen,1,key,NULL))
-		return 0;
+    if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
+                        (unsigned char *)buf, klen, 1, key, NULL))
+        return 0;
 
-	j=(int)len;
-	EVP_CIPHER_CTX_init(&ctx);
-	o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
-	if (o)
-		o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
-	if (o)
-		o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
-	EVP_CIPHER_CTX_cleanup(&ctx);
-	OPENSSL_cleanse((char *)buf,sizeof(buf));
-	OPENSSL_cleanse((char *)key,sizeof(key));
-	if (!o)
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
-		return(0);
-		}
-	j+=i;
-	*plen=j;
-	return(1);
-	}
+    j = (int)len;
+    EVP_CIPHER_CTX_init(&ctx);
+    o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
+    if (o)
+        o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
+    if (o)
+        o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    OPENSSL_cleanse((char *)buf, sizeof(buf));
+    OPENSSL_cleanse((char *)key, sizeof(key));
+    if (!o) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
+        return (0);
+    }
+    j += i;
+    *plen = j;
+    return (1);
+}
 
-static const EVP_CIPHER* cipher_by_name(const char *name) {
-  /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */
-  if (0 == strcmp(name, SN_rc4)) {
-    return EVP_rc4();
-  } else if (0 == strcmp(name, SN_des_cbc)) {
-    return EVP_des_cbc();
-  } else if (0 == strcmp(name, SN_des_ede3_cbc)) {
-    return EVP_des_ede3_cbc();
-  } else if (0 == strcmp(name, SN_aes_128_cbc)) {
-    return EVP_aes_128_cbc();
-  } else if (0 == strcmp(name, SN_aes_192_cbc)) {
-    return EVP_aes_192_cbc();
-  } else if (0 == strcmp(name, SN_aes_256_cbc)) {
-    return EVP_aes_256_cbc();
-  } else {
-    return NULL;
-  }
+static const EVP_CIPHER *cipher_by_name(const char *name)
+{
+    /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */
+    if (0 == strcmp(name, SN_rc4)) {
+        return EVP_rc4();
+    } else if (0 == strcmp(name, SN_des_cbc)) {
+        return EVP_des_cbc();
+    } else if (0 == strcmp(name, SN_des_ede3_cbc)) {
+        return EVP_des_ede3_cbc();
+    } else if (0 == strcmp(name, SN_aes_128_cbc)) {
+        return EVP_aes_128_cbc();
+    } else if (0 == strcmp(name, SN_aes_192_cbc)) {
+        return EVP_aes_192_cbc();
+    } else if (0 == strcmp(name, SN_aes_256_cbc)) {
+        return EVP_aes_256_cbc();
+    } else {
+        return NULL;
+    }
 }
 
 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
-	{
-	const EVP_CIPHER *enc=NULL;
-	char *p,c;
-	char **header_pp = &header;
+{
+    const EVP_CIPHER *enc = NULL;
+    char *p, c;
+    char **header_pp = &header;
 
-	cipher->cipher=NULL;
-	if ((header == NULL) || (*header == '\0') || (*header == '\n'))
-		return(1);
-	if (strncmp(header,"Proc-Type: ",11) != 0)
-		{ OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); return(0); }
-	header+=11;
-	if (*header != '4') return(0); header++;
-	if (*header != ',') return(0); header++;
-	if (strncmp(header,"ENCRYPTED",9) != 0)
-		{ OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); return(0); }
-	for (; (*header != '\n') && (*header != '\0'); header++)
-		;
-	if (*header == '\0')
-		{ OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); return(0); }
-	header++;
-	if (strncmp(header,"DEK-Info: ",10) != 0)
-		{ OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); return(0); }
-	header+=10;
+    cipher->cipher = NULL;
+    if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+        return (1);
+    if (strncmp(header, "Proc-Type: ", 11) != 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE);
+        return (0);
+    }
+    header += 11;
+    if (*header != '4')
+        return (0);
+    header++;
+    if (*header != ',')
+        return (0);
+    header++;
+    if (strncmp(header, "ENCRYPTED", 9) != 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED);
+        return (0);
+    }
+    for (; (*header != '\n') && (*header != '\0'); header++) ;
+    if (*header == '\0') {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER);
+        return (0);
+    }
+    header++;
+    if (strncmp(header, "DEK-Info: ", 10) != 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO);
+        return (0);
+    }
+    header += 10;
 
-	p=header;
-	for (;;)
-		{
-		c= *header;
-		if (!(	((c >= 'A') && (c <= 'Z')) || (c == '-') ||
-			((c >= '0') && (c <= '9'))))
-			break;
-		header++;
-		}
-	*header='\0';
-	cipher->cipher=enc=cipher_by_name(p);
-	*header=c;
-	header++;
+    p = header;
+    for (;;) {
+        c = *header;
+        if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') ||
+              ((c >= '0') && (c <= '9'))))
+            break;
+        header++;
+    }
+    *header = '\0';
+    cipher->cipher = enc = cipher_by_name(p);
+    *header = c;
+    header++;
 
-	if (enc == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
-		return(0);
-		}
-	if (!load_iv(header_pp,&(cipher->iv[0]),EVP_CIPHER_iv_length(enc)))
-		return(0);
+    if (enc == NULL) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
+        return (0);
+    }
+    if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc)))
+        return (0);
 
-	return(1);
-	}
+    return (1);
+}
 
 static int load_iv(char **fromp, unsigned char *to, int num)
-	{
-	int v,i;
-	char *from;
+{
+    int v, i;
+    char *from;
 
-	from= *fromp;
-	for (i=0; i<num; i++) to[i]=0;
-	num*=2;
-	for (i=0; i<num; i++)
-		{
-		if ((*from >= '0') && (*from <= '9'))
-			v= *from-'0';
-		else if ((*from >= 'A') && (*from <= 'F'))
-			v= *from-'A'+10;
-		else if ((*from >= 'a') && (*from <= 'f'))
-			v= *from-'a'+10;
-		else
-			{
-			OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
-			return(0);
-			}
-		from++;
-		to[i/2]|=v<<(long)((!(i&1))*4);
-		}
+    from = *fromp;
+    for (i = 0; i < num; i++)
+        to[i] = 0;
+    num *= 2;
+    for (i = 0; i < num; i++) {
+        if ((*from >= '0') && (*from <= '9'))
+            v = *from - '0';
+        else if ((*from >= 'A') && (*from <= 'F'))
+            v = *from - 'A' + 10;
+        else if ((*from >= 'a') && (*from <= 'f'))
+            v = *from - 'a' + 10;
+        else {
+            OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
+            return (0);
+        }
+        from++;
+        to[i / 2] |= v << (long)((!(i & 1)) * 4);
+    }
 
-	*fromp=from;
-	return(1);
-	}
+    *fromp = from;
+    return (1);
+}
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_write(FILE *fp, const char *name, const char *header,
-	      const unsigned char *data, long len)
-        {
-        BIO *b;
-        int ret;
+              const unsigned char *data, long len)
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_write_bio(b, name, header, data,len);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_write_bio(b, name, header, data, len);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 int PEM_write_bio(BIO *bp, const char *name, const char *header,
-		  const unsigned char *data, long len)
-	{
-	int nlen,n,i,j,outl;
-	unsigned char *buf = NULL;
-	EVP_ENCODE_CTX ctx;
-	int reason=ERR_R_BUF_LIB;
-	
-	EVP_EncodeInit(&ctx);
-	nlen=strlen(name);
+                  const unsigned char *data, long len)
+{
+    int nlen, n, i, j, outl;
+    unsigned char *buf = NULL;
+    EVP_ENCODE_CTX ctx;
+    int reason = ERR_R_BUF_LIB;
 
-	if (	(BIO_write(bp,"-----BEGIN ",11) != 11) ||
-		(BIO_write(bp,name,nlen) != nlen) ||
-		(BIO_write(bp,"-----\n",6) != 6))
-		goto err;
-		
-	i=strlen(header);
-	if (i > 0)
-		{
-		if (	(BIO_write(bp,header,i) != i) ||
-			(BIO_write(bp,"\n",1) != 1))
-			goto err;
-		}
+    EVP_EncodeInit(&ctx);
+    nlen = strlen(name);
 
-	buf = OPENSSL_malloc(PEM_BUFSIZE*8);
-	if (buf == NULL)
-		{
-		reason=ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
+    if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
+        (BIO_write(bp, name, nlen) != nlen) ||
+        (BIO_write(bp, "-----\n", 6) != 6))
+        goto err;
 
-	i=j=0;
-	while (len > 0)
-		{
-		n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len);
-		EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n);
-		if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl))
-			goto err;
-		i+=outl;
-		len-=n;
-		j+=n;
-		}
-	EVP_EncodeFinal(&ctx,buf,&outl);
-	if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err;
-	OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
-	OPENSSL_free(buf);
-	buf = NULL;
-	if (	(BIO_write(bp,"-----END ",9) != 9) ||
-		(BIO_write(bp,name,nlen) != nlen) ||
-		(BIO_write(bp,"-----\n",6) != 6))
-		goto err;
-	return(i+outl);
-err:
-	if (buf) {
-		OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
-		OPENSSL_free(buf);
-	}
-	OPENSSL_PUT_ERROR(PEM, reason);
-	return(0);
-	}
+    i = strlen(header);
+    if (i > 0) {
+        if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
+            goto err;
+    }
+
+    buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
+    if (buf == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+
+    i = j = 0;
+    while (len > 0) {
+        n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
+        EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
+        if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
+            goto err;
+        i += outl;
+        len -= n;
+        j += n;
+    }
+    EVP_EncodeFinal(&ctx, buf, &outl);
+    if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
+        goto err;
+    OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+    OPENSSL_free(buf);
+    buf = NULL;
+    if ((BIO_write(bp, "-----END ", 9) != 9) ||
+        (BIO_write(bp, name, nlen) != nlen) ||
+        (BIO_write(bp, "-----\n", 6) != 6))
+        goto err;
+    return (i + outl);
+ err:
+    if (buf) {
+        OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+        OPENSSL_free(buf);
+    }
+    OPENSSL_PUT_ERROR(PEM, reason);
+    return (0);
+}
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
-	     long *len)
-        {
-        BIO *b;
-        int ret;
+             long *len)
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_read_bio(b, name, header, data,len);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio(b, name, header, data, len);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
-	     long *len)
-	{
-	EVP_ENCODE_CTX ctx;
-	int end=0,i,k,bl=0,hl=0,nohead=0;
-	char buf[256];
-	BUF_MEM *nameB;
-	BUF_MEM *headerB;
-	BUF_MEM *dataB,*tmpB;
-	
-	nameB=BUF_MEM_new();
-	headerB=BUF_MEM_new();
-	dataB=BUF_MEM_new();
-	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
-		{
-		BUF_MEM_free(nameB);
-		BUF_MEM_free(headerB);
-		BUF_MEM_free(dataB);
-		OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
+                 long *len)
+{
+    EVP_ENCODE_CTX ctx;
+    int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
+    char buf[256];
+    BUF_MEM *nameB;
+    BUF_MEM *headerB;
+    BUF_MEM *dataB, *tmpB;
 
-	buf[254]='\0';
-	for (;;)
-		{
-		i=BIO_gets(bp,buf,254);
+    nameB = BUF_MEM_new();
+    headerB = BUF_MEM_new();
+    dataB = BUF_MEM_new();
+    if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
+        BUF_MEM_free(nameB);
+        BUF_MEM_free(headerB);
+        BUF_MEM_free(dataB);
+        OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
 
-		if (i <= 0)
-			{
-			OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
-			goto err;
-			}
+    buf[254] = '\0';
+    for (;;) {
+        i = BIO_gets(bp, buf, 254);
 
-		while ((i >= 0) && (buf[i] <= ' ')) i--;
-		buf[++i]='\n'; buf[++i]='\0';
+        if (i <= 0) {
+            OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
+            goto err;
+        }
 
-		if (strncmp(buf,"-----BEGIN ",11) == 0)
-			{
-			i=strlen(&(buf[11]));
+        while ((i >= 0) && (buf[i] <= ' '))
+            i--;
+        buf[++i] = '\n';
+        buf[++i] = '\0';
 
-			if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
-				continue;
-			if (!BUF_MEM_grow(nameB,i+9))
-				{
-				OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			memcpy(nameB->data,&(buf[11]),i-6);
-			nameB->data[i-6]='\0';
-			break;
-			}
-		}
-	hl=0;
-	if (!BUF_MEM_grow(headerB,256))
-		{ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
-	headerB->data[0]='\0';
-	for (;;)
-		{
-		i=BIO_gets(bp,buf,254);
-		if (i <= 0) break;
+        if (strncmp(buf, "-----BEGIN ", 11) == 0) {
+            i = strlen(&(buf[11]));
 
-		while ((i >= 0) && (buf[i] <= ' ')) i--;
-		buf[++i]='\n'; buf[++i]='\0';
+            if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
+                continue;
+            if (!BUF_MEM_grow(nameB, i + 9)) {
+                OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            memcpy(nameB->data, &(buf[11]), i - 6);
+            nameB->data[i - 6] = '\0';
+            break;
+        }
+    }
+    hl = 0;
+    if (!BUF_MEM_grow(headerB, 256)) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    headerB->data[0] = '\0';
+    for (;;) {
+        i = BIO_gets(bp, buf, 254);
+        if (i <= 0)
+            break;
 
-		if (buf[0] == '\n') break;
-		if (!BUF_MEM_grow(headerB,hl+i+9))
-			{ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
-		if (strncmp(buf,"-----END ",9) == 0)
-			{
-			nohead=1;
-			break;
-			}
-		memcpy(&(headerB->data[hl]),buf,i);
-		headerB->data[hl+i]='\0';
-		hl+=i;
-		}
+        while ((i >= 0) && (buf[i] <= ' '))
+            i--;
+        buf[++i] = '\n';
+        buf[++i] = '\0';
 
-	bl=0;
-	if (!BUF_MEM_grow(dataB,1024))
-		{ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
-	dataB->data[0]='\0';
-	if (!nohead)
-		{
-		for (;;)
-			{
-			i=BIO_gets(bp,buf,254);
-			if (i <= 0) break;
+        if (buf[0] == '\n')
+            break;
+        if (!BUF_MEM_grow(headerB, hl + i + 9)) {
+            OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (strncmp(buf, "-----END ", 9) == 0) {
+            nohead = 1;
+            break;
+        }
+        memcpy(&(headerB->data[hl]), buf, i);
+        headerB->data[hl + i] = '\0';
+        hl += i;
+    }
 
-			while ((i >= 0) && (buf[i] <= ' ')) i--;
-			buf[++i]='\n'; buf[++i]='\0';
+    bl = 0;
+    if (!BUF_MEM_grow(dataB, 1024)) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    dataB->data[0] = '\0';
+    if (!nohead) {
+        for (;;) {
+            i = BIO_gets(bp, buf, 254);
+            if (i <= 0)
+                break;
 
-			if (i != 65) end=1;
-			if (strncmp(buf,"-----END ",9) == 0)
-				break;
-			if (i > 65) break;
-			if (!BUF_MEM_grow_clean(dataB,i+bl+9))
-				{
-				OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			memcpy(&(dataB->data[bl]),buf,i);
-			dataB->data[bl+i]='\0';
-			bl+=i;
-			if (end)
-				{
-				buf[0]='\0';
-				i=BIO_gets(bp,buf,254);
-				if (i <= 0) break;
+            while ((i >= 0) && (buf[i] <= ' '))
+                i--;
+            buf[++i] = '\n';
+            buf[++i] = '\0';
 
-				while ((i >= 0) && (buf[i] <= ' ')) i--;
-				buf[++i]='\n'; buf[++i]='\0';
+            if (i != 65)
+                end = 1;
+            if (strncmp(buf, "-----END ", 9) == 0)
+                break;
+            if (i > 65)
+                break;
+            if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
+                OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            memcpy(&(dataB->data[bl]), buf, i);
+            dataB->data[bl + i] = '\0';
+            bl += i;
+            if (end) {
+                buf[0] = '\0';
+                i = BIO_gets(bp, buf, 254);
+                if (i <= 0)
+                    break;
 
-				break;
-				}
-			}
-		}
-	else
-		{
-		tmpB=headerB;
-		headerB=dataB;
-		dataB=tmpB;
-		bl=hl;
-		}
-	i=strlen(nameB->data);
-	if (	(strncmp(buf,"-----END ",9) != 0) ||
-		(strncmp(nameB->data,&(buf[9]),i) != 0) ||
-		(strncmp(&(buf[9+i]),"-----\n",6) != 0))
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
-		goto err;
-		}
+                while ((i >= 0) && (buf[i] <= ' '))
+                    i--;
+                buf[++i] = '\n';
+                buf[++i] = '\0';
 
-	EVP_DecodeInit(&ctx);
-	i=EVP_DecodeUpdate(&ctx,
-		(unsigned char *)dataB->data,&bl,
-		(unsigned char *)dataB->data,bl);
-	if (i < 0)
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
-		goto err;
-		}
-	i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
-	if (i < 0)
-		{
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
-		goto err;
-		}
-	bl+=k;
+                break;
+            }
+        }
+    } else {
+        tmpB = headerB;
+        headerB = dataB;
+        dataB = tmpB;
+        bl = hl;
+    }
+    i = strlen(nameB->data);
+    if ((strncmp(buf, "-----END ", 9) != 0) ||
+        (strncmp(nameB->data, &(buf[9]), i) != 0) ||
+        (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
+        goto err;
+    }
 
-	if (bl == 0) goto err;
-	*name=nameB->data;
-	*header=headerB->data;
-	*data=(unsigned char *)dataB->data;
-	*len=bl;
-	OPENSSL_free(nameB);
-	OPENSSL_free(headerB);
-	OPENSSL_free(dataB);
-	return(1);
-err:
-	BUF_MEM_free(nameB);
-	BUF_MEM_free(headerB);
-	BUF_MEM_free(dataB);
-	return(0);
-	}
+    EVP_DecodeInit(&ctx);
+    i = EVP_DecodeUpdate(&ctx,
+                         (unsigned char *)dataB->data, &bl,
+                         (unsigned char *)dataB->data, bl);
+    if (i < 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
+        goto err;
+    }
+    i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
+    if (i < 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
+        goto err;
+    }
+    bl += k;
 
-/* Check pem string and return prefix length.
- * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
- * the return value is 3 for the string "RSA".
- */
-
-int pem_check_suffix(const char *pem_str, const char *suffix)
-	{
-	int pem_len = strlen(pem_str);
-	int suffix_len = strlen(suffix);
-	const char *p;
-	if (suffix_len + 1 >= pem_len)
-		return 0;
-	p = pem_str + pem_len - suffix_len;
-	if (strcmp(p, suffix))
-		return 0;
-	p--;
-	if (*p != ' ')
-		return 0;
-	return p - pem_str;
-	}
+    if (bl == 0)
+        goto err;
+    *name = nameB->data;
+    *header = headerB->data;
+    *data = (unsigned char *)dataB->data;
+    *len = bl;
+    OPENSSL_free(nameB);
+    OPENSSL_free(headerB);
+    OPENSSL_free(dataB);
+    return (1);
+ err:
+    BUF_MEM_free(nameB);
+    BUF_MEM_free(headerB);
+    BUF_MEM_free(dataB);
+    return (0);
+}
 
 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;
-	}
+{
+    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_oth.c b/src/crypto/pem/pem_oth.c
index 3e8f6bd..8530c56 100644
--- a/src/crypto/pem/pem_oth.c
+++ b/src/crypto/pem/pem_oth.c
@@ -67,23 +67,22 @@
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
-
 /* Handle 'other' PEMs: not private keys */
 
 void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
-			pem_password_cb *cb, void *u)
-	{
-	const unsigned char *p=NULL;
-	unsigned char *data=NULL;
-	long len;
-	char *ret=NULL;
+                        pem_password_cb *cb, void *u)
+{
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    char *ret = NULL;
 
-	if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
-		return NULL;
-	p = data;
-	ret=d2i(x,&p,len);
-	if (ret == NULL)
-		OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-	OPENSSL_free(data);
-	return ret;
-	}
+    if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+        return NULL;
+    p = data;
+    ret = d2i(x, &p, len);
+    if (ret == NULL)
+        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+    OPENSSL_free(data);
+    return ret;
+}
diff --git a/src/crypto/pem/pem_pk8.c b/src/crypto/pem/pem_pk8.c
index 0824477..550661d 100644
--- a/src/crypto/pem/pem_pk8.c
+++ b/src/crypto/pem/pem_pk8.c
@@ -65,180 +65,193 @@
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
-
 static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
-				int nid, const EVP_CIPHER *enc,
-				char *kstr, int klen,
-				pem_password_cb *cb, void *u);
+                      int nid, const EVP_CIPHER *enc,
+                      char *kstr, int klen, pem_password_cb *cb, void *u);
 static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
-				int nid, const EVP_CIPHER *enc,
-				char *kstr, int klen,
-				pem_password_cb *cb, void *u);
+                         int nid, const EVP_CIPHER *enc,
+                         char *kstr, int klen, pem_password_cb *cb, void *u);
 
-/* These functions write a private key in PKCS#8 format: it is a "drop in"
+/*
+ * These functions write a private key in PKCS#8 format: it is a "drop in"
  * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
  * is NULL then it uses the unencrypted private key form. The 'nid' versions
  * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
  */
 
 int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                                      char *kstr, int klen,
+                                      pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
 }
 
 int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
 }
 
 int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                            char *kstr, int klen,
+                            pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
 }
 
 int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                                char *kstr, int klen,
+                                pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
 }
 
-static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+                      const EVP_CIPHER *enc, char *kstr, int klen,
+                      pem_password_cb *cb, void *u)
 {
-	X509_SIG *p8;
-	PKCS8_PRIV_KEY_INFO *p8inf;
-	char buf[PEM_BUFSIZE];
-	int ret;
-	if(!(p8inf = EVP_PKEY2PKCS8(x))) {
-		OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
-		return 0;
-	}
-	if(enc || (nid != -1)) {
-		if(!kstr) {
-			klen = 0;
-			if (!cb) cb = PEM_def_callback;
-			klen = cb(buf, PEM_BUFSIZE, 1, u);
-			if(klen <= 0) {
-				OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
-				PKCS8_PRIV_KEY_INFO_free(p8inf);
-				return 0;
-			}
-				
-			kstr = buf;
-		}
-		p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
-		if(kstr == buf) OPENSSL_cleanse(buf, klen);
-		PKCS8_PRIV_KEY_INFO_free(p8inf);
-		if(isder) ret = i2d_PKCS8_bio(bp, p8);
-		else ret = PEM_write_bio_PKCS8(bp, p8);
-		X509_SIG_free(p8);
-		return ret;
-	} else {
-		if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
-		else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
-		PKCS8_PRIV_KEY_INFO_free(p8inf);
-		return ret;
-	}
+    X509_SIG *p8;
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    char buf[PEM_BUFSIZE];
+    int ret;
+    if (!(p8inf = EVP_PKEY2PKCS8(x))) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+        return 0;
+    }
+    if (enc || (nid != -1)) {
+        if (!kstr) {
+            klen = 0;
+            if (!cb)
+                cb = PEM_def_callback;
+            klen = cb(buf, PEM_BUFSIZE, 1, u);
+            if (klen <= 0) {
+                OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
+                PKCS8_PRIV_KEY_INFO_free(p8inf);
+                return 0;
+            }
+
+            kstr = buf;
+        }
+        p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+        if (kstr == buf)
+            OPENSSL_cleanse(buf, klen);
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+        if (isder)
+            ret = i2d_PKCS8_bio(bp, p8);
+        else
+            ret = PEM_write_bio_PKCS8(bp, p8);
+        X509_SIG_free(p8);
+        return ret;
+    } else {
+        if (isder)
+            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+        else
+            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+        return ret;
+    }
 }
 
-EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u)
 {
-	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
-	X509_SIG *p8 = NULL;
-	int klen;
-	EVP_PKEY *ret;
-	char psbuf[PEM_BUFSIZE];
-	p8 = d2i_PKCS8_bio(bp, NULL);
-	if(!p8) return NULL;
+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+    X509_SIG *p8 = NULL;
+    int klen;
+    EVP_PKEY *ret;
+    char psbuf[PEM_BUFSIZE];
+    p8 = d2i_PKCS8_bio(bp, NULL);
+    if (!p8)
+        return NULL;
 
-	klen = 0;
-	if (!cb) cb = PEM_def_callback;
-	klen=cb(psbuf,PEM_BUFSIZE,0,u);
-	if (klen <= 0) {
-		OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
-		X509_SIG_free(p8);
-		return NULL;	
-	}
-	p8inf = PKCS8_decrypt(p8, psbuf, klen);
-	X509_SIG_free(p8);
-	if(!p8inf) return NULL;
-	ret = EVP_PKCS82PKEY(p8inf);
-	PKCS8_PRIV_KEY_INFO_free(p8inf);
-	if(!ret) return NULL;
-	if(x) {
-		if(*x) EVP_PKEY_free(*x);
-		*x = ret;
-	}
-	return ret;
+    klen = 0;
+    if (!cb)
+        cb = PEM_def_callback;
+    klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+    if (klen <= 0) {
+        OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+        X509_SIG_free(p8);
+        return NULL;
+    }
+    p8inf = PKCS8_decrypt(p8, psbuf, klen);
+    X509_SIG_free(p8);
+    if (!p8inf)
+        return NULL;
+    ret = EVP_PKCS82PKEY(p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    if (!ret)
+        return NULL;
+    if (x) {
+        if (*x)
+            EVP_PKEY_free(*x);
+        *x = ret;
+    }
+    return ret;
 }
 
 #ifndef OPENSSL_NO_FP_API
 
 int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                           char *kstr, int klen, pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
 }
 
 int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                               char *kstr, int klen,
+                               pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
 }
 
 int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u)
 {
-	return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
 }
 
 int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-			      char *kstr, int klen, pem_password_cb *cb, void *u)
+                              char *kstr, int klen, pem_password_cb *cb,
+                              void *u)
 {
-	return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
 }
 
-static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u)
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
+                         const EVP_CIPHER *enc, char *kstr, int klen,
+                         pem_password_cb *cb, void *u)
 {
-	BIO *bp;
-	int ret;
-	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-	}
-	ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
-	BIO_free(bp);
-	return ret;
+    BIO *bp;
+    int ret;
+    if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+    BIO_free(bp);
+    return ret;
 }
 
-EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                                 void *u)
 {
-	BIO *bp;
-	EVP_PKEY *ret;
-	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return NULL;
-	}
-	ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
-	BIO_free(bp);
-	return ret;
+    BIO *bp;
+    EVP_PKEY *ret;
+    if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+    BIO_free(bp);
+    return ret;
 }
 
 #endif
 
 IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+
+
 IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
-							 PKCS8_PRIV_KEY_INFO)
+             PKCS8_PRIV_KEY_INFO)
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index cd334b4..058c031 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -69,240 +69,159 @@
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
-#include "../evp/internal.h"
+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u)
+{
+    char *nm = NULL;
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    EVP_PKEY *ret = NULL;
 
+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
+        return NULL;
+    p = data;
 
-int pem_check_suffix(const char *pem_str, const char *suffix);
+    if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
+        PKCS8_PRIV_KEY_INFO *p8inf;
+        p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
+        if (!p8inf)
+            goto p8err;
+        ret = EVP_PKCS82PKEY(p8inf);
+        if (x) {
+            if (*x)
+                EVP_PKEY_free((EVP_PKEY *)*x);
+            *x = ret;
+        }
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+    } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
+        PKCS8_PRIV_KEY_INFO *p8inf;
+        X509_SIG *p8;
+        int klen;
+        char psbuf[PEM_BUFSIZE];
+        p8 = d2i_X509_SIG(NULL, &p, len);
+        if (!p8)
+            goto p8err;
 
-EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
-	{
-	char *nm=NULL;
-	const unsigned char *p=NULL;
-	unsigned char *data=NULL;
-	long len;
-	int slen;
-	EVP_PKEY *ret=NULL;
+        klen = 0;
+        if (!cb)
+            cb = PEM_def_callback;
+        klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+        if (klen <= 0) {
+            OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+            X509_SIG_free(p8);
+            goto err;
+        }
+        p8inf = PKCS8_decrypt(p8, psbuf, klen);
+        X509_SIG_free(p8);
+        if (!p8inf)
+            goto p8err;
+        ret = EVP_PKCS82PKEY(p8inf);
+        if (x) {
+            if (*x)
+                EVP_PKEY_free((EVP_PKEY *)*x);
+            *x = ret;
+        }
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+    } else if (strcmp(nm, PEM_STRING_RSA) == 0) {
+        /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the
+         * standalone format. This and the cases below probably should not
+         * accept PKCS#8. */
+        ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len);
+    } else if (strcmp(nm, PEM_STRING_EC) == 0) {
+        ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len);
+    } else if (strcmp(nm, PEM_STRING_DSA) == 0) {
+        ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len);
+    }
+ p8err:
+    if (ret == NULL)
+        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
 
-	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
-		return NULL;
-	p = data;
-
-	if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
-		PKCS8_PRIV_KEY_INFO *p8inf;
-		p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
-		if(!p8inf) goto p8err;
-		ret = EVP_PKCS82PKEY(p8inf);
-		if(x) {
-			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
-			*x = ret;
-		}
-		PKCS8_PRIV_KEY_INFO_free(p8inf);
-	} else if (strcmp(nm,PEM_STRING_PKCS8) == 0) {
-		PKCS8_PRIV_KEY_INFO *p8inf;
-		X509_SIG *p8;
-		int klen;
-		char psbuf[PEM_BUFSIZE];
-		p8 = d2i_X509_SIG(NULL, &p, len);
-		if(!p8) goto p8err;
-
-		klen = 0;
-		if (!cb) cb = PEM_def_callback;
-		klen=cb(psbuf,PEM_BUFSIZE,0,u);
-		if (klen <= 0) {
-			OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
-			X509_SIG_free(p8);
-			goto err;
-		}
-		p8inf = PKCS8_decrypt(p8, psbuf, klen);
-		X509_SIG_free(p8);
-		if(!p8inf) goto p8err;
-		ret = EVP_PKCS82PKEY(p8inf);
-		if(x) {
-			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
-			*x = ret;
-		}
-		PKCS8_PRIV_KEY_INFO_free(p8inf);
-	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
-		{
-		const EVP_PKEY_ASN1_METHOD *ameth;
-		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
-		if (!ameth || !ameth->old_priv_decode)
-			goto p8err;
-		ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
-		}
-p8err:
-	if (ret == NULL)
-		OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-
-err:
-	OPENSSL_free(nm);
-	OPENSSL_cleanse(data, len);
-	OPENSSL_free(data);
-	return(ret);
-	}
+ err:
+    OPENSSL_free(nm);
+    OPENSSL_cleanse(data, len);
+    OPENSSL_free(data);
+    return (ret);
+}
 
 int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-                                               unsigned char *kstr, int klen,
-                                               pem_password_cb *cb, void *u)
-	{
-	char pem_str[80];
-	if (!x->ameth || x->ameth->priv_encode)
-		return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
-							(char *)kstr, klen,
-							cb, u);
-
-	BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
-	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
-				pem_str,bp,x,enc,kstr,klen,cb,u);
-	}
-
-static int public_key_type_from_str(const char *name, size_t len) {
-  if (len == 3 && memcmp(name, "RSA", 3) == 0) {
-    return EVP_PKEY_RSA;
-  } else if (len == 2 && memcmp(name, "DH", 2) == 0) {
-    return EVP_PKEY_DH;
-  } else if (len == 2 && memcmp(name, "EC", 2) == 0) {
-    return EVP_PKEY_EC;
-  }
-  return NID_undef;
+                             unsigned char *kstr, int klen,
+                             pem_password_cb *cb, void *u)
+{
+    return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u);
 }
 
-static int set_pkey_type_from_str(EVP_PKEY *pkey, const char *name, size_t len) {
-  int nid = public_key_type_from_str(name, len);
-  if (nid == NID_undef) {
-    return 0;
-  }
-  return EVP_PKEY_set_type(pkey, nid);
-}
-
-EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
-	{
-	char *nm=NULL;
-	const unsigned char *p=NULL;
-	unsigned char *data=NULL;
-	long len;
-	int slen;
-	EVP_PKEY *ret=NULL;
-
-	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
-								bp, 0, NULL))
-		return NULL;
-	p = data;
-
-	if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
-		{
-		ret = EVP_PKEY_new();
-		if (!ret)
-			goto err;
-		if (!set_pkey_type_from_str(ret, nm, slen)
-			|| !ret->ameth->param_decode
-			|| !ret->ameth->param_decode(ret, &p, len))
-			{
-			EVP_PKEY_free(ret);
-			ret = NULL;
-			goto err;
-			}
-		if(x)
-			{
-			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
-			*x = ret;
-			}
-		}
-err:
-	if (ret == NULL)
-		OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-	OPENSSL_free(nm);
-	OPENSSL_free(data);
-	return(ret);
-	}
-
-int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
-	{
-	char pem_str[80];
-	if (!x->ameth || !x->ameth->param_encode)
-		return 0;
-
-	BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
-	return PEM_ASN1_write_bio(
-		(i2d_of_void *)x->ameth->param_encode,
-				pem_str,bp,x,NULL,NULL,0,0,NULL);
-	}
-
 #ifndef OPENSSL_NO_FP_API
-EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
-	{
-        BIO *b;
-        EVP_PKEY *ret;
+EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                              void *u)
+{
+    BIO *b;
+    EVP_PKEY *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_read_bio_PrivateKey(b,x,cb,u);
-        BIO_free(b);
-        return(ret);
-	}
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio_PrivateKey(b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
 
 int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-                                               unsigned char *kstr, int klen,
-                                               pem_password_cb *cb, void *u)
-	{
-        BIO *b;
-        int ret;
+                         unsigned char *kstr, int klen,
+                         pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return 0;
-		}
-        ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
-        BIO_free(b);
-        return ret;
-	}
+    if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return 0;
+    }
+    ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+    BIO_free(b);
+    return ret;
+}
 
 #endif
 
-
 /* Transparently read in PKCS#3 or X9.42 DH parameters */
 
 DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
-	{
-	char *nm=NULL;
-	const unsigned char *p=NULL;
-	unsigned char *data=NULL;
-	long len;
-	DH *ret=NULL;
+{
+    char *nm = NULL;
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    DH *ret = NULL;
 
-	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS,
-								bp, cb, u))
-		return NULL;
-	p = data;
+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u))
+        return NULL;
+    p = data;
 
-	ret = d2i_DHparams(x, &p, len);
+    ret = d2i_DHparams(x, &p, len);
 
-	if (ret == NULL)
-		OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-	OPENSSL_free(nm);
-	OPENSSL_free(data);
-	return ret;
-	}
+    if (ret == NULL)
+        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+    OPENSSL_free(nm);
+    OPENSSL_free(data);
+    return ret;
+}
 
 #ifndef OPENSSL_NO_FP_API
 DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
-	{
-        BIO *b;
-        DH *ret;
+{
+    BIO *b;
+    DH *ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=PEM_read_bio_DHparams(b,x,cb,u);
-        BIO_free(b);
-        return(ret);
-	}
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio_DHparams(b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
 #endif
diff --git a/src/crypto/pem/pem_x509.c b/src/crypto/pem/pem_x509.c
index f463047..97f814d 100644
--- a/src/crypto/pem/pem_x509.c
+++ b/src/crypto/pem/pem_x509.c
@@ -1,6 +1,7 @@
 /* pem_x509.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
  */
 /* ====================================================================
  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
@@ -61,5 +62,4 @@
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 
-
 IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
diff --git a/src/crypto/pem/pem_xaux.c b/src/crypto/pem/pem_xaux.c
index 8dabd41..386dd60 100644
--- a/src/crypto/pem/pem_xaux.c
+++ b/src/crypto/pem/pem_xaux.c
@@ -1,6 +1,7 @@
 /* pem_xaux.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
  */
 /* ====================================================================
  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
@@ -61,6 +62,6 @@
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 
-
 IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
-IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, X509_CERT_PAIR)
+IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR,
+                 X509_CERT_PAIR)
diff --git a/src/crypto/perlasm/arm-xlate.pl b/src/crypto/perlasm/arm-xlate.pl
index 706fa70..6e9b019 100755
--- a/src/crypto/perlasm/arm-xlate.pl
+++ b/src/crypto/perlasm/arm-xlate.pl
@@ -55,7 +55,9 @@
 			      };
     }
 
-    $ret = ".globl	$name" if (!$ret);
+    $ret = ".globl	$name\n";
+    # All symbols in assembly files are hidden.
+    $ret .= &$hidden($name);
     $$global = $name;
     $ret;
 };
@@ -165,6 +167,6 @@
     print "\n";
 }
 
-print "#endif" if ($flavour eq "linux32" || $flavour eq "linux64");
+print "#endif\n" if ($flavour eq "linux32" || $flavour eq "linux64");
 
 close STDOUT;
diff --git a/src/crypto/perlasm/x86_64-xlate.pl b/src/crypto/perlasm/x86_64-xlate.pl
index 3ebb018..4965985 100755
--- a/src/crypto/perlasm/x86_64-xlate.pl
+++ b/src/crypto/perlasm/x86_64-xlate.pl
@@ -190,14 +190,17 @@
     sub out {
     	my $self = shift;
 
+	$self->{value} =~ s/\b(0b[0-1]+)/oct($1)/eig;
 	if ($gas) {
 	    # Solaris /usr/ccs/bin/as can't handle multiplications
 	    # in $self->{value}
-	    $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
-	    $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+	    my $value = $self->{value};
+	    $value =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+	    if ($value =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg) {
+	        $self->{value} = $value;
+	    }
 	    sprintf "\$%s",$self->{value};
 	} else {
-	    $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
 	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
 	    sprintf "%s",$self->{value};
 	}
diff --git a/src/crypto/perlasm/x86gas.pl b/src/crypto/perlasm/x86gas.pl
index 99d7c1b..55d09d8 100644
--- a/src/crypto/perlasm/x86gas.pl
+++ b/src/crypto/perlasm/x86gas.pl
@@ -17,7 +17,7 @@
 { my $reg=shift;
     if    ($reg =~ m/^%e/o)		{ "l"; }
     elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
-    elsif ($reg =~ m/^%[xm]/o)		{ undef; }
+    elsif ($reg =~ m/^%[yxm]/o)		{ undef; }
     else				{ "w"; }
 }
 
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index 9550109..ffb3821 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -1,7 +1,7 @@
 include_directories(../../include)
 
 add_library(
-  pkcs8
+  pkcs8_lib
 
   OBJECT
 
diff --git a/src/crypto/pkcs8/p5_pbe.c b/src/crypto/pkcs8/p5_pbe.c
index 653cabf..8e56d41 100644
--- a/src/crypto/pkcs8/p5_pbe.c
+++ b/src/crypto/pkcs8/p5_pbe.c
@@ -57,6 +57,7 @@
 
 #include <openssl/asn1t.h>
 #include <openssl/err.h>
+#include <openssl/obj.h>
 #include <openssl/pkcs8.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
diff --git a/src/crypto/pkcs8/p5_pbev2.c b/src/crypto/pkcs8/p5_pbev2.c
index fec0d86..3799b39 100644
--- a/src/crypto/pkcs8/p5_pbev2.c
+++ b/src/crypto/pkcs8/p5_pbev2.c
@@ -61,6 +61,7 @@
 #include <openssl/cipher.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
+#include <openssl/obj.h>
 #include <openssl/pkcs8.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
diff --git a/src/crypto/pkcs8/pkcs12_test.cc b/src/crypto/pkcs8/pkcs12_test.cc
index 55006b4..17bcd27 100644
--- a/src/crypto/pkcs8/pkcs12_test.cc
+++ b/src/crypto/pkcs8/pkcs12_test.cc
@@ -708,7 +708,7 @@
 }
 
 static bool TestCompat(const uint8_t *der, size_t der_len) {
-  ScopedBIO bio(BIO_new_mem_buf((void*) der, der_len));
+  ScopedBIO bio(BIO_new_mem_buf(der, der_len));
   if (!bio) {
     return false;
   }
@@ -757,7 +757,6 @@
 
 int main(int argc, char **argv) {
   CRYPTO_library_init();
-  ERR_load_crypto_strings();
 
   if (!Test("OpenSSL", kOpenSSL, sizeof(kOpenSSL)) ||
       !Test("NSS", kNSS, sizeof(kNSS)) ||
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 31a34a7..4ecf17f 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -60,18 +60,18 @@
 #include <string.h>
 
 #include <openssl/asn1.h>
-#include <openssl/bn.h>
 #include <openssl/buf.h>
+#include <openssl/bytestring.h>
 #include <openssl/cipher.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/hmac.h>
 #include <openssl/mem.h>
+#include <openssl/obj.h>
 #include <openssl/x509.h>
 
 #include "internal.h"
 #include "../bytestring/internal.h"
-#include "../evp/internal.h"
 
 
 #define PKCS12_KEY_ID 1
@@ -106,112 +106,122 @@
 
 static int pkcs12_key_gen_raw(const uint8_t *pass_raw, size_t pass_raw_len,
                               const uint8_t *salt, size_t salt_len,
-                              int id, int iterations,
+                              uint8_t id, int iterations,
                               size_t out_len, uint8_t *out,
-                              const EVP_MD *md_type) {
-  uint8_t *B, *D, *I, *p, *Ai;
-  int Slen, Plen, Ilen, Ijlen;
-  int i, j, v;
-  size_t u;
-  int ret = 0;
-  BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
-  EVP_MD_CTX ctx;
+                              const EVP_MD *md) {
+  /* See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the
+   * specification have errata applied and other typos fixed. */
 
+  if (iterations < 1) {
+    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+    return 0;
+  }
+
+  /* In the spec, |block_size| is called "v", but measured in bits. */
+  size_t block_size = EVP_MD_block_size(md);
+
+  /* 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies
+   * of ID. */
+  uint8_t D[EVP_MAX_MD_BLOCK_SIZE];
+  memset(D, id, block_size);
+
+  /* 2. Concatenate copies of the salt together to create a string S of length
+   * v(ceiling(s/v)) bits (the final copy of the salt may be truncated to
+   * create S). Note that if the salt is the empty string, then so is S.
+   *
+   * 3. Concatenate copies of the password together to create a string P of
+   * length v(ceiling(p/v)) bits (the final copy of the password may be
+   * truncated to create P).  Note that if the password is the empty string,
+   * then so is P.
+   *
+   * 4. Set I=S||P to be the concatenation of S and P. */
+  if (salt_len + block_size - 1 < salt_len ||
+      pass_raw_len + block_size - 1 < pass_raw_len) {
+    OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+    return 0;
+  }
+  size_t S_len = block_size * ((salt_len + block_size - 1) / block_size);
+  size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size);
+  size_t I_len = S_len + P_len;
+  if (I_len < S_len) {
+    OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+    return 0;
+  }
+
+  uint8_t *I = OPENSSL_malloc(I_len);
+  if (I_len != 0 && I == NULL) {
+    OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+    return 0;
+  }
+
+  size_t i;
+  for (i = 0; i < S_len; i++) {
+    I[i] = salt[i % salt_len];
+  }
+  for (i = 0; i < P_len; i++) {
+    I[i + S_len] = pass_raw[i % pass_raw_len];
+  }
+
+  int ret = 0;
+  EVP_MD_CTX ctx;
   EVP_MD_CTX_init(&ctx);
-  v = EVP_MD_block_size(md_type);
-  u = EVP_MD_size(md_type);
-  D = OPENSSL_malloc(v);
-  Ai = OPENSSL_malloc(u);
-  B = OPENSSL_malloc(v + 1);
-  Slen = v * ((salt_len + v - 1) / v);
-  if (pass_raw_len) {
-    Plen = v * ((pass_raw_len + v - 1) / v);
-  } else {
-    Plen = 0;
-  }
-  Ilen = Slen + Plen;
-  I = OPENSSL_malloc(Ilen);
-  Ij = BN_new();
-  Bpl1 = BN_new();
-  if (!D || !Ai || !B || !I || !Ij || !Bpl1) {
-    goto err;
-  }
-  for (i = 0; i < v; i++) {
-    D[i] = id;
-  }
-  p = I;
-  for (i = 0; i < Slen; i++) {
-    *p++ = salt[i % salt_len];
-  }
-  for (i = 0; i < Plen; i++) {
-    *p++ = pass_raw[i % pass_raw_len];
-  }
-  for (;;) {
-    if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
-        !EVP_DigestUpdate(&ctx, D, v) ||
-        !EVP_DigestUpdate(&ctx, I, Ilen) ||
-        !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
+
+  while (out_len != 0) {
+    /* A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I,
+     * H(H(H(... H(D||I)))) */
+    uint8_t A[EVP_MAX_MD_SIZE];
+    unsigned A_len;
+    if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
+        !EVP_DigestUpdate(&ctx, D, block_size) ||
+        !EVP_DigestUpdate(&ctx, I, I_len) ||
+        !EVP_DigestFinal_ex(&ctx, A, &A_len)) {
       goto err;
     }
-    for (j = 1; j < iterations; j++) {
-      if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
-          !EVP_DigestUpdate(&ctx, Ai, u) ||
-          !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
+    int iter;
+    for (iter = 1; iter < iterations; iter++) {
+      if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
+          !EVP_DigestUpdate(&ctx, A, A_len) ||
+          !EVP_DigestFinal_ex(&ctx, A, &A_len)) {
         goto err;
       }
     }
-    memcpy(out, Ai, out_len < u ? out_len : u);
-    if (u >= out_len) {
-      ret = 1;
-      goto end;
+
+    size_t todo = out_len < A_len ? out_len : A_len;
+    memcpy(out, A, todo);
+    out += todo;
+    out_len -= todo;
+    if (out_len == 0) {
+      break;
     }
-    out_len -= u;
-    out += u;
-    for (j = 0; j < v; j++) {
-      B[j] = Ai[j % u];
+
+    /* B. Concatenate copies of A_i to create a string B of length v bits (the
+     * final copy of A_i may be truncated to create B). */
+    uint8_t B[EVP_MAX_MD_BLOCK_SIZE];
+    for (i = 0; i < block_size; i++) {
+      B[i] = A[i % A_len];
     }
-    /* Work out B + 1 first then can use B as tmp space */
-    if (!BN_bin2bn(B, v, Bpl1) ||
-        !BN_add_word(Bpl1, 1)) {
-      goto err;
-    }
-    for (j = 0; j < Ilen; j += v) {
-      if (!BN_bin2bn(I + j, v, Ij) ||
-          !BN_add(Ij, Ij, Bpl1) ||
-          !BN_bn2bin(Ij, B)) {
-        goto err;
-      }
-      Ijlen = BN_num_bytes(Ij);
-      /* If more than 2^(v*8) - 1 cut off MSB */
-      if (Ijlen > v) {
-        if (!BN_bn2bin(Ij, B)) {
-          goto err;
-        }
-        memcpy(I + j, B + 1, v);
-        /* If less than v bytes pad with zeroes */
-      } else if (Ijlen < v) {
-        memset(I + j, 0, v - Ijlen);
-        if (!BN_bn2bin(Ij, I + j + v - Ijlen)) {
-          goto err;
-        }
-      } else if (!BN_bn2bin(Ij, I + j)) {
-        goto err;
+
+    /* C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks,
+     * where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod
+     * 2^v for each j. */
+    assert(I_len % block_size == 0);
+    for (i = 0; i < I_len; i += block_size) {
+      unsigned carry = 1;
+      size_t j;
+      for (j = block_size - 1; j < block_size; j--) {
+        carry += I[i + j] + B[j];
+        I[i + j] = (uint8_t)carry;
+        carry >>= 8;
       }
     }
   }
 
+  ret = 1;
+
 err:
-  OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
-
-end:
-  OPENSSL_free(Ai);
-  OPENSSL_free(B);
-  OPENSSL_free(D);
+  OPENSSL_cleanse(I, I_len);
   OPENSSL_free(I);
-  BN_free(Ij);
-  BN_free(Bpl1);
   EVP_MD_CTX_cleanup(&ctx);
-
   return ret;
 }
 
@@ -591,72 +601,52 @@
 }
 
 EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
-  EVP_PKEY *pkey = NULL;
-  ASN1_OBJECT *algoid;
-  char obj_tmp[80];
-
-  if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) {
+  uint8_t *der = NULL;
+  int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der);
+  if (der_len < 0) {
     return NULL;
   }
 
-  pkey = EVP_PKEY_new();
-  if (pkey == NULL) {
-    OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+  CBS cbs;
+  CBS_init(&cbs, der, (size_t)der_len);
+  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
+  if (ret == NULL || CBS_len(&cbs) != 0) {
+    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+    EVP_PKEY_free(ret);
+    OPENSSL_free(der);
     return NULL;
   }
 
-  if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
-    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-    i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
-    ERR_add_error_data(2, "TYPE=", obj_tmp);
-    goto error;
-  }
-
-  if (pkey->ameth->priv_decode) {
-    if (!pkey->ameth->priv_decode(pkey, p8)) {
-      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
-      goto error;
-    }
-  } else {
-    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
-    goto error;
-  }
-
-  return pkey;
-
-error:
-  EVP_PKEY_free(pkey);
-  return NULL;
+  OPENSSL_free(der);
+  return ret;
 }
 
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
-  PKCS8_PRIV_KEY_INFO *p8;
-
-  p8 = PKCS8_PRIV_KEY_INFO_new();
-  if (p8 == NULL) {
-    OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
-    return NULL;
+  CBB cbb;
+  uint8_t *der = NULL;
+  size_t der_len;
+  if (!CBB_init(&cbb, 0) ||
+      !EVP_marshal_private_key(&cbb, pkey) ||
+      !CBB_finish(&cbb, &der, &der_len) ||
+      der_len > LONG_MAX) {
+    CBB_cleanup(&cbb);
+    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR);
+    goto err;
   }
-  p8->broken = PKCS8_OK;
 
-  if (pkey->ameth) {
-    if (pkey->ameth->priv_encode) {
-      if (!pkey->ameth->priv_encode(p8, pkey)) {
-        OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
-        goto error;
-      }
-    } else {
-      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
-      goto error;
-    }
-  } else {
-    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-    goto error;
+  const uint8_t *p = der;
+  PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len);
+  if (p8 == NULL || p != der + der_len) {
+    PKCS8_PRIV_KEY_INFO_free(p8);
+    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+    goto err;
   }
+
+  OPENSSL_free(der);
   return p8;
 
-error:
-  PKCS8_PRIV_KEY_INFO_free(p8);
+err:
+  OPENSSL_free(der);
   return NULL;
 }
 
@@ -737,6 +727,7 @@
                                       struct pkcs12_context *ctx) {
   CBS content_type, wrapped_contents, contents, content_infos;
   int nid, ret = 0;
+  uint8_t *storage = NULL;
 
   if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
       !CBS_get_asn1(content_info, &wrapped_contents,
@@ -767,8 +758,9 @@
         /* AlgorithmIdentifier, see
          * https://tools.ietf.org/html/rfc5280#section-4.1.1.2 */
         !CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) ||
-        !CBS_get_asn1(&eci, &encrypted_contents,
-                      CBS_ASN1_CONTEXT_SPECIFIC | 0)) {
+        !CBS_get_asn1_implicit_string(
+            &eci, &encrypted_contents, &storage,
+            CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) {
       OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
       goto err;
     }
@@ -895,6 +887,7 @@
   }
 
 err:
+  OPENSSL_free(storage);
   return ret;
 }
 
@@ -975,7 +968,7 @@
 
   ctx.out_key = out_key;
   ctx.out_certs = out_certs;
-  if (!ascii_to_ucs2(password, strlen(password), &ctx.password,
+  if (!ascii_to_ucs2(password, password ? strlen(password) : 0, &ctx.password,
                      &ctx.password_len)) {
     OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
     goto err;
@@ -1066,9 +1059,6 @@
 PKCS12* d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, size_t ber_len) {
   PKCS12 *p12;
 
-  /* out_p12 must be NULL because we don't export the PKCS12 structure. */
-  assert(out_p12 == NULL);
-
   p12 = OPENSSL_malloc(sizeof(PKCS12));
   if (!p12) {
     return NULL;
@@ -1084,6 +1074,12 @@
   p12->ber_len = ber_len;
   *ber_bytes += ber_len;
 
+  if (out_p12) {
+    PKCS12_free(*out_p12);
+
+    *out_p12 = p12;
+  }
+
   return p12;
 }
 
@@ -1105,7 +1101,12 @@
   for (;;) {
     int n = BIO_read(bio, &buf->data[used], buf->length - used);
     if (n < 0) {
-      goto out;
+      if (used == 0) {
+        goto out;
+      }
+      /* Workaround a bug in node.js. It uses a memory BIO for this in the wrong
+       * mode. */
+      n = 0;
     }
 
     if (n == 0) {
@@ -1212,6 +1213,9 @@
 }
 
 void PKCS12_free(PKCS12 *p12) {
+  if (p12 == NULL) {
+    return;
+  }
   OPENSSL_free(p12->ber_bytes);
   OPENSSL_free(p12);
 }
diff --git a/src/crypto/poly1305/asm/poly1305-armv4.pl b/src/crypto/poly1305/asm/poly1305-armv4.pl
new file mode 100755
index 0000000..9b765ce
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-armv4.pl
@@ -0,0 +1,1216 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+#			IALU(*)/gcc-4.4		NEON
+#
+# ARM11xx(ARMv6)	7.78/+100%		-
+# Cortex-A5		6.30/+130%		2.96
+# Cortex-A8		6.25/+115%		2.36
+# Cortex-A9		5.10/+95%		2.55
+# Cortex-A15		3.79/+85%		1.25(**)
+# Snapdragon S4		5.70/+100%		1.48(**)
+#
+# (*)	this is for -march=armv6, i.e. with bunch of ldrb loading data;
+# (**)	these are trade-off results, they can be improved by ~8% but at
+#	the cost of 15/12% regression on Cortex-A5/A7, it's even possible
+#	to improve Cortex-A9 result, but then A5/A7 loose more than 20%;
+
+$flavour = shift;
+if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
+else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
+
+if ($flavour && $flavour ne "void") {
+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+    die "can't locate arm-xlate.pl";
+
+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+    open STDOUT,">$output";
+}
+
+($ctx,$inp,$len,$padbit)=map("r$_",(0..3));
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax	unified
+.thumb
+#else
+.code	32
+#endif
+
+.globl	poly1305_emit
+.globl	poly1305_blocks
+.globl	poly1305_init
+.type	poly1305_init,%function
+.align	5
+poly1305_init:
+.Lpoly1305_init:
+	stmdb	sp!,{r4-r11}
+
+	eor	r3,r3,r3
+	cmp	$inp,#0
+	str	r3,[$ctx,#0]		@ zero hash value
+	str	r3,[$ctx,#4]
+	str	r3,[$ctx,#8]
+	str	r3,[$ctx,#12]
+	str	r3,[$ctx,#16]
+	str	r3,[$ctx,#36]		@ is_base2_26
+	add	$ctx,$ctx,#20
+
+#ifdef	__thumb2__
+	it	eq
+#endif
+	moveq	r0,#0
+	beq	.Lno_key
+
+#if	__ARM_MAX_ARCH__>=7
+	adr	r11,.Lpoly1305_init
+	ldr	r12,.LOPENSSL_armcap
+#endif
+	ldrb	r4,[$inp,#0]
+	mov	r10,#0x0fffffff
+	ldrb	r5,[$inp,#1]
+	and	r3,r10,#-4		@ 0x0ffffffc
+	ldrb	r6,[$inp,#2]
+	ldrb	r7,[$inp,#3]
+	orr	r4,r4,r5,lsl#8
+	ldrb	r5,[$inp,#4]
+	orr	r4,r4,r6,lsl#16
+	ldrb	r6,[$inp,#5]
+	orr	r4,r4,r7,lsl#24
+	ldrb	r7,[$inp,#6]
+	and	r4,r4,r10
+
+#if	__ARM_MAX_ARCH__>=7
+	ldr	r12,[r11,r12]		@ OPENSSL_armcap_P
+# ifdef	__APPLE__
+	ldr	r12,[r12]
+# endif
+#endif
+	ldrb	r8,[$inp,#7]
+	orr	r5,r5,r6,lsl#8
+	ldrb	r6,[$inp,#8]
+	orr	r5,r5,r7,lsl#16
+	ldrb	r7,[$inp,#9]
+	orr	r5,r5,r8,lsl#24
+	ldrb	r8,[$inp,#10]
+	and	r5,r5,r3
+
+#if	__ARM_MAX_ARCH__>=7
+	tst	r12,#ARMV7_NEON		@ check for NEON
+# ifdef	__APPLE__
+	adr	r9,poly1305_blocks_neon
+	adr	r11,poly1305_blocks
+#  ifdef __thumb2__
+	it	ne
+#  endif
+	movne	r11,r9
+	adr	r12,poly1305_emit
+	adr	r10,poly1305_emit_neon
+#  ifdef __thumb2__
+	it	ne
+#  endif
+	movne	r12,r10
+# else
+#  ifdef __thumb2__
+	itete	eq
+#  endif
+	addeq	r12,r11,#(poly1305_emit-.Lpoly1305_init)
+	addne	r12,r11,#(poly1305_emit_neon-.Lpoly1305_init)
+	addeq	r11,r11,#(poly1305_blocks-.Lpoly1305_init)
+	addne	r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init)
+# endif
+# ifdef	__thumb2__
+	orr	r12,r12,#1	@ thumb-ify address
+	orr	r11,r11,#1
+# endif
+#endif
+	ldrb	r9,[$inp,#11]
+	orr	r6,r6,r7,lsl#8
+	ldrb	r7,[$inp,#12]
+	orr	r6,r6,r8,lsl#16
+	ldrb	r8,[$inp,#13]
+	orr	r6,r6,r9,lsl#24
+	ldrb	r9,[$inp,#14]
+	and	r6,r6,r3
+
+	ldrb	r10,[$inp,#15]
+	orr	r7,r7,r8,lsl#8
+	str	r4,[$ctx,#0]
+	orr	r7,r7,r9,lsl#16
+	str	r5,[$ctx,#4]
+	orr	r7,r7,r10,lsl#24
+	str	r6,[$ctx,#8]
+	and	r7,r7,r3
+	str	r7,[$ctx,#12]
+#if	__ARM_MAX_ARCH__>=7
+	stmia	r2,{r11,r12}		@ fill functions table
+	mov	r0,#1
+#else
+	mov	r0,#0
+#endif
+.Lno_key:
+	ldmia	sp!,{r4-r11}
+#if	__ARM_ARCH__>=5
+	ret				@ bx	lr
+#else
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+#endif
+.size	poly1305_init,.-poly1305_init
+___
+{
+my ($h0,$h1,$h2,$h3,$h4,$r0,$r1,$r2,$r3)=map("r$_",(4..12));
+my ($s1,$s2,$s3)=($r1,$r2,$r3);
+
+$code.=<<___;
+.type	poly1305_blocks,%function
+.align	5
+poly1305_blocks:
+	stmdb	sp!,{r3-r11,lr}
+
+	ands	$len,$len,#-16
+	beq	.Lno_data
+
+	cmp	$padbit,#0
+	add	$len,$len,$inp		@ end pointer
+	sub	sp,sp,#32
+
+	ldmia	$ctx,{$h0-$r3}		@ load context
+
+	str	$ctx,[sp,#12]		@ offload stuff
+	mov	lr,$inp
+	str	$len,[sp,#16]
+	str	$r1,[sp,#20]
+	str	$r2,[sp,#24]
+	str	$r3,[sp,#28]
+	b	.Loop
+
+.Loop:
+#if __ARM_ARCH__<7
+	ldrb	r0,[lr],#16		@ load input
+# ifdef	__thumb2__
+	it	hi
+# endif
+	addhi	$h4,$h4,#1		@ 1<<128
+	ldrb	r1,[lr,#-15]
+	ldrb	r2,[lr,#-14]
+	ldrb	r3,[lr,#-13]
+	orr	r1,r0,r1,lsl#8
+	ldrb	r0,[lr,#-12]
+	orr	r2,r1,r2,lsl#16
+	ldrb	r1,[lr,#-11]
+	orr	r3,r2,r3,lsl#24
+	ldrb	r2,[lr,#-10]
+	adds	$h0,$h0,r3		@ accumulate input
+
+	ldrb	r3,[lr,#-9]
+	orr	r1,r0,r1,lsl#8
+	ldrb	r0,[lr,#-8]
+	orr	r2,r1,r2,lsl#16
+	ldrb	r1,[lr,#-7]
+	orr	r3,r2,r3,lsl#24
+	ldrb	r2,[lr,#-6]
+	adcs	$h1,$h1,r3
+
+	ldrb	r3,[lr,#-5]
+	orr	r1,r0,r1,lsl#8
+	ldrb	r0,[lr,#-4]
+	orr	r2,r1,r2,lsl#16
+	ldrb	r1,[lr,#-3]
+	orr	r3,r2,r3,lsl#24
+	ldrb	r2,[lr,#-2]
+	adcs	$h2,$h2,r3
+
+	ldrb	r3,[lr,#-1]
+	orr	r1,r0,r1,lsl#8
+	str	lr,[sp,#8]		@ offload input pointer
+	orr	r2,r1,r2,lsl#16
+	add	$s1,$r1,$r1,lsr#2
+	orr	r3,r2,r3,lsl#24
+#else
+	ldr	r0,[lr],#16		@ load input
+# ifdef	__thumb2__
+	it	hi
+# endif
+	addhi	$h4,$h4,#1		@ padbit
+	ldr	r1,[lr,#-12]
+	ldr	r2,[lr,#-8]
+	ldr	r3,[lr,#-4]
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+	adds	$h0,$h0,r0		@ accumulate input
+	str	lr,[sp,#8]		@ offload input pointer
+	adcs	$h1,$h1,r1
+	add	$s1,$r1,$r1,lsr#2
+	adcs	$h2,$h2,r2
+#endif
+	add	$s2,$r2,$r2,lsr#2
+	adcs	$h3,$h3,r3
+	add	$s3,$r3,$r3,lsr#2
+
+	umull	r2,r3,$h1,$r0
+	 adc	$h4,$h4,#0
+	umull	r0,r1,$h0,$r0
+	umlal	r2,r3,$h4,$s1
+	umlal	r0,r1,$h3,$s1
+	ldr	$r1,[sp,#20]		@ reload $r1
+	umlal	r2,r3,$h2,$s3
+	umlal	r0,r1,$h1,$s3
+	umlal	r2,r3,$h3,$s2
+	umlal	r0,r1,$h2,$s2
+	umlal	r2,r3,$h0,$r1
+	str	r0,[sp,#0]		@ future $h0
+	 mul	r0,$s2,$h4
+	ldr	$r2,[sp,#24]		@ reload $r2
+	adds	r2,r2,r1		@ d1+=d0>>32
+	 eor	r1,r1,r1
+	adc	lr,r3,#0		@ future $h2
+	str	r2,[sp,#4]		@ future $h1
+
+	mul	r2,$s3,$h4
+	eor	r3,r3,r3
+	umlal	r0,r1,$h3,$s3
+	ldr	$r3,[sp,#28]		@ reload $r3
+	umlal	r2,r3,$h3,$r0
+	umlal	r0,r1,$h2,$r0
+	umlal	r2,r3,$h2,$r1
+	umlal	r0,r1,$h1,$r1
+	umlal	r2,r3,$h1,$r2
+	umlal	r0,r1,$h0,$r2
+	umlal	r2,r3,$h0,$r3
+	ldr	$h0,[sp,#0]
+	mul	$h4,$r0,$h4
+	ldr	$h1,[sp,#4]
+
+	adds	$h2,lr,r0		@ d2+=d1>>32
+	ldr	lr,[sp,#8]		@ reload input pointer
+	adc	r1,r1,#0
+	adds	$h3,r2,r1		@ d3+=d2>>32
+	ldr	r0,[sp,#16]		@ reload end pointer
+	adc	r3,r3,#0
+	add	$h4,$h4,r3		@ h4+=d3>>32
+
+	and	r1,$h4,#-4
+	and	$h4,$h4,#3
+	add	r1,r1,r1,lsr#2		@ *=5
+	adds	$h0,$h0,r1
+	adcs	$h1,$h1,#0
+	adcs	$h2,$h2,#0
+	adc	$h3,$h3,#0
+
+	cmp	r0,lr			@ done yet?
+	bhi	.Loop
+
+	ldr	$ctx,[sp,#12]
+	add	sp,sp,#32
+	stmia	$ctx,{$h0-$h4}		@ store the result
+
+.Lno_data:
+#if	__ARM_ARCH__>=5
+	ldmia	sp!,{r3-r11,pc}
+#else
+	ldmia	sp!,{r3-r11,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+#endif
+.size	poly1305_blocks,.-poly1305_blocks
+___
+}
+{
+my ($ctx,$mac,$nonce)=map("r$_",(0..2));
+my ($h0,$h1,$h2,$h3,$h4,$g0,$g1,$g2,$g3)=map("r$_",(3..11));
+my $g4=$h4;
+
+$code.=<<___;
+.type	poly1305_emit,%function
+.align	5
+poly1305_emit:
+	stmdb	sp!,{r4-r11}
+.Lpoly1305_emit_enter:
+
+	ldmia	$ctx,{$h0-$h4}
+	adds	$g0,$h0,#5		@ compare to modulus
+	adcs	$g1,$h1,#0
+	adcs	$g2,$h2,#0
+	adcs	$g3,$h3,#0
+	adc	$g4,$h4,#0
+	tst	$g4,#4			@ did it carry/borrow?
+
+#ifdef	__thumb2__
+	it	ne
+#endif
+	movne	$h0,$g0
+	ldr	$g0,[$nonce,#0]
+#ifdef	__thumb2__
+	it	ne
+#endif
+	movne	$h1,$g1
+	ldr	$g1,[$nonce,#4]
+#ifdef	__thumb2__
+	it	ne
+#endif
+	movne	$h2,$g2
+	ldr	$g2,[$nonce,#8]
+#ifdef	__thumb2__
+	it	ne
+#endif
+	movne	$h3,$g3
+	ldr	$g3,[$nonce,#12]
+
+	adds	$h0,$h0,$g0
+	adcs	$h1,$h1,$g1
+	adcs	$h2,$h2,$g2
+	adc	$h3,$h3,$g3
+
+#if __ARM_ARCH__>=7
+# ifdef __ARMEB__
+	rev	$h0,$h0
+	rev	$h1,$h1
+	rev	$h2,$h2
+	rev	$h3,$h3
+# endif
+	str	$h0,[$mac,#0]
+	str	$h1,[$mac,#4]
+	str	$h2,[$mac,#8]
+	str	$h3,[$mac,#12]
+#else
+	strb	$h0,[$mac,#0]
+	mov	$h0,$h0,lsr#8
+	strb	$h1,[$mac,#4]
+	mov	$h1,$h1,lsr#8
+	strb	$h2,[$mac,#8]
+	mov	$h2,$h2,lsr#8
+	strb	$h3,[$mac,#12]
+	mov	$h3,$h3,lsr#8
+
+	strb	$h0,[$mac,#1]
+	mov	$h0,$h0,lsr#8
+	strb	$h1,[$mac,#5]
+	mov	$h1,$h1,lsr#8
+	strb	$h2,[$mac,#9]
+	mov	$h2,$h2,lsr#8
+	strb	$h3,[$mac,#13]
+	mov	$h3,$h3,lsr#8
+
+	strb	$h0,[$mac,#2]
+	mov	$h0,$h0,lsr#8
+	strb	$h1,[$mac,#6]
+	mov	$h1,$h1,lsr#8
+	strb	$h2,[$mac,#10]
+	mov	$h2,$h2,lsr#8
+	strb	$h3,[$mac,#14]
+	mov	$h3,$h3,lsr#8
+
+	strb	$h0,[$mac,#3]
+	strb	$h1,[$mac,#7]
+	strb	$h2,[$mac,#11]
+	strb	$h3,[$mac,#15]
+#endif
+	ldmia	sp!,{r4-r11}
+#if	__ARM_ARCH__>=5
+	ret				@ bx	lr
+#else
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+#endif
+.size	poly1305_emit,.-poly1305_emit
+___
+{
+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("d$_",(0..9));
+my ($D0,$D1,$D2,$D3,$D4, $H0,$H1,$H2,$H3,$H4) = map("q$_",(5..14));
+my ($T0,$T1,$MASK) = map("q$_",(15,4,0));
+
+my ($in2,$zeros,$tbl0,$tbl1) = map("r$_",(4..7));
+
+$code.=<<___;
+#if	__ARM_MAX_ARCH__>=7
+.fpu	neon
+
+.type	poly1305_init_neon,%function
+.align	5
+poly1305_init_neon:
+	ldr	r4,[$ctx,#20]		@ load key base 2^32
+	ldr	r5,[$ctx,#24]
+	ldr	r6,[$ctx,#28]
+	ldr	r7,[$ctx,#32]
+
+	and	r2,r4,#0x03ffffff	@ base 2^32 -> base 2^26
+	mov	r3,r4,lsr#26
+	mov	r4,r5,lsr#20
+	orr	r3,r3,r5,lsl#6
+	mov	r5,r6,lsr#14
+	orr	r4,r4,r6,lsl#12
+	mov	r6,r7,lsr#8
+	orr	r5,r5,r7,lsl#18
+	and	r3,r3,#0x03ffffff
+	and	r4,r4,#0x03ffffff
+	and	r5,r5,#0x03ffffff
+
+	vdup.32	$R0,r2			@ r^1 in both lanes
+	add	r2,r3,r3,lsl#2		@ *5
+	vdup.32	$R1,r3
+	add	r3,r4,r4,lsl#2
+	vdup.32	$S1,r2
+	vdup.32	$R2,r4
+	add	r4,r5,r5,lsl#2
+	vdup.32	$S2,r3
+	vdup.32	$R3,r5
+	add	r5,r6,r6,lsl#2
+	vdup.32	$S3,r4
+	vdup.32	$R4,r6
+	vdup.32	$S4,r5
+
+	mov	$zeros,#2		@ counter
+
+.Lsquare_neon:
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+	@ d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	@ d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	@ d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	@ d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+
+	vmull.u32	$D0,$R0,${R0}[1]
+	vmull.u32	$D1,$R1,${R0}[1]
+	vmull.u32	$D2,$R2,${R0}[1]
+	vmull.u32	$D3,$R3,${R0}[1]
+	vmull.u32	$D4,$R4,${R0}[1]
+
+	vmlal.u32	$D0,$R4,${S1}[1]
+	vmlal.u32	$D1,$R0,${R1}[1]
+	vmlal.u32	$D2,$R1,${R1}[1]
+	vmlal.u32	$D3,$R2,${R1}[1]
+	vmlal.u32	$D4,$R3,${R1}[1]
+
+	vmlal.u32	$D0,$R3,${S2}[1]
+	vmlal.u32	$D1,$R4,${S2}[1]
+	vmlal.u32	$D3,$R1,${R2}[1]
+	vmlal.u32	$D2,$R0,${R2}[1]
+	vmlal.u32	$D4,$R2,${R2}[1]
+
+	vmlal.u32	$D0,$R2,${S3}[1]
+	vmlal.u32	$D3,$R0,${R3}[1]
+	vmlal.u32	$D1,$R3,${S3}[1]
+	vmlal.u32	$D2,$R4,${S3}[1]
+	vmlal.u32	$D4,$R1,${R3}[1]
+
+	vmlal.u32	$D3,$R4,${S4}[1]
+	vmlal.u32	$D0,$R1,${S4}[1]
+	vmlal.u32	$D1,$R2,${S4}[1]
+	vmlal.u32	$D2,$R3,${S4}[1]
+	vmlal.u32	$D4,$R0,${R4}[1]
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+	@ and P. Schwabe
+
+	vshr.u64	$T0,$D3,#26
+	vmovn.i64	$D3#lo,$D3
+	 vshr.u64	$T1,$D0,#26
+	 vmovn.i64	$D0#lo,$D0
+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
+	vbic.i32	$D3#lo,#0xfc000000	@ &=0x03ffffff
+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
+	 vbic.i32	$D0#lo,#0xfc000000
+
+	vshrn.u64	$T0#lo,$D4,#26
+	vmovn.i64	$D4#lo,$D4
+	 vshr.u64	$T1,$D1,#26
+	 vmovn.i64	$D1#lo,$D1
+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
+	vbic.i32	$D4#lo,#0xfc000000
+	 vbic.i32	$D1#lo,#0xfc000000
+
+	vadd.i32	$D0#lo,$D0#lo,$T0#lo
+	vshl.u32	$T0#lo,$T0#lo,#2
+	 vshrn.u64	$T1#lo,$D2,#26
+	 vmovn.i64	$D2#lo,$D2
+	vadd.i32	$D0#lo,$D0#lo,$T0#lo	@ h4 -> h0
+	 vadd.i32	$D3#lo,$D3#lo,$T1#lo	@ h2 -> h3
+	 vbic.i32	$D2#lo,#0xfc000000
+
+	vshr.u32	$T0#lo,$D0#lo,#26
+	vbic.i32	$D0#lo,#0xfc000000
+	 vshr.u32	$T1#lo,$D3#lo,#26
+	 vbic.i32	$D3#lo,#0xfc000000
+	vadd.i32	$D1#lo,$D1#lo,$T0#lo	@ h0 -> h1
+	 vadd.i32	$D4#lo,$D4#lo,$T1#lo	@ h3 -> h4
+
+	subs		$zeros,$zeros,#1
+	beq		.Lsquare_break_neon
+
+	add		$tbl0,$ctx,#(48+0*9*4)
+	add		$tbl1,$ctx,#(48+1*9*4)
+
+	vtrn.32		$R0,$D0#lo		@ r^2:r^1
+	vtrn.32		$R2,$D2#lo
+	vtrn.32		$R3,$D3#lo
+	vtrn.32		$R1,$D1#lo
+	vtrn.32		$R4,$D4#lo
+
+	vshl.u32	$S2,$R2,#2		@ *5
+	vshl.u32	$S3,$R3,#2
+	vshl.u32	$S1,$R1,#2
+	vshl.u32	$S4,$R4,#2
+	vadd.i32	$S2,$S2,$R2
+	vadd.i32	$S1,$S1,$R1
+	vadd.i32	$S3,$S3,$R3
+	vadd.i32	$S4,$S4,$R4
+
+	vst4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
+	vst4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
+	vst4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+	vst4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+	vst1.32		{${S4}[0]},[$tbl0,:32]
+	vst1.32		{${S4}[1]},[$tbl1,:32]
+
+	b		.Lsquare_neon
+
+.align	4
+.Lsquare_break_neon:
+	add		$tbl0,$ctx,#(48+2*4*9)
+	add		$tbl1,$ctx,#(48+3*4*9)
+
+	vmov		$R0,$D0#lo		@ r^4:r^3
+	vshl.u32	$S1,$D1#lo,#2		@ *5
+	vmov		$R1,$D1#lo
+	vshl.u32	$S2,$D2#lo,#2
+	vmov		$R2,$D2#lo
+	vshl.u32	$S3,$D3#lo,#2
+	vmov		$R3,$D3#lo
+	vshl.u32	$S4,$D4#lo,#2
+	vmov		$R4,$D4#lo
+	vadd.i32	$S1,$S1,$D1#lo
+	vadd.i32	$S2,$S2,$D2#lo
+	vadd.i32	$S3,$S3,$D3#lo
+	vadd.i32	$S4,$S4,$D4#lo
+
+	vst4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
+	vst4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
+	vst4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+	vst4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+	vst1.32		{${S4}[0]},[$tbl0]
+	vst1.32		{${S4}[1]},[$tbl1]
+
+	ret				@ bx	lr
+.size	poly1305_init_neon,.-poly1305_init_neon
+
+.type	poly1305_blocks_neon,%function
+.align	5
+poly1305_blocks_neon:
+	ldr	ip,[$ctx,#36]		@ is_base2_26
+	ands	$len,$len,#-16
+	beq	.Lno_data_neon
+
+	cmp	$len,#64
+	bhs	.Lenter_neon
+	tst	ip,ip			@ is_base2_26?
+	beq	poly1305_blocks
+
+.Lenter_neon:
+	stmdb	sp!,{r4-r7}
+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
+
+	tst	ip,ip			@ is_base2_26?
+	bne	.Lbase2_26_neon
+
+	stmdb	sp!,{r1-r3,lr}
+	bl	poly1305_init_neon
+
+	ldr	r4,[$ctx,#0]		@ load hash value base 2^32
+	ldr	r5,[$ctx,#4]
+	ldr	r6,[$ctx,#8]
+	ldr	r7,[$ctx,#12]
+	ldr	ip,[$ctx,#16]
+
+	and	r2,r4,#0x03ffffff	@ base 2^32 -> base 2^26
+	mov	r3,r4,lsr#26
+	 veor	$D0#lo,$D0#lo,$D0#lo
+	mov	r4,r5,lsr#20
+	orr	r3,r3,r5,lsl#6
+	 veor	$D1#lo,$D1#lo,$D1#lo
+	mov	r5,r6,lsr#14
+	orr	r4,r4,r6,lsl#12
+	 veor	$D2#lo,$D2#lo,$D2#lo
+	mov	r6,r7,lsr#8
+	orr	r5,r5,r7,lsl#18
+	 veor	$D3#lo,$D3#lo,$D3#lo
+	and	r3,r3,#0x03ffffff
+	orr	r6,r6,ip,lsl#24
+	 veor	$D4#lo,$D4#lo,$D4#lo
+	and	r4,r4,#0x03ffffff
+	mov	r1,#1
+	and	r5,r5,#0x03ffffff
+	str	r1,[$ctx,#36]		@ is_base2_26
+
+	vmov.32	$D0#lo[0],r2
+	vmov.32	$D1#lo[0],r3
+	vmov.32	$D2#lo[0],r4
+	vmov.32	$D3#lo[0],r5
+	vmov.32	$D4#lo[0],r6
+	adr	$zeros,.Lzeros
+
+	ldmia	sp!,{r1-r3,lr}
+	b	.Lbase2_32_neon
+
+.align	4
+.Lbase2_26_neon:
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ load hash value
+
+	veor		$D0#lo,$D0#lo,$D0#lo
+	veor		$D1#lo,$D1#lo,$D1#lo
+	veor		$D2#lo,$D2#lo,$D2#lo
+	veor		$D3#lo,$D3#lo,$D3#lo
+	veor		$D4#lo,$D4#lo,$D4#lo
+	vld4.32		{$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
+	adr		$zeros,.Lzeros
+	vld1.32		{$D4#lo[0]},[$ctx]
+	sub		$ctx,$ctx,#16		@ rewind
+
+.Lbase2_32_neon:
+	add		$in2,$inp,#32
+	mov		$padbit,$padbit,lsl#24
+	tst		$len,#31
+	beq		.Leven
+
+	vld4.32		{$H0#lo[0],$H1#lo[0],$H2#lo[0],$H3#lo[0]},[$inp]!
+	vmov.32		$H4#lo[0],$padbit
+	sub		$len,$len,#16
+	add		$in2,$inp,#32
+
+# ifdef	__ARMEB__
+	vrev32.8	$H0,$H0
+	vrev32.8	$H3,$H3
+	vrev32.8	$H1,$H1
+	vrev32.8	$H2,$H2
+# endif
+	vsri.u32	$H4#lo,$H3#lo,#8	@ base 2^32 -> base 2^26
+	vshl.u32	$H3#lo,$H3#lo,#18
+
+	vsri.u32	$H3#lo,$H2#lo,#14
+	vshl.u32	$H2#lo,$H2#lo,#12
+	vadd.i32	$H4#hi,$H4#lo,$D4#lo	@ add hash value and move to #hi
+
+	vbic.i32	$H3#lo,#0xfc000000
+	vsri.u32	$H2#lo,$H1#lo,#20
+	vshl.u32	$H1#lo,$H1#lo,#6
+
+	vbic.i32	$H2#lo,#0xfc000000
+	vsri.u32	$H1#lo,$H0#lo,#26
+	vadd.i32	$H3#hi,$H3#lo,$D3#lo
+
+	vbic.i32	$H0#lo,#0xfc000000
+	vbic.i32	$H1#lo,#0xfc000000
+	vadd.i32	$H2#hi,$H2#lo,$D2#lo
+
+	vadd.i32	$H0#hi,$H0#lo,$D0#lo
+	vadd.i32	$H1#hi,$H1#lo,$D1#lo
+
+	mov		$tbl1,$zeros
+	add		$tbl0,$ctx,#48
+
+	cmp		$len,$len
+	b		.Long_tail
+
+.align	4
+.Leven:
+	subs		$len,$len,#64
+# ifdef	__thumb2__
+	it		lo
+# endif
+	movlo		$in2,$zeros
+
+	vmov.i32	$H4,#1<<24		@ padbit, yes, always
+	vld4.32		{$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp]	@ inp[0:1]
+	add		$inp,$inp,#64
+	vld4.32		{$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2]	@ inp[2:3] (or 0)
+	add		$in2,$in2,#64
+# ifdef	__thumb2__
+	itt		hi
+# endif
+	addhi		$tbl1,$ctx,#(48+1*9*4)
+	addhi		$tbl0,$ctx,#(48+3*9*4)
+
+# ifdef	__ARMEB__
+	vrev32.8	$H0,$H0
+	vrev32.8	$H3,$H3
+	vrev32.8	$H1,$H1
+	vrev32.8	$H2,$H2
+# endif
+	vsri.u32	$H4,$H3,#8		@ base 2^32 -> base 2^26
+	vshl.u32	$H3,$H3,#18
+
+	vsri.u32	$H3,$H2,#14
+	vshl.u32	$H2,$H2,#12
+
+	vbic.i32	$H3,#0xfc000000
+	vsri.u32	$H2,$H1,#20
+	vshl.u32	$H1,$H1,#6
+
+	vbic.i32	$H2,#0xfc000000
+	vsri.u32	$H1,$H0,#26
+
+	vbic.i32	$H0,#0xfc000000
+	vbic.i32	$H1,#0xfc000000
+
+	bls		.Lskip_loop
+
+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^2
+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^4
+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+	b		.Loop_neon
+
+.align	5
+.Loop_neon:
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+	@ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+	@   \___________________/
+	@ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+	@ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+	@   \___________________/ \____________________/
+	@
+	@ Note that we start with inp[2:3]*r^2. This is because it
+	@ doesn't depend on reduction in previous iteration.
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	@ d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	@ d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	@ d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	@ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ inp[2:3]*r^2
+
+	vadd.i32	$H2#lo,$H2#lo,$D2#lo	@ accumulate inp[0:1]
+	vmull.u32	$D2,$H2#hi,${R0}[1]
+	vadd.i32	$H0#lo,$H0#lo,$D0#lo
+	vmull.u32	$D0,$H0#hi,${R0}[1]
+	vadd.i32	$H3#lo,$H3#lo,$D3#lo
+	vmull.u32	$D3,$H3#hi,${R0}[1]
+	vmlal.u32	$D2,$H1#hi,${R1}[1]
+	vadd.i32	$H1#lo,$H1#lo,$D1#lo
+	vmull.u32	$D1,$H1#hi,${R0}[1]
+
+	vadd.i32	$H4#lo,$H4#lo,$D4#lo
+	vmull.u32	$D4,$H4#hi,${R0}[1]
+	subs		$len,$len,#64
+	vmlal.u32	$D0,$H4#hi,${S1}[1]
+# ifdef	__thumb2__
+	it		lo
+# endif
+	movlo		$in2,$zeros
+	vmlal.u32	$D3,$H2#hi,${R1}[1]
+	vld1.32		${S4}[1],[$tbl1,:32]
+	vmlal.u32	$D1,$H0#hi,${R1}[1]
+	vmlal.u32	$D4,$H3#hi,${R1}[1]
+
+	vmlal.u32	$D0,$H3#hi,${S2}[1]
+	vmlal.u32	$D3,$H1#hi,${R2}[1]
+	vmlal.u32	$D4,$H2#hi,${R2}[1]
+	vmlal.u32	$D1,$H4#hi,${S2}[1]
+	vmlal.u32	$D2,$H0#hi,${R2}[1]
+
+	vmlal.u32	$D3,$H0#hi,${R3}[1]
+	vmlal.u32	$D0,$H2#hi,${S3}[1]
+	vmlal.u32	$D4,$H1#hi,${R3}[1]
+	vmlal.u32	$D1,$H3#hi,${S3}[1]
+	vmlal.u32	$D2,$H4#hi,${S3}[1]
+
+	vmlal.u32	$D3,$H4#hi,${S4}[1]
+	vmlal.u32	$D0,$H1#hi,${S4}[1]
+	vmlal.u32	$D4,$H0#hi,${R4}[1]
+	vmlal.u32	$D1,$H2#hi,${S4}[1]
+	vmlal.u32	$D2,$H3#hi,${S4}[1]
+
+	vld4.32		{$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2]	@ inp[2:3] (or 0)
+	add		$in2,$in2,#64
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ (hash+inp[0:1])*r^4 and accumulate
+
+	vmlal.u32	$D3,$H3#lo,${R0}[0]
+	vmlal.u32	$D0,$H0#lo,${R0}[0]
+	vmlal.u32	$D4,$H4#lo,${R0}[0]
+	vmlal.u32	$D1,$H1#lo,${R0}[0]
+	vmlal.u32	$D2,$H2#lo,${R0}[0]
+	vld1.32		${S4}[0],[$tbl0,:32]
+
+	vmlal.u32	$D3,$H2#lo,${R1}[0]
+	vmlal.u32	$D0,$H4#lo,${S1}[0]
+	vmlal.u32	$D4,$H3#lo,${R1}[0]
+	vmlal.u32	$D1,$H0#lo,${R1}[0]
+	vmlal.u32	$D2,$H1#lo,${R1}[0]
+
+	vmlal.u32	$D3,$H1#lo,${R2}[0]
+	vmlal.u32	$D0,$H3#lo,${S2}[0]
+	vmlal.u32	$D4,$H2#lo,${R2}[0]
+	vmlal.u32	$D1,$H4#lo,${S2}[0]
+	vmlal.u32	$D2,$H0#lo,${R2}[0]
+
+	vmlal.u32	$D3,$H0#lo,${R3}[0]
+	vmlal.u32	$D0,$H2#lo,${S3}[0]
+	vmlal.u32	$D4,$H1#lo,${R3}[0]
+	vmlal.u32	$D1,$H3#lo,${S3}[0]
+	vmlal.u32	$D3,$H4#lo,${S4}[0]
+
+	vmlal.u32	$D2,$H4#lo,${S3}[0]
+	vmlal.u32	$D0,$H1#lo,${S4}[0]
+	vmlal.u32	$D4,$H0#lo,${R4}[0]
+	vmov.i32	$H4,#1<<24		@ padbit, yes, always
+	vmlal.u32	$D1,$H2#lo,${S4}[0]
+	vmlal.u32	$D2,$H3#lo,${S4}[0]
+
+	vld4.32		{$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp]	@ inp[0:1]
+	add		$inp,$inp,#64
+# ifdef	__ARMEB__
+	vrev32.8	$H0,$H0
+	vrev32.8	$H1,$H1
+	vrev32.8	$H2,$H2
+	vrev32.8	$H3,$H3
+# endif
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ lazy reduction interleaved with base 2^32 -> base 2^26
+
+	vshr.u64	$T0,$D3,#26
+	vmovn.i64	$D3#lo,$D3
+	 vshr.u64	$T1,$D0,#26
+	 vmovn.i64	$D0#lo,$D0
+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
+	vbic.i32	$D3#lo,#0xfc000000
+	  vsri.u32	$H4,$H3,#8		@ base 2^32 -> base 2^26
+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
+	  vshl.u32	$H3,$H3,#18
+	 vbic.i32	$D0#lo,#0xfc000000
+
+	vshrn.u64	$T0#lo,$D4,#26
+	vmovn.i64	$D4#lo,$D4
+	 vshr.u64	$T1,$D1,#26
+	 vmovn.i64	$D1#lo,$D1
+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
+	  vsri.u32	$H3,$H2,#14
+	vbic.i32	$D4#lo,#0xfc000000
+	  vshl.u32	$H2,$H2,#12
+	 vbic.i32	$D1#lo,#0xfc000000
+
+	vadd.i32	$D0#lo,$D0#lo,$T0#lo
+	vshl.u32	$T0#lo,$T0#lo,#2
+	  vbic.i32	$H3,#0xfc000000
+	 vshrn.u64	$T1#lo,$D2,#26
+	 vmovn.i64	$D2#lo,$D2
+	vadd.i32	$D0#lo,$D0#lo,$T0#lo	@ h4 -> h0
+	  vsri.u32	$H2,$H1,#20
+	 vadd.i32	$D3#lo,$D3#lo,$T1#lo	@ h2 -> h3
+	  vshl.u32	$H1,$H1,#6
+	 vbic.i32	$D2#lo,#0xfc000000
+	  vbic.i32	$H2,#0xfc000000
+
+	vshr.u32	$T0#lo,$D0#lo,#26
+	vbic.i32	$D0#lo,#0xfc000000
+	  vsri.u32	$H1,$H0,#26
+	  vbic.i32	$H0,#0xfc000000
+	 vshr.u32	$T1#lo,$D3#lo,#26
+	 vbic.i32	$D3#lo,#0xfc000000
+	vadd.i32	$D1#lo,$D1#lo,$T0#lo	@ h0 -> h1
+	 vadd.i32	$D4#lo,$D4#lo,$T1#lo	@ h3 -> h4
+	  vbic.i32	$H1,#0xfc000000
+
+	bhi		.Loop_neon
+
+.Lskip_loop:
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+	add		$tbl1,$ctx,#(48+0*9*4)
+	add		$tbl0,$ctx,#(48+1*9*4)
+	adds		$len,$len,#32
+# ifdef	__thumb2__
+	it		ne
+# endif
+	movne		$len,#0
+	bne		.Long_tail
+
+	vadd.i32	$H2#hi,$H2#lo,$D2#lo	@ add hash value and move to #hi
+	vadd.i32	$H0#hi,$H0#lo,$D0#lo
+	vadd.i32	$H3#hi,$H3#lo,$D3#lo
+	vadd.i32	$H1#hi,$H1#lo,$D1#lo
+	vadd.i32	$H4#hi,$H4#lo,$D4#lo
+
+.Long_tail:
+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^1
+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^2
+
+	vadd.i32	$H2#lo,$H2#lo,$D2#lo	@ can be redundant
+	vmull.u32	$D2,$H2#hi,$R0
+	vadd.i32	$H0#lo,$H0#lo,$D0#lo
+	vmull.u32	$D0,$H0#hi,$R0
+	vadd.i32	$H3#lo,$H3#lo,$D3#lo
+	vmull.u32	$D3,$H3#hi,$R0
+	vadd.i32	$H1#lo,$H1#lo,$D1#lo
+	vmull.u32	$D1,$H1#hi,$R0
+	vadd.i32	$H4#lo,$H4#lo,$D4#lo
+	vmull.u32	$D4,$H4#hi,$R0
+
+	vmlal.u32	$D0,$H4#hi,$S1
+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+	vmlal.u32	$D3,$H2#hi,$R1
+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+	vmlal.u32	$D1,$H0#hi,$R1
+	vmlal.u32	$D4,$H3#hi,$R1
+	vmlal.u32	$D2,$H1#hi,$R1
+
+	vmlal.u32	$D3,$H1#hi,$R2
+	vld1.32		${S4}[1],[$tbl1,:32]
+	vmlal.u32	$D0,$H3#hi,$S2
+	vld1.32		${S4}[0],[$tbl0,:32]
+	vmlal.u32	$D4,$H2#hi,$R2
+	vmlal.u32	$D1,$H4#hi,$S2
+	vmlal.u32	$D2,$H0#hi,$R2
+
+	vmlal.u32	$D3,$H0#hi,$R3
+# ifdef	__thumb2__
+	it		ne
+# endif
+	 addne		$tbl1,$ctx,#(48+2*9*4)
+	vmlal.u32	$D0,$H2#hi,$S3
+# ifdef	__thumb2__
+	it		ne
+# endif
+	 addne		$tbl0,$ctx,#(48+3*9*4)
+	vmlal.u32	$D4,$H1#hi,$R3
+	vmlal.u32	$D1,$H3#hi,$S3
+	vmlal.u32	$D2,$H4#hi,$S3
+
+	vmlal.u32	$D3,$H4#hi,$S4
+	 vorn		$MASK,$MASK,$MASK	@ all-ones, can be redundant
+	vmlal.u32	$D0,$H1#hi,$S4
+	 vshr.u64	$MASK,$MASK,#38
+	vmlal.u32	$D4,$H0#hi,$R4
+	vmlal.u32	$D1,$H2#hi,$S4
+	vmlal.u32	$D2,$H3#hi,$S4
+
+	beq		.Lshort_tail
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ (hash+inp[0:1])*r^4:r^3 and accumulate
+
+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^3
+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^4
+
+	vmlal.u32	$D2,$H2#lo,$R0
+	vmlal.u32	$D0,$H0#lo,$R0
+	vmlal.u32	$D3,$H3#lo,$R0
+	vmlal.u32	$D1,$H1#lo,$R0
+	vmlal.u32	$D4,$H4#lo,$R0
+
+	vmlal.u32	$D0,$H4#lo,$S1
+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+	vmlal.u32	$D3,$H2#lo,$R1
+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+	vmlal.u32	$D1,$H0#lo,$R1
+	vmlal.u32	$D4,$H3#lo,$R1
+	vmlal.u32	$D2,$H1#lo,$R1
+
+	vmlal.u32	$D3,$H1#lo,$R2
+	vld1.32		${S4}[1],[$tbl1,:32]
+	vmlal.u32	$D0,$H3#lo,$S2
+	vld1.32		${S4}[0],[$tbl0,:32]
+	vmlal.u32	$D4,$H2#lo,$R2
+	vmlal.u32	$D1,$H4#lo,$S2
+	vmlal.u32	$D2,$H0#lo,$R2
+
+	vmlal.u32	$D3,$H0#lo,$R3
+	vmlal.u32	$D0,$H2#lo,$S3
+	vmlal.u32	$D4,$H1#lo,$R3
+	vmlal.u32	$D1,$H3#lo,$S3
+	vmlal.u32	$D2,$H4#lo,$S3
+
+	vmlal.u32	$D3,$H4#lo,$S4
+	 vorn		$MASK,$MASK,$MASK	@ all-ones
+	vmlal.u32	$D0,$H1#lo,$S4
+	 vshr.u64	$MASK,$MASK,#38
+	vmlal.u32	$D4,$H0#lo,$R4
+	vmlal.u32	$D1,$H2#lo,$S4
+	vmlal.u32	$D2,$H3#lo,$S4
+
+.Lshort_tail:
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ horizontal addition
+
+	vadd.i64	$D3#lo,$D3#lo,$D3#hi
+	vadd.i64	$D0#lo,$D0#lo,$D0#hi
+	vadd.i64	$D4#lo,$D4#lo,$D4#hi
+	vadd.i64	$D1#lo,$D1#lo,$D1#hi
+	vadd.i64	$D2#lo,$D2#lo,$D2#hi
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ lazy reduction, but without narrowing
+
+	vshr.u64	$T0,$D3,#26
+	vand.i64	$D3,$D3,$MASK
+	 vshr.u64	$T1,$D0,#26
+	 vand.i64	$D0,$D0,$MASK
+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
+
+	vshr.u64	$T0,$D4,#26
+	vand.i64	$D4,$D4,$MASK
+	 vshr.u64	$T1,$D1,#26
+	 vand.i64	$D1,$D1,$MASK
+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
+
+	vadd.i64	$D0,$D0,$T0
+	vshl.u64	$T0,$T0,#2
+	 vshr.u64	$T1,$D2,#26
+	 vand.i64	$D2,$D2,$MASK
+	vadd.i64	$D0,$D0,$T0		@ h4 -> h0
+	 vadd.i64	$D3,$D3,$T1		@ h2 -> h3
+
+	vshr.u64	$T0,$D0,#26
+	vand.i64	$D0,$D0,$MASK
+	 vshr.u64	$T1,$D3,#26
+	 vand.i64	$D3,$D3,$MASK
+	vadd.i64	$D1,$D1,$T0		@ h0 -> h1
+	 vadd.i64	$D4,$D4,$T1		@ h3 -> h4
+
+	cmp		$len,#0
+	bne		.Leven
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@ store hash value
+
+	vst4.32		{$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
+	vst1.32		{$D4#lo[0]},[$ctx]
+
+	vldmia	sp!,{d8-d15}			@ epilogue
+	ldmia	sp!,{r4-r7}
+.Lno_data_neon:
+	ret					@ bx	lr
+.size	poly1305_blocks_neon,.-poly1305_blocks_neon
+
+.type	poly1305_emit_neon,%function
+.align	5
+poly1305_emit_neon:
+	ldr	ip,[$ctx,#36]		@ is_base2_26
+
+	stmdb	sp!,{r4-r11}
+
+	tst	ip,ip
+	beq	.Lpoly1305_emit_enter
+
+	ldmia	$ctx,{$h0-$h4}
+	eor	$g0,$g0,$g0
+
+	adds	$h0,$h0,$h1,lsl#26	@ base 2^26 -> base 2^32
+	mov	$h1,$h1,lsr#6
+	adcs	$h1,$h1,$h2,lsl#20
+	mov	$h2,$h2,lsr#12
+	adcs	$h2,$h2,$h3,lsl#14
+	mov	$h3,$h3,lsr#18
+	adcs	$h3,$h3,$h4,lsl#8
+	adc	$h4,$g0,$h4,lsr#24	@ can be partially reduced ...
+
+	and	$g0,$h4,#-4		@ ... so reduce
+	and	$h4,$h3,#3
+	add	$g0,$g0,$g0,lsr#2	@ *= 5
+	adds	$h0,$h0,$g0
+	adcs	$h1,$h1,#0
+	adcs	$h2,$h2,#0
+	adc	$h3,$h3,#0
+
+	adds	$g0,$h0,#5		@ compare to modulus
+	adcs	$g1,$h1,#0
+	adcs	$g2,$h2,#0
+	adcs	$g3,$h3,#0
+	adc	$g4,$h4,#0
+	tst	$g4,#4			@ did it carry/borrow?
+
+# ifdef	__thumb2__
+	it	ne
+# endif
+	movne	$h0,$g0
+	ldr	$g0,[$nonce,#0]
+# ifdef	__thumb2__
+	it	ne
+# endif
+	movne	$h1,$g1
+	ldr	$g1,[$nonce,#4]
+# ifdef	__thumb2__
+	it	ne
+# endif
+	movne	$h2,$g2
+	ldr	$g2,[$nonce,#8]
+# ifdef	__thumb2__
+	it	ne
+# endif
+	movne	$h3,$g3
+	ldr	$g3,[$nonce,#12]
+
+	adds	$h0,$h0,$g0		@ accumulate nonce
+	adcs	$h1,$h1,$g1
+	adcs	$h2,$h2,$g2
+	adc	$h3,$h3,$g3
+
+# ifdef __ARMEB__
+	rev	$h0,$h0
+	rev	$h1,$h1
+	rev	$h2,$h2
+	rev	$h3,$h3
+# endif
+	str	$h0,[$mac,#0]		@ store the result
+	str	$h1,[$mac,#4]
+	str	$h2,[$mac,#8]
+	str	$h3,[$mac,#12]
+
+	ldmia	sp!,{r4-r11}
+	ret				@ bx	lr
+.size	poly1305_emit_neon,.-poly1305_emit_neon
+
+.align	5
+.Lzeros:
+.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.LOPENSSL_armcap:
+.word	OPENSSL_armcap_P-.Lpoly1305_init
+#endif
+___
+}	}
+$code.=<<___;
+.asciz	"Poly1305 for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+#if	__ARM_MAX_ARCH__>=7
+.comm   OPENSSL_armcap_P,4,4
+#endif
+___
+
+foreach (split("\n",$code)) {
+	s/\`([^\`]*)\`/eval $1/geo;
+
+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo	or
+	s/\bret\b/bx	lr/go						or
+	s/\bbx\s+lr\b/.word\t0xe12fff1e/go;	# make it possible to compile with -march=armv4
+
+	print $_,"\n";
+}
+close STDOUT; # enforce flush
diff --git a/src/crypto/poly1305/asm/poly1305-armv8.pl b/src/crypto/poly1305/asm/poly1305-armv8.pl
new file mode 100755
index 0000000..1d9a81b
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-armv8.pl
@@ -0,0 +1,925 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for ARMv8.
+#
+# June 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone.
+#
+#		IALU/gcc-4.9	NEON
+#
+# Apple A7	1.86/+5%	0.72
+# Cortex-A53	2.63/+58%	1.47
+# Cortex-A57	2.70/+7%	1.14
+# Denver	1.39/+50%	1.18(*)
+# X-Gene	2.00/+68%	2.19
+#
+# (*)	estimate based on resources availability is less than 1.0,
+#	i.e. measured result is worse than expected, presumably binary
+#	translator is not almighty;
+
+$flavour=shift;
+$output=shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3));
+my ($mac,$nonce)=($inp,$len);
+
+my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14));
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+
+// forward "declarations" are required for Apple
+.extern	OPENSSL_armcap_P
+.globl	poly1305_blocks
+.globl	poly1305_emit
+
+.globl	poly1305_init
+.type	poly1305_init,%function
+.align	5
+poly1305_init:
+	cmp	$inp,xzr
+	stp	xzr,xzr,[$ctx]		// zero hash value
+	stp	xzr,xzr,[$ctx,#16]	// [along with is_base2_26]
+
+	csel	x0,xzr,x0,eq
+	b.eq	.Lno_key
+
+#ifdef	__ILP32__
+	ldrsw	$t1,.LOPENSSL_armcap_P
+#else
+	ldr	$t1,.LOPENSSL_armcap_P
+#endif
+	adr	$t0,.LOPENSSL_armcap_P
+
+	ldp	$r0,$r1,[$inp]		// load key
+	mov	$s1,#0xfffffffc0fffffff
+	movk	$s1,#0x0fff,lsl#48
+	ldr	w17,[$t0,$t1]
+#ifdef	__ARMEB__
+	rev	$r0,$r0			// flip bytes
+	rev	$r1,$r1
+#endif
+	and	$r0,$r0,$s1		// &=0ffffffc0fffffff
+	and	$s1,$s1,#-4
+	and	$r1,$r1,$s1		// &=0ffffffc0ffffffc
+	stp	$r0,$r1,[$ctx,#32]	// save key value
+
+	tst	w17,#ARMV7_NEON
+
+	adr	$d0,poly1305_blocks
+	adr	$r0,poly1305_blocks_neon
+	adr	$d1,poly1305_emit
+	adr	$r1,poly1305_emit_neon
+
+	csel	$d0,$d0,$r0,eq
+	csel	$d1,$d1,$r1,eq
+
+	stp	$d0,$d1,[$len]
+
+	mov	x0,#1
+.Lno_key:
+	ret
+.size	poly1305_init,.-poly1305_init
+
+.type	poly1305_blocks,%function
+.align	5
+poly1305_blocks:
+	ands	$len,$len,#-16
+	b.eq	.Lno_data
+
+	ldp	$h0,$h1,[$ctx]		// load hash value
+	ldp	$r0,$r1,[$ctx,#32]	// load key value
+	ldr	$h2,[$ctx,#16]
+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
+	b	.Loop
+
+.align	5
+.Loop:
+	ldp	$t0,$t1,[$inp],#16	// load input
+	sub	$len,$len,#16
+#ifdef	__ARMEB__
+	rev	$t0,$t0
+	rev	$t1,$t1
+#endif
+	adds	$h0,$h0,$t0		// accumulate input
+	adcs	$h1,$h1,$t1
+
+	mul	$d0,$h0,$r0		// h0*r0
+	adc	$h2,$h2,$padbit
+	umulh	$d1,$h0,$r0
+
+	mul	$t0,$h1,$s1		// h1*5*r1
+	umulh	$t1,$h1,$s1
+
+	adds	$d0,$d0,$t0
+	mul	$t0,$h0,$r1		// h0*r1
+	adc	$d1,$d1,$t1
+	umulh	$d2,$h0,$r1
+
+	adds	$d1,$d1,$t0
+	mul	$t0,$h1,$r0		// h1*r0
+	adc	$d2,$d2,xzr
+	umulh	$t1,$h1,$r0
+
+	adds	$d1,$d1,$t0
+	mul	$t0,$h2,$s1		// h2*5*r1
+	adc	$d2,$d2,$t1
+	mul	$t1,$h2,$r0		// h2*r0
+
+	adds	$d1,$d1,$t0
+	adc	$d2,$d2,$t1
+
+	and	$t0,$d2,#-4		// final reduction
+	and	$h2,$d2,#3
+	add	$t0,$t0,$d2,lsr#2
+	adds	$h0,$d0,$t0
+	adc	$h1,$d1,xzr
+
+	cbnz	$len,.Loop
+
+	stp	$h0,$h1,[$ctx]		// store hash value
+	str	$h2,[$ctx,#16]
+
+.Lno_data:
+	ret
+.size	poly1305_blocks,.-poly1305_blocks
+
+.type	poly1305_emit,%function
+.align	5
+poly1305_emit:
+	ldp	$h0,$h1,[$ctx]		// load hash base 2^64
+	ldr	$h2,[$ctx,#16]
+	ldp	$t0,$t1,[$nonce]	// load nonce
+
+	adds	$d0,$h0,#5		// compare to modulus
+	adcs	$d1,$h1,xzr
+	adc	$d2,$h2,xzr
+
+	tst	$d2,#-4			// see if it's carried/borrowed
+
+	csel	$h0,$h0,$d0,eq
+	csel	$h1,$h1,$d1,eq
+
+#ifdef	__ARMEB__
+	ror	$t0,$t0,#32		// flip nonce words
+	ror	$t1,$t1,#32
+#endif
+	adds	$h0,$h0,$t0		// accumulate nonce
+	adc	$h1,$h1,$t1
+#ifdef	__ARMEB__
+	rev	$h0,$h0			// flip output bytes
+	rev	$h1,$h1
+#endif
+	stp	$h0,$h1,[$mac]		// write result
+
+	ret
+.size	poly1305_emit,.-poly1305_emit
+___
+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8));
+my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13));
+my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18));
+my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23));
+my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28));
+my ($T0,$T1,$MASK) = map("v$_",(29..31));
+
+my ($in2,$zeros)=("x16","x17");
+my $is_base2_26 = $zeros;		# borrow
+
+$code.=<<___;
+.type	poly1305_mult,%function
+.align	5
+poly1305_mult:
+	mul	$d0,$h0,$r0		// h0*r0
+	umulh	$d1,$h0,$r0
+
+	mul	$t0,$h1,$s1		// h1*5*r1
+	umulh	$t1,$h1,$s1
+
+	adds	$d0,$d0,$t0
+	mul	$t0,$h0,$r1		// h0*r1
+	adc	$d1,$d1,$t1
+	umulh	$d2,$h0,$r1
+
+	adds	$d1,$d1,$t0
+	mul	$t0,$h1,$r0		// h1*r0
+	adc	$d2,$d2,xzr
+	umulh	$t1,$h1,$r0
+
+	adds	$d1,$d1,$t0
+	mul	$t0,$h2,$s1		// h2*5*r1
+	adc	$d2,$d2,$t1
+	mul	$t1,$h2,$r0		// h2*r0
+
+	adds	$d1,$d1,$t0
+	adc	$d2,$d2,$t1
+
+	and	$t0,$d2,#-4		// final reduction
+	and	$h2,$d2,#3
+	add	$t0,$t0,$d2,lsr#2
+	adds	$h0,$d0,$t0
+	adc	$h1,$d1,xzr
+
+	ret
+.size	poly1305_mult,.-poly1305_mult
+
+.type	poly1305_splat,%function
+.align	5
+poly1305_splat:
+	and	x12,$h0,#0x03ffffff	// base 2^64 -> base 2^26
+	ubfx	x13,$h0,#26,#26
+	extr	x14,$h1,$h0,#52
+	and	x14,x14,#0x03ffffff
+	ubfx	x15,$h1,#14,#26
+	extr	x16,$h2,$h1,#40
+
+	str	w12,[$ctx,#16*0]	// r0
+	add	w12,w13,w13,lsl#2	// r1*5
+	str	w13,[$ctx,#16*1]	// r1
+	add	w13,w14,w14,lsl#2	// r2*5
+	str	w12,[$ctx,#16*2]	// s1
+	str	w14,[$ctx,#16*3]	// r2
+	add	w14,w15,w15,lsl#2	// r3*5
+	str	w13,[$ctx,#16*4]	// s2
+	str	w15,[$ctx,#16*5]	// r3
+	add	w15,w16,w16,lsl#2	// r4*5
+	str	w14,[$ctx,#16*6]	// s3
+	str	w16,[$ctx,#16*7]	// r4
+	str	w15,[$ctx,#16*8]	// s4
+
+	ret
+.size	poly1305_splat,.-poly1305_splat
+
+.type	poly1305_blocks_neon,%function
+.align	5
+poly1305_blocks_neon:
+	ldr	$is_base2_26,[$ctx,#24]
+	cmp	$len,#128
+	b.hs	.Lblocks_neon
+	cbz	$is_base2_26,poly1305_blocks
+
+.Lblocks_neon:
+	stp	x29,x30,[sp,#-80]!
+	add	x29,sp,#0
+
+	ands	$len,$len,#-16
+	b.eq	.Lno_data_neon
+
+	cbz	$is_base2_26,.Lbase2_64_neon
+
+	ldp	w10,w11,[$ctx]		// load hash value base 2^26
+	ldp	w12,w13,[$ctx,#8]
+	ldr	w14,[$ctx,#16]
+
+	tst	$len,#31
+	b.eq	.Leven_neon
+
+	ldp	$r0,$r1,[$ctx,#32]	// load key value
+
+	add	$h0,x10,x11,lsl#26	// base 2^26 -> base 2^64
+	lsr	$h1,x12,#12
+	adds	$h0,$h0,x12,lsl#52
+	add	$h1,$h1,x13,lsl#14
+	adc	$h1,$h1,xzr
+	lsr	$h2,x14,#24
+	adds	$h1,$h1,x14,lsl#40
+	adc	$d2,$h2,xzr		// can be partially reduced...
+
+	ldp	$d0,$d1,[$inp],#16	// load input
+	sub	$len,$len,#16
+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
+
+	and	$t0,$d2,#-4		// ... so reduce
+	and	$h2,$d2,#3
+	add	$t0,$t0,$d2,lsr#2
+	adds	$h0,$h0,$t0
+	adc	$h1,$h1,xzr
+
+#ifdef	__ARMEB__
+	rev	$d0,$d0
+	rev	$d1,$d1
+#endif
+	adds	$h0,$h0,$d0		// accumulate input
+	adcs	$h1,$h1,$d1
+	adc	$h2,$h2,$padbit
+
+	bl	poly1305_mult
+	ldr	x30,[sp,#8]
+
+	cbz	$padbit,.Lstore_base2_64_neon
+
+	and	x10,$h0,#0x03ffffff	// base 2^64 -> base 2^26
+	ubfx	x11,$h0,#26,#26
+	extr	x12,$h1,$h0,#52
+	and	x12,x12,#0x03ffffff
+	ubfx	x13,$h1,#14,#26
+	extr	x14,$h2,$h1,#40
+
+	cbnz	$len,.Leven_neon
+
+	stp	w10,w11,[$ctx]		// store hash value base 2^26
+	stp	w12,w13,[$ctx,#8]
+	str	w14,[$ctx,#16]
+	b	.Lno_data_neon
+
+.align	4
+.Lstore_base2_64_neon:
+	stp	$h0,$h1,[$ctx]		// store hash value base 2^64
+	stp	$h2,xzr,[$ctx,#16]	// note that is_base2_26 is zeroed
+	b	.Lno_data_neon
+
+.align	4
+.Lbase2_64_neon:
+	ldp	$r0,$r1,[$ctx,#32]	// load key value
+
+	ldp	$h0,$h1,[$ctx]		// load hash value base 2^64
+	ldr	$h2,[$ctx,#16]
+
+	tst	$len,#31
+	b.eq	.Linit_neon
+
+	ldp	$d0,$d1,[$inp],#16	// load input
+	sub	$len,$len,#16
+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
+#ifdef	__ARMEB__
+	rev	$d0,$d0
+	rev	$d1,$d1
+#endif
+	adds	$h0,$h0,$d0		// accumulate input
+	adcs	$h1,$h1,$d1
+	adc	$h2,$h2,$padbit
+
+	bl	poly1305_mult
+
+.Linit_neon:
+	and	x10,$h0,#0x03ffffff	// base 2^64 -> base 2^26
+	ubfx	x11,$h0,#26,#26
+	extr	x12,$h1,$h0,#52
+	and	x12,x12,#0x03ffffff
+	ubfx	x13,$h1,#14,#26
+	extr	x14,$h2,$h1,#40
+
+	stp	d8,d9,[sp,#16]		// meet ABI requirements
+	stp	d10,d11,[sp,#32]
+	stp	d12,d13,[sp,#48]
+	stp	d14,d15,[sp,#64]
+
+	fmov	${H0},x10
+	fmov	${H1},x11
+	fmov	${H2},x12
+	fmov	${H3},x13
+	fmov	${H4},x14
+
+	////////////////////////////////// initialize r^n table
+	mov	$h0,$r0			// r^1
+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
+	mov	$h1,$r1
+	mov	$h2,xzr
+	add	$ctx,$ctx,#48+12
+	bl	poly1305_splat
+
+	bl	poly1305_mult		// r^2
+	sub	$ctx,$ctx,#4
+	bl	poly1305_splat
+
+	bl	poly1305_mult		// r^3
+	sub	$ctx,$ctx,#4
+	bl	poly1305_splat
+
+	bl	poly1305_mult		// r^4
+	sub	$ctx,$ctx,#4
+	bl	poly1305_splat
+	ldr	x30,[sp,#8]
+
+	add	$in2,$inp,#32
+	adr	$zeros,.Lzeros
+	subs	$len,$len,#64
+	csel	$in2,$zeros,$in2,lo
+
+	mov	x4,#1
+	str	x4,[$ctx,#-24]		// set is_base2_26
+	sub	$ctx,$ctx,#48		// restore original $ctx
+	b	.Ldo_neon
+
+.align	4
+.Leven_neon:
+	add	$in2,$inp,#32
+	adr	$zeros,.Lzeros
+	subs	$len,$len,#64
+	csel	$in2,$zeros,$in2,lo
+
+	stp	d8,d9,[sp,#16]		// meet ABI requirements
+	stp	d10,d11,[sp,#32]
+	stp	d12,d13,[sp,#48]
+	stp	d14,d15,[sp,#64]
+
+	fmov	${H0},x10
+	fmov	${H1},x11
+	fmov	${H2},x12
+	fmov	${H3},x13
+	fmov	${H4},x14
+
+.Ldo_neon:
+	ldp	x8,x12,[$in2],#16	// inp[2:3] (or zero)
+	ldp	x9,x13,[$in2],#48
+
+	lsl	$padbit,$padbit,#24
+	add	x15,$ctx,#48
+
+#ifdef	__ARMEB__
+	rev	x8,x8
+	rev	x12,x12
+	rev	x9,x9
+	rev	x13,x13
+#endif
+	and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
+	and	x5,x9,#0x03ffffff
+	ubfx	x6,x8,#26,#26
+	ubfx	x7,x9,#26,#26
+	add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
+	extr	x8,x12,x8,#52
+	extr	x9,x13,x9,#52
+	add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
+	fmov	$IN23_0,x4
+	and	x8,x8,#0x03ffffff
+	and	x9,x9,#0x03ffffff
+	ubfx	x10,x12,#14,#26
+	ubfx	x11,x13,#14,#26
+	add	x12,$padbit,x12,lsr#40
+	add	x13,$padbit,x13,lsr#40
+	add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
+	fmov	$IN23_1,x6
+	add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
+	add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
+	fmov	$IN23_2,x8
+	fmov	$IN23_3,x10
+	fmov	$IN23_4,x12
+
+	ldp	x8,x12,[$inp],#16	// inp[0:1]
+	ldp	x9,x13,[$inp],#48
+
+	ld1	{$R0,$R1,$S1,$R2},[x15],#64
+	ld1	{$S2,$R3,$S3,$R4},[x15],#64
+	ld1	{$S4},[x15]
+
+#ifdef	__ARMEB__
+	rev	x8,x8
+	rev	x12,x12
+	rev	x9,x9
+	rev	x13,x13
+#endif
+	and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
+	and	x5,x9,#0x03ffffff
+	ubfx	x6,x8,#26,#26
+	ubfx	x7,x9,#26,#26
+	add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
+	extr	x8,x12,x8,#52
+	extr	x9,x13,x9,#52
+	add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
+	fmov	$IN01_0,x4
+	and	x8,x8,#0x03ffffff
+	and	x9,x9,#0x03ffffff
+	ubfx	x10,x12,#14,#26
+	ubfx	x11,x13,#14,#26
+	add	x12,$padbit,x12,lsr#40
+	add	x13,$padbit,x13,lsr#40
+	add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
+	fmov	$IN01_1,x6
+	add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
+	add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
+	fmov	$IN01_2,x8
+	fmov	$IN01_3,x10
+	fmov	$IN01_4,x12
+
+	b.ls	.Lskip_loop
+
+.align	4
+.Loop_neon:
+	////////////////////////////////////////////////////////////////
+	// ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+	// ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+	//   \___________________/
+	// ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+	// ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+	//   \___________________/ \____________________/
+	//
+	// Note that we start with inp[2:3]*r^2. This is because it
+	// doesn't depend on reduction in previous iteration.
+	////////////////////////////////////////////////////////////////
+	// d4 = h0*r4 + h1*r3   + h2*r2   + h3*r1   + h4*r0
+	// d3 = h0*r3 + h1*r2   + h2*r1   + h3*r0   + h4*5*r4
+	// d2 = h0*r2 + h1*r1   + h2*r0   + h3*5*r4 + h4*5*r3
+	// d1 = h0*r1 + h1*r0   + h2*5*r4 + h3*5*r3 + h4*5*r2
+	// d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+	subs	$len,$len,#64
+	umull	$ACC4,$IN23_0,${R4}[2]
+	csel	$in2,$zeros,$in2,lo
+	umull	$ACC3,$IN23_0,${R3}[2]
+	umull	$ACC2,$IN23_0,${R2}[2]
+	 ldp	x8,x12,[$in2],#16	// inp[2:3] (or zero)
+	umull	$ACC1,$IN23_0,${R1}[2]
+	 ldp	x9,x13,[$in2],#48
+	umull	$ACC0,$IN23_0,${R0}[2]
+#ifdef	__ARMEB__
+	 rev	x8,x8
+	 rev	x12,x12
+	 rev	x9,x9
+	 rev	x13,x13
+#endif
+
+	umlal	$ACC4,$IN23_1,${R3}[2]
+	 and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
+	umlal	$ACC3,$IN23_1,${R2}[2]
+	 and	x5,x9,#0x03ffffff
+	umlal	$ACC2,$IN23_1,${R1}[2]
+	 ubfx	x6,x8,#26,#26
+	umlal	$ACC1,$IN23_1,${R0}[2]
+	 ubfx	x7,x9,#26,#26
+	umlal	$ACC0,$IN23_1,${S4}[2]
+	 add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
+
+	umlal	$ACC4,$IN23_2,${R2}[2]
+	 extr	x8,x12,x8,#52
+	umlal	$ACC3,$IN23_2,${R1}[2]
+	 extr	x9,x13,x9,#52
+	umlal	$ACC2,$IN23_2,${R0}[2]
+	 add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
+	umlal	$ACC1,$IN23_2,${S4}[2]
+	 fmov	$IN23_0,x4
+	umlal	$ACC0,$IN23_2,${S3}[2]
+	 and	x8,x8,#0x03ffffff
+
+	umlal	$ACC4,$IN23_3,${R1}[2]
+	 and	x9,x9,#0x03ffffff
+	umlal	$ACC3,$IN23_3,${R0}[2]
+	 ubfx	x10,x12,#14,#26
+	umlal	$ACC2,$IN23_3,${S4}[2]
+	 ubfx	x11,x13,#14,#26
+	umlal	$ACC1,$IN23_3,${S3}[2]
+	 add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
+	umlal	$ACC0,$IN23_3,${S2}[2]
+	 fmov	$IN23_1,x6
+
+	add	$IN01_2,$IN01_2,$H2
+	 add	x12,$padbit,x12,lsr#40
+	umlal	$ACC4,$IN23_4,${R0}[2]
+	 add	x13,$padbit,x13,lsr#40
+	umlal	$ACC3,$IN23_4,${S4}[2]
+	 add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
+	umlal	$ACC2,$IN23_4,${S3}[2]
+	 add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
+	umlal	$ACC1,$IN23_4,${S2}[2]
+	 fmov	$IN23_2,x8
+	umlal	$ACC0,$IN23_4,${S1}[2]
+	 fmov	$IN23_3,x10
+
+	////////////////////////////////////////////////////////////////
+	// (hash+inp[0:1])*r^4 and accumulate
+
+	add	$IN01_0,$IN01_0,$H0
+	 fmov	$IN23_4,x12
+	umlal	$ACC3,$IN01_2,${R1}[0]
+	 ldp	x8,x12,[$inp],#16	// inp[0:1]
+	umlal	$ACC0,$IN01_2,${S3}[0]
+	 ldp	x9,x13,[$inp],#48
+	umlal	$ACC4,$IN01_2,${R2}[0]
+	umlal	$ACC1,$IN01_2,${S4}[0]
+	umlal	$ACC2,$IN01_2,${R0}[0]
+#ifdef	__ARMEB__
+	 rev	x8,x8
+	 rev	x12,x12
+	 rev	x9,x9
+	 rev	x13,x13
+#endif
+
+	add	$IN01_1,$IN01_1,$H1
+	umlal	$ACC3,$IN01_0,${R3}[0]
+	umlal	$ACC4,$IN01_0,${R4}[0]
+	 and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
+	umlal	$ACC2,$IN01_0,${R2}[0]
+	 and	x5,x9,#0x03ffffff
+	umlal	$ACC0,$IN01_0,${R0}[0]
+	 ubfx	x6,x8,#26,#26
+	umlal	$ACC1,$IN01_0,${R1}[0]
+	 ubfx	x7,x9,#26,#26
+
+	add	$IN01_3,$IN01_3,$H3
+	 add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
+	umlal	$ACC3,$IN01_1,${R2}[0]
+	 extr	x8,x12,x8,#52
+	umlal	$ACC4,$IN01_1,${R3}[0]
+	 extr	x9,x13,x9,#52
+	umlal	$ACC0,$IN01_1,${S4}[0]
+	 add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
+	umlal	$ACC2,$IN01_1,${R1}[0]
+	 fmov	$IN01_0,x4
+	umlal	$ACC1,$IN01_1,${R0}[0]
+	 and	x8,x8,#0x03ffffff
+
+	add	$IN01_4,$IN01_4,$H4
+	 and	x9,x9,#0x03ffffff
+	umlal	$ACC3,$IN01_3,${R0}[0]
+	 ubfx	x10,x12,#14,#26
+	umlal	$ACC0,$IN01_3,${S2}[0]
+	 ubfx	x11,x13,#14,#26
+	umlal	$ACC4,$IN01_3,${R1}[0]
+	 add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
+	umlal	$ACC1,$IN01_3,${S3}[0]
+	 fmov	$IN01_1,x6
+	umlal	$ACC2,$IN01_3,${S4}[0]
+	 add	x12,$padbit,x12,lsr#40
+
+	umlal	$ACC3,$IN01_4,${S4}[0]
+	 add	x13,$padbit,x13,lsr#40
+	umlal	$ACC0,$IN01_4,${S1}[0]
+	 add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
+	umlal	$ACC4,$IN01_4,${R0}[0]
+	 add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
+	umlal	$ACC1,$IN01_4,${S2}[0]
+	 fmov	$IN01_2,x8
+	umlal	$ACC2,$IN01_4,${S3}[0]
+	 fmov	$IN01_3,x10
+
+	/////////////////////////////////////////////////////////////////
+	// lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+        // and P. Schwabe
+
+	ushr	$T0.2d,$ACC3,#26
+	 fmov	$IN01_4,x12
+	xtn	$H3,$ACC3
+	 ushr	$T1.2d,$ACC0,#26
+	 xtn	$H0,$ACC0
+	add	$ACC4,$ACC4,$T0.2d	// h3 -> h4
+	bic	$H3,#0xfc,lsl#24	// &=0x03ffffff
+	 add	$ACC1,$ACC1,$T1.2d	// h0 -> h1
+	 bic	$H0,#0xfc,lsl#24
+
+	shrn	$T0.2s,$ACC4,#26
+	xtn	$H4,$ACC4
+	 ushr	$T1.2d,$ACC1,#26
+	 xtn	$H1,$ACC1
+	 add	$ACC2,$ACC2,$T1.2d	// h1 -> h2
+	bic	$H4,#0xfc,lsl#24
+	 bic	$H1,#0xfc,lsl#24
+
+	add	$H0,$H0,$T0.2s
+	shl	$T0.2s,$T0.2s,#2
+	 shrn	$T1.2s,$ACC2,#26
+	 xtn	$H2,$ACC2
+	add	$H0,$H0,$T0.2s		// h4 -> h0
+	 add	$H3,$H3,$T1.2s		// h2 -> h3
+	 bic	$H2,#0xfc,lsl#24
+
+	ushr	$T0.2s,$H0,#26
+	bic	$H0,#0xfc,lsl#24
+	 ushr	$T1.2s,$H3,#26
+	 bic	$H3,#0xfc,lsl#24
+	add	$H1,$H1,$T0.2s		// h0 -> h1
+	 add	$H4,$H4,$T1.2s		// h3 -> h4
+
+	b.hi	.Loop_neon
+
+.Lskip_loop:
+	dup	$IN23_2,${IN23_2}[0]
+	movi	$MASK.2d,#-1
+	add	$IN01_2,$IN01_2,$H2
+	ushr	$MASK.2d,$MASK.2d,#38
+
+	////////////////////////////////////////////////////////////////
+	// multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+	adds	$len,$len,#32
+	b.ne	.Long_tail
+
+	dup	$IN23_2,${IN01_2}[0]
+	add	$IN23_0,$IN01_0,$H0
+	add	$IN23_3,$IN01_3,$H3
+	add	$IN23_1,$IN01_1,$H1
+	add	$IN23_4,$IN01_4,$H4
+
+.Long_tail:
+	dup	$IN23_0,${IN23_0}[0]
+	umull2	$ACC0,$IN23_2,${S3}
+	umull2	$ACC3,$IN23_2,${R1}
+	umull2	$ACC4,$IN23_2,${R2}
+	umull2	$ACC2,$IN23_2,${R0}
+	umull2	$ACC1,$IN23_2,${S4}
+
+	dup	$IN23_1,${IN23_1}[0]
+	umlal2	$ACC0,$IN23_0,${R0}
+	umlal2	$ACC2,$IN23_0,${R2}
+	umlal2	$ACC3,$IN23_0,${R3}
+	umlal2	$ACC4,$IN23_0,${R4}
+	umlal2	$ACC1,$IN23_0,${R1}
+
+	dup	$IN23_3,${IN23_3}[0]
+	umlal2	$ACC0,$IN23_1,${S4}
+	umlal2	$ACC3,$IN23_1,${R2}
+	umlal2	$ACC2,$IN23_1,${R1}
+	umlal2	$ACC4,$IN23_1,${R3}
+	umlal2	$ACC1,$IN23_1,${R0}
+
+	dup	$IN23_4,${IN23_4}[0]
+	umlal2	$ACC3,$IN23_3,${R0}
+	umlal2	$ACC4,$IN23_3,${R1}
+	umlal2	$ACC0,$IN23_3,${S2}
+	umlal2	$ACC1,$IN23_3,${S3}
+	umlal2	$ACC2,$IN23_3,${S4}
+
+	umlal2	$ACC3,$IN23_4,${S4}
+	umlal2	$ACC0,$IN23_4,${S1}
+	umlal2	$ACC4,$IN23_4,${R0}
+	umlal2	$ACC1,$IN23_4,${S2}
+	umlal2	$ACC2,$IN23_4,${S3}
+
+	b.eq	.Lshort_tail
+
+	////////////////////////////////////////////////////////////////
+	// (hash+inp[0:1])*r^4:r^3 and accumulate
+
+	add	$IN01_0,$IN01_0,$H0
+	umlal	$ACC3,$IN01_2,${R1}
+	umlal	$ACC0,$IN01_2,${S3}
+	umlal	$ACC4,$IN01_2,${R2}
+	umlal	$ACC1,$IN01_2,${S4}
+	umlal	$ACC2,$IN01_2,${R0}
+
+	add	$IN01_1,$IN01_1,$H1
+	umlal	$ACC3,$IN01_0,${R3}
+	umlal	$ACC0,$IN01_0,${R0}
+	umlal	$ACC4,$IN01_0,${R4}
+	umlal	$ACC1,$IN01_0,${R1}
+	umlal	$ACC2,$IN01_0,${R2}
+
+	add	$IN01_3,$IN01_3,$H3
+	umlal	$ACC3,$IN01_1,${R2}
+	umlal	$ACC0,$IN01_1,${S4}
+	umlal	$ACC4,$IN01_1,${R3}
+	umlal	$ACC1,$IN01_1,${R0}
+	umlal	$ACC2,$IN01_1,${R1}
+
+	add	$IN01_4,$IN01_4,$H4
+	umlal	$ACC3,$IN01_3,${R0}
+	umlal	$ACC0,$IN01_3,${S2}
+	umlal	$ACC4,$IN01_3,${R1}
+	umlal	$ACC1,$IN01_3,${S3}
+	umlal	$ACC2,$IN01_3,${S4}
+
+	umlal	$ACC3,$IN01_4,${S4}
+	umlal	$ACC0,$IN01_4,${S1}
+	umlal	$ACC4,$IN01_4,${R0}
+	umlal	$ACC1,$IN01_4,${S2}
+	umlal	$ACC2,$IN01_4,${S3}
+
+.Lshort_tail:
+	////////////////////////////////////////////////////////////////
+	// horizontal add
+
+	addp	$ACC3,$ACC3,$ACC3
+	 ldp	d8,d9,[sp,#16]		// meet ABI requirements
+	addp	$ACC0,$ACC0,$ACC0
+	 ldp	d10,d11,[sp,#32]
+	addp	$ACC4,$ACC4,$ACC4
+	 ldp	d12,d13,[sp,#48]
+	addp	$ACC1,$ACC1,$ACC1
+	 ldp	d14,d15,[sp,#64]
+	addp	$ACC2,$ACC2,$ACC2
+
+	////////////////////////////////////////////////////////////////
+	// lazy reduction, but without narrowing
+
+	ushr	$T0.2d,$ACC3,#26
+	and	$ACC3,$ACC3,$MASK.2d
+	 ushr	$T1.2d,$ACC0,#26
+	 and	$ACC0,$ACC0,$MASK.2d
+
+	add	$ACC4,$ACC4,$T0.2d	// h3 -> h4
+	 add	$ACC1,$ACC1,$T1.2d	// h0 -> h1
+
+	ushr	$T0.2d,$ACC4,#26
+	and	$ACC4,$ACC4,$MASK.2d
+	 ushr	$T1.2d,$ACC1,#26
+	 and	$ACC1,$ACC1,$MASK.2d
+	 add	$ACC2,$ACC2,$T1.2d	// h1 -> h2
+
+	add	$ACC0,$ACC0,$T0.2d
+	shl	$T0.2d,$T0.2d,#2
+	 ushr	$T1.2d,$ACC2,#26
+	 and	$ACC2,$ACC2,$MASK.2d
+	add	$ACC0,$ACC0,$T0.2d	// h4 -> h0
+	 add	$ACC3,$ACC3,$T1.2d	// h2 -> h3
+
+	ushr	$T0.2d,$ACC0,#26
+	and	$ACC0,$ACC0,$MASK.2d
+	 ushr	$T1.2d,$ACC3,#26
+	 and	$ACC3,$ACC3,$MASK.2d
+	add	$ACC1,$ACC1,$T0.2d	// h0 -> h1
+	 add	$ACC4,$ACC4,$T1.2d	// h3 -> h4
+
+	////////////////////////////////////////////////////////////////
+	// write the result, can be partially reduced
+
+	st4	{$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16
+	st1	{$ACC4}[0],[$ctx]
+
+.Lno_data_neon:
+	ldr	x29,[sp],#80
+	ret
+.size	poly1305_blocks_neon,.-poly1305_blocks_neon
+
+.type	poly1305_emit_neon,%function
+.align	5
+poly1305_emit_neon:
+	ldr	$is_base2_26,[$ctx,#24]
+	cbz	$is_base2_26,poly1305_emit
+
+	ldp	w10,w11,[$ctx]		// load hash value base 2^26
+	ldp	w12,w13,[$ctx,#8]
+	ldr	w14,[$ctx,#16]
+
+	add	$h0,x10,x11,lsl#26	// base 2^26 -> base 2^64
+	lsr	$h1,x12,#12
+	adds	$h0,$h0,x12,lsl#52
+	add	$h1,$h1,x13,lsl#14
+	adc	$h1,$h1,xzr
+	lsr	$h2,x14,#24
+	adds	$h1,$h1,x14,lsl#40
+	adc	$h2,$h2,xzr		// can be partially reduced...
+
+	ldp	$t0,$t1,[$nonce]	// load nonce
+
+	and	$d0,$h2,#-4		// ... so reduce
+	add	$d0,$d0,$h2,lsr#2
+	and	$h2,$h2,#3
+	adds	$h0,$h0,$d0
+	adc	$h1,$h1,xzr
+
+	adds	$d0,$h0,#5		// compare to modulus
+	adcs	$d1,$h1,xzr
+	adc	$d2,$h2,xzr
+
+	tst	$d2,#-4			// see if it's carried/borrowed
+
+	csel	$h0,$h0,$d0,eq
+	csel	$h1,$h1,$d1,eq
+
+#ifdef	__ARMEB__
+	ror	$t0,$t0,#32		// flip nonce words
+	ror	$t1,$t1,#32
+#endif
+	adds	$h0,$h0,$t0		// accumulate nonce
+	adc	$h1,$h1,$t1
+#ifdef	__ARMEB__
+	rev	$h0,$h0			// flip output bytes
+	rev	$h1,$h1
+#endif
+	stp	$h0,$h1,[$mac]		// write result
+
+	ret
+.size	poly1305_emit_neon,.-poly1305_emit_neon
+
+.align	5
+.Lzeros:
+.long	0,0,0,0,0,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef	__ILP32__
+.long	OPENSSL_armcap_P-.
+#else
+.quad	OPENSSL_armcap_P-.
+#endif
+.asciz	"Poly1305 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+foreach (split("\n",$code)) {
+	s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/			or
+	s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/	or
+	(m/\bdup\b/ and (s/\.[24]s/.2d/g or 1))			or
+	(m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1))	or
+	(m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1))		or
+	(m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1))		or
+	(m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1));
+
+	s/\.[124]([sd])\[/.$1\[/;
+
+	print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/poly1305/asm/poly1305-x86.pl b/src/crypto/poly1305/asm/poly1305-x86.pl
new file mode 100755
index 0000000..4ad2289
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-x86.pl
@@ -0,0 +1,1788 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for x86.
+#
+# April 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone,
+# measured with rdtsc at fixed clock frequency.
+#
+#		IALU/gcc-3.4(*)	SSE2(**)	AVX2
+# Pentium	15.7/+80%	-
+# PIII		6.21/+90%	-
+# P4		19.8/+40%	3.24
+# Core 2	4.85/+90%	1.80
+# Westmere	4.58/+100%	1.43
+# Sandy Bridge	3.90/+100%	1.36
+# Haswell	3.88/+70%	1.18		0.72
+# Silvermont	11.0/+40%	4.80
+# VIA Nano	6.71/+90%	2.47
+# Sledgehammer	3.51/+180%	4.27
+# Bulldozer	4.53/+140%	1.31
+#
+# (*)	gcc 4.8 for some reason generated worse code;
+# (**)	besides SSE2 there are floating-point and AVX options; FP
+#	is deemed unnecessary, because pre-SSE2 processor are too
+#	old to care about, while it's not the fastest option on
+#	SSE2-capable ones; AVX is omitted, because it doesn't give
+#	a lot of improvement, 5-10% depending on processor;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"poly1305-x86.pl",$ARGV[$#ARGV] eq "386");
+
+$sse2=$avx=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+if ($sse2) {
+	&static_label("const_sse2");
+	&static_label("enter_blocks");
+	&static_label("enter_emit");
+	&external_label("OPENSSL_ia32cap_P");
+
+	# This may be set to 2, but valgrind can't do AVX2 on 32-bit. Without a
+	# way to verify test coverage, keep it disabled.
+	$avx = 0;
+}
+
+########################################################################
+# Layout of opaque area is following.
+#
+#	unsigned __int32 h[5];		# current hash value base 2^32
+#	unsigned __int32 pad;		# is_base2_26 in vector context
+#	unsigned __int32 r[4];		# key value base 2^32
+
+&align(64);
+&function_begin("poly1305_init");
+	&mov	("edi",&wparam(0));		# context
+	&mov	("esi",&wparam(1));		# key
+	&mov	("ebp",&wparam(2));		# function table
+
+	&xor	("eax","eax");
+	&mov	(&DWP(4*0,"edi"),"eax");	# zero hash value
+	&mov	(&DWP(4*1,"edi"),"eax");
+	&mov	(&DWP(4*2,"edi"),"eax");
+	&mov	(&DWP(4*3,"edi"),"eax");
+	&mov	(&DWP(4*4,"edi"),"eax");
+	&mov	(&DWP(4*5,"edi"),"eax");	# is_base2_26
+
+	&cmp	("esi",0);
+	&je	(&label("nokey"));
+
+    if ($sse2) {
+	&call	(&label("pic_point"));
+    &set_label("pic_point");
+	&blindpop("ebx");
+
+	&lea	("eax",&DWP("poly1305_blocks-".&label("pic_point"),"ebx"));
+	&lea	("edx",&DWP("poly1305_emit-".&label("pic_point"),"ebx"));
+
+	&picmeup("edi","OPENSSL_ia32cap_P","ebx",&label("pic_point"));
+	&mov	("ecx",&DWP(0,"edi"));
+	&and	("ecx",1<<26|1<<24);
+	&cmp	("ecx",1<<26|1<<24);		# SSE2 and XMM?
+	&jne	(&label("no_sse2"));
+
+	&lea	("eax",&DWP("_poly1305_blocks_sse2-".&label("pic_point"),"ebx"));
+	&lea	("edx",&DWP("_poly1305_emit_sse2-".&label("pic_point"),"ebx"));
+
+      if ($avx>1) {
+	&mov	("ecx",&DWP(8,"edi"));
+	&test	("ecx",1<<5);			# AVX2?
+	&jz	(&label("no_sse2"));
+
+	&lea	("eax",&DWP("_poly1305_blocks_avx2-".&label("pic_point"),"ebx"));
+      }
+    &set_label("no_sse2");
+	&mov	("edi",&wparam(0));		# reload context
+	&mov	(&DWP(0,"ebp"),"eax");		# fill function table
+	&mov	(&DWP(4,"ebp"),"edx");
+    }
+
+	&mov	("eax",&DWP(4*0,"esi"));	# load input key
+	&mov	("ebx",&DWP(4*1,"esi"));
+	&mov	("ecx",&DWP(4*2,"esi"));
+	&mov	("edx",&DWP(4*3,"esi"));
+	&and	("eax",0x0fffffff);
+	&and	("ebx",0x0ffffffc);
+	&and	("ecx",0x0ffffffc);
+	&and	("edx",0x0ffffffc);
+	&mov	(&DWP(4*6,"edi"),"eax");
+	&mov	(&DWP(4*7,"edi"),"ebx");
+	&mov	(&DWP(4*8,"edi"),"ecx");
+	&mov	(&DWP(4*9,"edi"),"edx");
+
+	&mov	("eax",$sse2);
+&set_label("nokey");
+&function_end("poly1305_init");
+
+($h0,$h1,$h2,$h3,$h4,
+ $d0,$d1,$d2,$d3,
+ $r0,$r1,$r2,$r3,
+     $s1,$s2,$s3)=map(4*$_,(0..15));
+
+&function_begin("poly1305_blocks");
+	&mov	("edi",&wparam(0));		# ctx
+	&mov	("esi",&wparam(1));		# inp
+	&mov	("ecx",&wparam(2));		# len
+&set_label("enter_blocks");
+	&and	("ecx",-15);
+	&jz	(&label("nodata"));
+
+	&stack_push(16);
+	&mov	("eax",&DWP(4*6,"edi"));	# r0
+	&mov	("ebx",&DWP(4*7,"edi"));	# r1
+	 &lea	("ebp",&DWP(0,"esi","ecx"));	# end of input
+	&mov	("ecx",&DWP(4*8,"edi"));	# r2
+	&mov	("edx",&DWP(4*9,"edi"));	# r3
+
+	&mov	(&wparam(2),"ebp");
+	&mov	("ebp","esi");
+
+	&mov	(&DWP($r0,"esp"),"eax");	# r0
+	&mov	("eax","ebx");
+	&shr	("eax",2);
+	&mov	(&DWP($r1,"esp"),"ebx");	# r1
+	&add	("eax","ebx");			# s1
+	&mov	("ebx","ecx");
+	&shr	("ebx",2);
+	&mov	(&DWP($r2,"esp"),"ecx");	# r2
+	&add	("ebx","ecx");			# s2
+	&mov	("ecx","edx");
+	&shr	("ecx",2);
+	&mov	(&DWP($r3,"esp"),"edx");	# r3
+	&add	("ecx","edx");			# s3
+	&mov	(&DWP($s1,"esp"),"eax");	# s1
+	&mov	(&DWP($s2,"esp"),"ebx");	# s2
+	&mov	(&DWP($s3,"esp"),"ecx");	# s3
+
+	&mov	("eax",&DWP(4*0,"edi"));	# load hash value
+	&mov	("ebx",&DWP(4*1,"edi"));
+	&mov	("ecx",&DWP(4*2,"edi"));
+	&mov	("esi",&DWP(4*3,"edi"));
+	&mov	("edi",&DWP(4*4,"edi"));
+	&jmp	(&label("loop"));
+
+&set_label("loop",32);
+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate input
+	&adc	("ebx",&DWP(4*1,"ebp"));
+	&adc	("ecx",&DWP(4*2,"ebp"));
+	&adc	("esi",&DWP(4*3,"ebp"));
+	&lea	("ebp",&DWP(4*4,"ebp"));
+	&adc	("edi",&wparam(3));		# padbit
+
+	&mov	(&DWP($h0,"esp"),"eax");	# put aside hash[+inp]
+	&mov	(&DWP($h3,"esp"),"esi");
+
+	&mul	(&DWP($r0,"esp"));		# h0*r0
+	 &mov	(&DWP($h4,"esp"),"edi");
+	&mov	("edi","eax");
+	&mov	("eax","ebx");			# h1
+	&mov	("esi","edx");
+	&mul	(&DWP($s3,"esp"));		# h1*s3
+	&add	("edi","eax");
+	&mov	("eax","ecx");			# h2
+	&adc	("esi","edx");
+	&mul	(&DWP($s2,"esp"));		# h2*s2
+	&add	("edi","eax");
+	&mov	("eax",&DWP($h3,"esp"));
+	&adc	("esi","edx");
+	&mul	(&DWP($s1,"esp"));		# h3*s1
+	&add	("edi","eax");
+	 &mov	("eax",&DWP($h0,"esp"));
+	&adc	("esi","edx");
+
+	&mul	(&DWP($r1,"esp"));		# h0*r1
+	 &mov	(&DWP($d0,"esp"),"edi");
+	&xor	("edi","edi");
+	&add	("esi","eax");
+	&mov	("eax","ebx");			# h1
+	&adc	("edi","edx");
+	&mul	(&DWP($r0,"esp"));		# h1*r0
+	&add	("esi","eax");
+	&mov	("eax","ecx");			# h2
+	&adc	("edi","edx");
+	&mul	(&DWP($s3,"esp"));		# h2*s3
+	&add	("esi","eax");
+	&mov	("eax",&DWP($h3,"esp"));
+	&adc	("edi","edx");
+	&mul	(&DWP($s2,"esp"));		# h3*s2
+	&add	("esi","eax");
+	&mov	("eax",&DWP($h4,"esp"));
+	&adc	("edi","edx");
+	&imul	("eax",&DWP($s1,"esp"));	# h4*s1
+	&add	("esi","eax");
+	 &mov	("eax",&DWP($h0,"esp"));
+	&adc	("edi",0);
+
+	&mul	(&DWP($r2,"esp"));		# h0*r2
+	 &mov	(&DWP($d1,"esp"),"esi");
+	&xor	("esi","esi");
+	&add	("edi","eax");
+	&mov	("eax","ebx");			# h1
+	&adc	("esi","edx");
+	&mul	(&DWP($r1,"esp"));		# h1*r1
+	&add	("edi","eax");
+	&mov	("eax","ecx");			# h2
+	&adc	("esi","edx");
+	&mul	(&DWP($r0,"esp"));		# h2*r0
+	&add	("edi","eax");
+	&mov	("eax",&DWP($h3,"esp"));
+	&adc	("esi","edx");
+	&mul	(&DWP($s3,"esp"));		# h3*s3
+	&add	("edi","eax");
+	&mov	("eax",&DWP($h4,"esp"));
+	&adc	("esi","edx");
+	&imul	("eax",&DWP($s2,"esp"));	# h4*s2
+	&add	("edi","eax");
+	 &mov	("eax",&DWP($h0,"esp"));
+	&adc	("esi",0);
+
+	&mul	(&DWP($r3,"esp"));		# h0*r3
+	 &mov	(&DWP($d2,"esp"),"edi");
+	&xor	("edi","edi");
+	&add	("esi","eax");
+	&mov	("eax","ebx");			# h1
+	&adc	("edi","edx");
+	&mul	(&DWP($r2,"esp"));		# h1*r2
+	&add	("esi","eax");
+	&mov	("eax","ecx");			# h2
+	&adc	("edi","edx");
+	&mul	(&DWP($r1,"esp"));		# h2*r1
+	&add	("esi","eax");
+	&mov	("eax",&DWP($h3,"esp"));
+	&adc	("edi","edx");
+	&mul	(&DWP($r0,"esp"));		# h3*r0
+	&add	("esi","eax");
+	 &mov	("ecx",&DWP($h4,"esp"));
+	&adc	("edi","edx");
+
+	&mov	("edx","ecx");
+	&imul	("ecx",&DWP($s3,"esp"));	# h4*s3
+	&add	("esi","ecx");
+	 &mov	("eax",&DWP($d0,"esp"));
+	&adc	("edi",0);
+
+	&imul	("edx",&DWP($r0,"esp"));	# h4*r0
+	&add	("edx","edi");
+
+	&mov	("ebx",&DWP($d1,"esp"));
+	&mov	("ecx",&DWP($d2,"esp"));
+
+	&mov	("edi","edx");			# last reduction step
+	&shr	("edx",2);
+	&and	("edi",3);
+	&lea	("edx",&DWP(0,"edx","edx",4));	# *5
+	&add	("eax","edx");
+	&adc	("ebx",0);
+	&adc	("ecx",0);
+	&adc	("esi",0);
+
+	&cmp	("ebp",&wparam(2));		# done yet?
+	&jne	(&label("loop"));
+
+	&mov	("edx",&wparam(0));		# ctx
+	&stack_pop(16);
+	&mov	(&DWP(4*0,"edx"),"eax");	# store hash value
+	&mov	(&DWP(4*1,"edx"),"ebx");
+	&mov	(&DWP(4*2,"edx"),"ecx");
+	&mov	(&DWP(4*3,"edx"),"esi");
+	&mov	(&DWP(4*4,"edx"),"edi");
+&set_label("nodata");
+&function_end("poly1305_blocks");
+
+&function_begin("poly1305_emit");
+	&mov	("ebp",&wparam(0));		# context
+&set_label("enter_emit");
+	&mov	("edi",&wparam(1));		# output
+	&mov	("eax",&DWP(4*0,"ebp"));	# load hash value
+	&mov	("ebx",&DWP(4*1,"ebp"));
+	&mov	("ecx",&DWP(4*2,"ebp"));
+	&mov	("edx",&DWP(4*3,"ebp"));
+	&mov	("esi",&DWP(4*4,"ebp"));
+
+	&add	("eax",5);			# compare to modulus
+	&adc	("ebx",0);
+	&adc	("ecx",0);
+	&adc	("edx",0);
+	&adc	("esi",0);
+	&shr	("esi",2);			# did it carry/borrow?
+	&neg	("esi");			# do we choose hash-modulus?
+
+	&and	("eax","esi");
+	&and	("ebx","esi");
+	&and	("ecx","esi");
+	&and	("edx","esi");
+	&mov	(&DWP(4*0,"edi"),"eax");
+	&mov	(&DWP(4*1,"edi"),"ebx");
+	&mov	(&DWP(4*2,"edi"),"ecx");
+	&mov	(&DWP(4*3,"edi"),"edx");
+
+	&not	("esi");			# or original hash value?
+	&mov	("eax",&DWP(4*0,"ebp"));
+	&mov	("ebx",&DWP(4*1,"ebp"));
+	&mov	("ecx",&DWP(4*2,"ebp"));
+	&mov	("edx",&DWP(4*3,"ebp"));
+	&mov	("ebp",&wparam(2));
+	&and	("eax","esi");
+	&and	("ebx","esi");
+	&and	("ecx","esi");
+	&and	("edx","esi");
+	&or	("eax",&DWP(4*0,"edi"));
+	&or	("ebx",&DWP(4*1,"edi"));
+	&or	("ecx",&DWP(4*2,"edi"));
+	&or	("edx",&DWP(4*3,"edi"));
+
+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate key
+	&adc	("ebx",&DWP(4*1,"ebp"));
+	&adc	("ecx",&DWP(4*2,"ebp"));
+	&adc	("edx",&DWP(4*3,"ebp"));
+
+	&mov	(&DWP(4*0,"edi"),"eax");
+	&mov	(&DWP(4*1,"edi"),"ebx");
+	&mov	(&DWP(4*2,"edi"),"ecx");
+	&mov	(&DWP(4*3,"edi"),"edx");
+&function_end("poly1305_emit");
+
+if ($sse2) {
+########################################################################
+# Layout of opaque area is following.
+#
+#	unsigned __int32 h[5];		# current hash value base 2^26
+#	unsigned __int32 is_base2_26;
+#	unsigned __int32 r[4];		# key value base 2^32
+#	unsigned __int32 pad[2];
+#	struct { unsigned __int32 r^4, r^3, r^2, r^1; } r[9];
+#
+# where r^n are base 2^26 digits of degrees of multiplier key. There are
+# 5 digits, but last four are interleaved with multiples of 5, totalling
+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
+
+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("xmm$_",(0..7));
+my $MASK=$T2;	# borrow and keep in mind
+
+&align	(32);
+&function_begin_B("_poly1305_init_sse2");
+	&movdqu		($D4,&QWP(4*6,"edi"));		# key base 2^32
+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
+	&mov		("ebp","esp");
+	&sub		("esp",16*(9+5));
+	&and		("esp",-16);
+
+	#&pand		($D4,&QWP(96,"ebx"));		# magic mask
+	&movq		($MASK,&QWP(64,"ebx"));
+
+	&movdqa		($D0,$D4);
+	&movdqa		($D1,$D4);
+	&movdqa		($D2,$D4);
+
+	&pand		($D0,$MASK);			# -> base 2^26
+	&psrlq		($D1,26);
+	&psrldq		($D2,6);
+	&pand		($D1,$MASK);
+	&movdqa		($D3,$D2);
+	&psrlq		($D2,4)
+	&psrlq		($D3,30);
+	&pand		($D2,$MASK);
+	&pand		($D3,$MASK);
+	&psrldq		($D4,13);
+
+	&lea		("edx",&DWP(16*9,"esp"));	# size optimization
+	&mov		("ecx",2);
+&set_label("square");
+	&movdqa		(&QWP(16*0,"esp"),$D0);
+	&movdqa		(&QWP(16*1,"esp"),$D1);
+	&movdqa		(&QWP(16*2,"esp"),$D2);
+	&movdqa		(&QWP(16*3,"esp"),$D3);
+	&movdqa		(&QWP(16*4,"esp"),$D4);
+
+	&movdqa		($T1,$D1);
+	&movdqa		($T0,$D2);
+	&pslld		($T1,2);
+	&pslld		($T0,2);
+	&paddd		($T1,$D1);			# *5
+	&paddd		($T0,$D2);			# *5
+	&movdqa		(&QWP(16*5,"esp"),$T1);
+	&movdqa		(&QWP(16*6,"esp"),$T0);
+	&movdqa		($T1,$D3);
+	&movdqa		($T0,$D4);
+	&pslld		($T1,2);
+	&pslld		($T0,2);
+	&paddd		($T1,$D3);			# *5
+	&paddd		($T0,$D4);			# *5
+	&movdqa		(&QWP(16*7,"esp"),$T1);
+	&movdqa		(&QWP(16*8,"esp"),$T0);
+
+	&pshufd		($T1,$D0,0b01000100);
+	&movdqa		($T0,$D1);
+	&pshufd		($D1,$D1,0b01000100);
+	&pshufd		($D2,$D2,0b01000100);
+	&pshufd		($D3,$D3,0b01000100);
+	&pshufd		($D4,$D4,0b01000100);
+	&movdqa		(&QWP(16*0,"edx"),$T1);
+	&movdqa		(&QWP(16*1,"edx"),$D1);
+	&movdqa		(&QWP(16*2,"edx"),$D2);
+	&movdqa		(&QWP(16*3,"edx"),$D3);
+	&movdqa		(&QWP(16*4,"edx"),$D4);
+
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	&pmuludq	($D4,$D0);			# h4*r0
+	&pmuludq	($D3,$D0);			# h3*r0
+	&pmuludq	($D2,$D0);			# h2*r0
+	&pmuludq	($D1,$D0);			# h1*r0
+	&pmuludq	($D0,$T1);			# h0*r0
+
+sub pmuladd {
+my $load = shift;
+my $base = shift; $base = "esp" if (!defined($base));
+
+	################################################################
+	# As for choice to "rotate" $T0-$T2 in order to move paddq
+	# past next multiplication. While it makes code harder to read
+	# and doesn't have significant effect on most processors, it
+	# makes a lot of difference on Atom, up to 30% improvement.
+
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&QWP(16*3,$base));		# r1*h3
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&QWP(16*2,$base));		# r1*h2
+	&paddq		($D4,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&QWP(16*1,$base));		# r1*h1
+	&paddq		($D3,$T1);
+	&$load		($T1,5);			# s1
+	&pmuludq	($T0,&QWP(16*0,$base));		# r1*h0
+	&paddq		($D2,$T2);
+	&pmuludq	($T1,&QWP(16*4,$base));		# s1*h4
+	 &$load		($T2,2);			# r2^n
+	&paddq		($D1,$T0);
+
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&QWP(16*2,$base));		# r2*h2
+	 &paddq		($D0,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&QWP(16*1,$base));		# r2*h1
+	&paddq		($D4,$T2);
+	&$load		($T2,6);			# s2^n
+	&pmuludq	($T1,&QWP(16*0,$base));		# r2*h0
+	&paddq		($D3,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&QWP(16*4,$base));		# s2*h4
+	&paddq		($D2,$T1);
+	&pmuludq	($T0,&QWP(16*3,$base));		# s2*h3
+	 &$load		($T1,3);			# r3^n
+	&paddq		($D1,$T2);
+
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&QWP(16*1,$base));		# r3*h1
+	 &paddq		($D0,$T0);
+	&$load		($T0,7);			# s3^n
+	&pmuludq	($T2,&QWP(16*0,$base));		# r3*h0
+	&paddq		($D4,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&QWP(16*4,$base));		# s3*h4
+	&paddq		($D3,$T2);
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&QWP(16*3,$base));		# s3*h3
+	&paddq		($D2,$T0);
+	&pmuludq	($T2,&QWP(16*2,$base));		# s3*h2
+	 &$load		($T0,4);			# r4^n
+	&paddq		($D1,$T1);
+
+	&$load		($T1,8);			# s4^n
+	&pmuludq	($T0,&QWP(16*0,$base));		# r4*h0
+	 &paddq		($D0,$T2);
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&QWP(16*4,$base));		# s4*h4
+	&paddq		($D4,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&QWP(16*1,$base));		# s4*h1
+	&paddq		($D3,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&QWP(16*2,$base));		# s4*h2
+	&paddq		($D0,$T2);
+	&pmuludq	($T1,&QWP(16*3,$base));		# s4*h3
+	 &movdqa	($MASK,&QWP(64,"ebx"));
+	&paddq		($D1,$T0);
+	&paddq		($D2,$T1);
+}
+	&pmuladd	(sub {	my ($reg,$i)=@_;
+				&movdqa ($reg,&QWP(16*$i,"esp"));
+			     },"edx");
+
+sub lazy_reduction {
+my $extra = shift;
+my $paddx = defined($extra) ? paddq : paddd;
+
+	################################################################
+	# lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+	# and P. Schwabe
+
+	 &movdqa	($T0,$D3);
+	 &pand		($D3,$MASK);
+	 &psrlq		($T0,26);
+	 &$extra	()				if (defined($extra));
+	 &paddq		($T0,$D4);			# h3 -> h4
+	&movdqa		($T1,$D0);
+	&pand		($D0,$MASK);
+	&psrlq		($T1,26);
+	 &movdqa	($D4,$T0);
+	&paddq		($T1,$D1);			# h0 -> h1
+	 &psrlq		($T0,26);
+	 &pand		($D4,$MASK);
+	&movdqa		($D1,$T1);
+	&psrlq		($T1,26);
+	 &paddd		($D0,$T0);			# favour paddd when
+							# possible, because
+							# paddq is "broken"
+							# on Atom
+	 &psllq		($T0,2);
+	&paddq		($T1,$D2);			# h1 -> h2
+	 &$paddx	($T0,$D0);			# h4 -> h0
+	&pand		($D1,$MASK);
+	&movdqa		($D2,$T1);
+	&psrlq		($T1,26);
+	&pand		($D2,$MASK);
+	&paddd		($T1,$D3);			# h2 -> h3
+	 &movdqa	($D0,$T0);
+	 &psrlq		($T0,26);
+	&movdqa		($D3,$T1);
+	&psrlq		($T1,26);
+	 &pand		($D0,$MASK);
+	 &paddd		($D1,$T0);			# h0 -> h1
+	&pand		($D3,$MASK);
+	&paddd		($D4,$T1);			# h3 -> h4
+}
+	&lazy_reduction	();
+
+	&dec		("ecx");
+	&jz		(&label("square_break"));
+
+	&punpcklqdq	($D0,&QWP(16*0,"esp"));		# 0:r^1:0:r^2
+	&punpcklqdq	($D1,&QWP(16*1,"esp"));
+	&punpcklqdq	($D2,&QWP(16*2,"esp"));
+	&punpcklqdq	($D3,&QWP(16*3,"esp"));
+	&punpcklqdq	($D4,&QWP(16*4,"esp"));
+	&jmp		(&label("square"));
+
+&set_label("square_break");
+	&psllq		($D0,32);			# -> r^3:0:r^4:0
+	&psllq		($D1,32);
+	&psllq		($D2,32);
+	&psllq		($D3,32);
+	&psllq		($D4,32);
+	&por		($D0,&QWP(16*0,"esp"));		# r^3:r^1:r^4:r^2
+	&por		($D1,&QWP(16*1,"esp"));
+	&por		($D2,&QWP(16*2,"esp"));
+	&por		($D3,&QWP(16*3,"esp"));
+	&por		($D4,&QWP(16*4,"esp"));
+
+	&pshufd		($D0,$D0,0b10001101);		# -> r^1:r^2:r^3:r^4
+	&pshufd		($D1,$D1,0b10001101);
+	&pshufd		($D2,$D2,0b10001101);
+	&pshufd		($D3,$D3,0b10001101);
+	&pshufd		($D4,$D4,0b10001101);
+
+	&movdqu		(&QWP(16*0,"edi"),$D0);		# save the table
+	&movdqu		(&QWP(16*1,"edi"),$D1);
+	&movdqu		(&QWP(16*2,"edi"),$D2);
+	&movdqu		(&QWP(16*3,"edi"),$D3);
+	&movdqu		(&QWP(16*4,"edi"),$D4);
+
+	&movdqa		($T1,$D1);
+	&movdqa		($T0,$D2);
+	&pslld		($T1,2);
+	&pslld		($T0,2);
+	&paddd		($T1,$D1);			# *5
+	&paddd		($T0,$D2);			# *5
+	&movdqu		(&QWP(16*5,"edi"),$T1);
+	&movdqu		(&QWP(16*6,"edi"),$T0);
+	&movdqa		($T1,$D3);
+	&movdqa		($T0,$D4);
+	&pslld		($T1,2);
+	&pslld		($T0,2);
+	&paddd		($T1,$D3);			# *5
+	&paddd		($T0,$D4);			# *5
+	&movdqu		(&QWP(16*7,"edi"),$T1);
+	&movdqu		(&QWP(16*8,"edi"),$T0);
+
+	&mov		("esp","ebp");
+	&lea		("edi",&DWP(-16*3,"edi"));	# size de-optimization
+	&ret		();
+&function_end_B("_poly1305_init_sse2");
+
+&align	(32);
+&function_begin("_poly1305_blocks_sse2");
+	&mov	("edi",&wparam(0));			# ctx
+	&mov	("esi",&wparam(1));			# inp
+	&mov	("ecx",&wparam(2));			# len
+
+	&mov	("eax",&DWP(4*5,"edi"));		# is_base2_26
+	&and	("ecx",-16);
+	&jz	(&label("nodata"));
+	&cmp	("ecx",64);
+	&jae	(&label("enter_sse2"));
+	&test	("eax","eax");				# is_base2_26?
+	&jz	(&label("enter_blocks"));
+
+&set_label("enter_sse2",16);
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop("ebx");
+	&lea	("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
+
+	&test	("eax","eax");				# is_base2_26?
+	&jnz	(&label("base2_26"));
+
+	&call	("_poly1305_init_sse2");
+
+	################################################# base 2^32 -> base 2^26
+	&mov	("eax",&DWP(0,"edi"));
+	&mov	("ecx",&DWP(3,"edi"));
+	&mov	("edx",&DWP(6,"edi"));
+	&mov	("esi",&DWP(9,"edi"));
+	&mov	("ebp",&DWP(13,"edi"));
+	&mov	(&DWP(4*5,"edi"),1);			# is_base2_26
+
+	&shr	("ecx",2);
+	&and	("eax",0x3ffffff);
+	&shr	("edx",4);
+	&and	("ecx",0x3ffffff);
+	&shr	("esi",6);
+	&and	("edx",0x3ffffff);
+
+	&movd	($D0,"eax");
+	&movd	($D1,"ecx");
+	&movd	($D2,"edx");
+	&movd	($D3,"esi");
+	&movd	($D4,"ebp");
+
+	&mov	("esi",&wparam(1));			# [reload] inp
+	&mov	("ecx",&wparam(2));			# [reload] len
+	&jmp	(&label("base2_32"));
+
+&set_label("base2_26",16);
+	&movd	($D0,&DWP(4*0,"edi"));			# load hash value
+	&movd	($D1,&DWP(4*1,"edi"));
+	&movd	($D2,&DWP(4*2,"edi"));
+	&movd	($D3,&DWP(4*3,"edi"));
+	&movd	($D4,&DWP(4*4,"edi"));
+	&movdqa	($MASK,&QWP(64,"ebx"));
+
+&set_label("base2_32");
+	&mov	("eax",&wparam(3));			# padbit
+	&mov	("ebp","esp");
+
+	&sub	("esp",16*(5+5+5+9+9));
+	&and	("esp",-16);
+
+	&lea	("edi",&DWP(16*3,"edi"));		# size optimization
+	&shl	("eax",24);				# padbit
+
+	&test	("ecx",31);
+	&jz	(&label("even"));
+
+	################################################################
+	# process single block, with SSE2, because it's still faster
+	# even though half of result is discarded
+
+	&movdqu		($T1,&QWP(0,"esi"));		# input
+	&lea		("esi",&DWP(16,"esi"));
+
+	&movdqa		($T0,$T1);			# -> base 2^26 ...
+	&pand		($T1,$MASK);
+	&paddd		($D0,$T1);			# ... and accumuate
+
+	&movdqa		($T1,$T0);
+	&psrlq		($T0,26);
+	&psrldq		($T1,6);
+	&pand		($T0,$MASK);
+	&paddd		($D1,$T0);
+
+	&movdqa		($T0,$T1);
+	&psrlq		($T1,4);
+	&pand		($T1,$MASK);
+	&paddd		($D2,$T1);
+
+	&movdqa		($T1,$T0);
+	&psrlq		($T0,30);
+	&pand		($T0,$MASK);
+	&psrldq		($T1,7);
+	&paddd		($D3,$T0);
+
+	&movd		($T0,"eax");			# padbit
+	&paddd		($D4,$T1);
+	 &movd		($T1,&DWP(16*0+12,"edi"));	# r0
+	&paddd		($D4,$T0);
+
+	&movdqa		(&QWP(16*0,"esp"),$D0);
+	&movdqa		(&QWP(16*1,"esp"),$D1);
+	&movdqa		(&QWP(16*2,"esp"),$D2);
+	&movdqa		(&QWP(16*3,"esp"),$D3);
+	&movdqa		(&QWP(16*4,"esp"),$D4);
+
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	&pmuludq	($D0,$T1);			# h4*r0
+	&pmuludq	($D1,$T1);			# h3*r0
+	&pmuludq	($D2,$T1);			# h2*r0
+	 &movd		($T0,&DWP(16*1+12,"edi"));	# r1
+	&pmuludq	($D3,$T1);			# h1*r0
+	&pmuludq	($D4,$T1);			# h0*r0
+
+	&pmuladd	(sub {	my ($reg,$i)=@_;
+				&movd ($reg,&DWP(16*$i+12,"edi"));
+			     });
+
+	&lazy_reduction	();
+
+	&sub		("ecx",16);
+	&jz		(&label("done"));
+
+&set_label("even");
+	&lea		("edx",&DWP(16*(5+5+5+9),"esp"));# size optimization
+	&lea		("eax",&DWP(-16*2,"esi"));
+	&sub		("ecx",64);
+
+	################################################################
+	# expand and copy pre-calculated table to stack
+
+	&movdqu		($T0,&QWP(16*0,"edi"));		# r^1:r^2:r^3:r^4
+	&pshufd		($T1,$T0,0b01000100);		# duplicate r^3:r^4
+	&cmovb		("esi","eax");
+	&pshufd		($T0,$T0,0b11101110);		# duplicate r^1:r^2
+	&movdqa		(&QWP(16*0,"edx"),$T1);
+	&lea		("eax",&DWP(16*10,"esp"));
+	&movdqu		($T1,&QWP(16*1,"edi"));
+	&movdqa		(&QWP(16*(0-9),"edx"),$T0);
+	&pshufd		($T0,$T1,0b01000100);
+	&pshufd		($T1,$T1,0b11101110);
+	&movdqa		(&QWP(16*1,"edx"),$T0);
+	&movdqu		($T0,&QWP(16*2,"edi"));
+	&movdqa		(&QWP(16*(1-9),"edx"),$T1);
+	&pshufd		($T1,$T0,0b01000100);
+	&pshufd		($T0,$T0,0b11101110);
+	&movdqa		(&QWP(16*2,"edx"),$T1);
+	&movdqu		($T1,&QWP(16*3,"edi"));
+	&movdqa		(&QWP(16*(2-9),"edx"),$T0);
+	&pshufd		($T0,$T1,0b01000100);
+	&pshufd		($T1,$T1,0b11101110);
+	&movdqa		(&QWP(16*3,"edx"),$T0);
+	&movdqu		($T0,&QWP(16*4,"edi"));
+	&movdqa		(&QWP(16*(3-9),"edx"),$T1);
+	&pshufd		($T1,$T0,0b01000100);
+	&pshufd		($T0,$T0,0b11101110);
+	&movdqa		(&QWP(16*4,"edx"),$T1);
+	&movdqu		($T1,&QWP(16*5,"edi"));
+	&movdqa		(&QWP(16*(4-9),"edx"),$T0);
+	&pshufd		($T0,$T1,0b01000100);
+	&pshufd		($T1,$T1,0b11101110);
+	&movdqa		(&QWP(16*5,"edx"),$T0);
+	&movdqu		($T0,&QWP(16*6,"edi"));
+	&movdqa		(&QWP(16*(5-9),"edx"),$T1);
+	&pshufd		($T1,$T0,0b01000100);
+	&pshufd		($T0,$T0,0b11101110);
+	&movdqa		(&QWP(16*6,"edx"),$T1);
+	&movdqu		($T1,&QWP(16*7,"edi"));
+	&movdqa		(&QWP(16*(6-9),"edx"),$T0);
+	&pshufd		($T0,$T1,0b01000100);
+	&pshufd		($T1,$T1,0b11101110);
+	&movdqa		(&QWP(16*7,"edx"),$T0);
+	&movdqu		($T0,&QWP(16*8,"edi"));
+	&movdqa		(&QWP(16*(7-9),"edx"),$T1);
+	&pshufd		($T1,$T0,0b01000100);
+	&pshufd		($T0,$T0,0b11101110);
+	&movdqa		(&QWP(16*8,"edx"),$T1);
+	&movdqa		(&QWP(16*(8-9),"edx"),$T0);
+
+sub load_input {
+my ($inpbase,$offbase)=@_;
+
+	&movdqu		($T0,&QWP($inpbase+0,"esi"));	# load input
+	&movdqu		($T1,&QWP($inpbase+16,"esi"));
+	&lea		("esi",&DWP(16*2,"esi"));
+
+	&movdqa		(&QWP($offbase+16*2,"esp"),$D2);
+	&movdqa		(&QWP($offbase+16*3,"esp"),$D3);
+	&movdqa		(&QWP($offbase+16*4,"esp"),$D4);
+
+	&movdqa		($D2,$T0);			# splat input
+	&movdqa		($D3,$T1);
+	&psrldq		($D2,6);
+	&psrldq		($D3,6);
+	&movdqa		($D4,$T0);
+	&punpcklqdq	($D2,$D3);			# 2:3
+	&punpckhqdq	($D4,$T1);			# 4
+	&punpcklqdq	($T0,$T1);			# 0:1
+
+	&movdqa		($D3,$D2);
+	&psrlq		($D2,4);
+	&psrlq		($D3,30);
+	&movdqa		($T1,$T0);
+	&psrlq		($D4,40);			# 4
+	&psrlq		($T1,26);
+	&pand		($T0,$MASK);			# 0
+	&pand		($T1,$MASK);			# 1
+	&pand		($D2,$MASK);			# 2
+	&pand		($D3,$MASK);			# 3
+	&por		($D4,&QWP(0,"ebx"));		# padbit, yes, always
+
+	&movdqa		(&QWP($offbase+16*0,"esp"),$D0)	if ($offbase);
+	&movdqa		(&QWP($offbase+16*1,"esp"),$D1)	if ($offbase);
+}
+	&load_input	(16*2,16*5);
+
+	&jbe		(&label("skip_loop"));
+	&jmp		(&label("loop"));
+
+&set_label("loop",32);
+	################################################################
+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+	#   \___________________/
+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+	#   \___________________/ \____________________/
+	################################################################
+
+	&movdqa		($T2,&QWP(16*(0-9),"edx"));	# r0^2
+	&movdqa		(&QWP(16*1,"eax"),$T1);
+	&movdqa		(&QWP(16*2,"eax"),$D2);
+	&movdqa		(&QWP(16*3,"eax"),$D3);
+	&movdqa		(&QWP(16*4,"eax"),$D4);
+
+	################################################################
+	# d4 = h4*r0 + h0*r4   + h1*r3   + h2*r2   + h3*r1
+	# d3 = h3*r0 + h0*r3   + h1*r2   + h2*r1   + h4*5*r4
+	# d2 = h2*r0 + h0*r2   + h1*r1   + h3*5*r4 + h4*5*r3
+	# d1 = h1*r0 + h0*r1   + h2*5*r4 + h3*5*r3 + h4*5*r2
+	# d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+	&movdqa		($D1,$T0);
+	&pmuludq	($T0,$T2);			# h0*r0
+	&movdqa		($D0,$T1);
+	&pmuludq	($T1,$T2);			# h1*r0
+	&pmuludq	($D2,$T2);			# h2*r0
+	&pmuludq	($D3,$T2);			# h3*r0
+	&pmuludq	($D4,$T2);			# h4*r0
+
+sub pmuladd_alt {
+my $addr = shift;
+
+	&pmuludq	($D0,&$addr(8));		# h1*s4
+	&movdqa		($T2,$D1);
+	&pmuludq	($D1,&$addr(1));		# h0*r1
+	&paddq		($D0,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&$addr(2));		# h0*r2
+	&paddq		($D1,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&$addr(3));		# h0*r3
+	&paddq		($D2,$T2);
+	 &movdqa	($T2,&QWP(16*1,"eax"));		# pull h1
+	&pmuludq	($T1,&$addr(4));		# h0*r4
+	&paddq		($D3,$T0);
+
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&$addr(1));		# h1*r1
+	 &paddq		($D4,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&$addr(2));		# h1*r2
+	&paddq		($D2,$T2);
+	&movdqa		($T2,&QWP(16*2,"eax"));		# pull h2
+	&pmuludq	($T1,&$addr(3));		# h1*r3
+	&paddq		($D3,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&$addr(7));		# h2*s3
+	&paddq		($D4,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&$addr(8));		# h2*s4
+	&paddq		($D0,$T2);
+
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&$addr(1));		# h2*r1
+	 &paddq		($D1,$T0);
+	&movdqa		($T0,&QWP(16*3,"eax"));		# pull h3
+	&pmuludq	($T2,&$addr(2));		# h2*r2
+	&paddq		($D3,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&$addr(6));		# h3*s2
+	&paddq		($D4,$T2);
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&$addr(7));		# h3*s3
+	&paddq		($D0,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&$addr(8));		# h3*s4
+	&paddq		($D1,$T1);
+
+	&movdqa		($T1,&QWP(16*4,"eax"));		# pull h4
+	&pmuludq	($T0,&$addr(1));		# h3*r1
+	 &paddq		($D2,$T2);
+	&movdqa		($T2,$T1);
+	&pmuludq	($T1,&$addr(8));		# h4*s4
+	&paddq		($D4,$T0);
+	&movdqa		($T0,$T2);
+	&pmuludq	($T2,&$addr(5));		# h4*s1
+	&paddq		($D3,$T1);
+	&movdqa		($T1,$T0);
+	&pmuludq	($T0,&$addr(6));		# h4*s2
+	&paddq		($D0,$T2);
+	 &movdqa	($MASK,&QWP(64,"ebx"));
+	&pmuludq	($T1,&$addr(7));		# h4*s3
+	&paddq		($D1,$T0);
+	&paddq		($D2,$T1);
+}
+	&pmuladd_alt	(sub {	my $i=shift; &QWP(16*($i-9),"edx");	});
+
+	&load_input	(-16*2,0);
+	&lea		("eax",&DWP(-16*2,"esi"));
+	&sub		("ecx",64);
+
+	&paddd		($T0,&QWP(16*(5+0),"esp"));	# add hash value
+	&paddd		($T1,&QWP(16*(5+1),"esp"));
+	&paddd		($D2,&QWP(16*(5+2),"esp"));
+	&paddd		($D3,&QWP(16*(5+3),"esp"));
+	&paddd		($D4,&QWP(16*(5+4),"esp"));
+
+	&cmovb		("esi","eax");
+	&lea		("eax",&DWP(16*10,"esp"));
+
+	&movdqa		($T2,&QWP(16*0,"edx"));		# r0^4
+	&movdqa		(&QWP(16*1,"esp"),$D1);
+	&movdqa		(&QWP(16*1,"eax"),$T1);
+	&movdqa		(&QWP(16*2,"eax"),$D2);
+	&movdqa		(&QWP(16*3,"eax"),$D3);
+	&movdqa		(&QWP(16*4,"eax"),$D4);
+
+	################################################################
+	# d4 += h4*r0 + h0*r4   + h1*r3   + h2*r2   + h3*r1
+	# d3 += h3*r0 + h0*r3   + h1*r2   + h2*r1   + h4*5*r4
+	# d2 += h2*r0 + h0*r2   + h1*r1   + h3*5*r4 + h4*5*r3
+	# d1 += h1*r0 + h0*r1   + h2*5*r4 + h3*5*r3 + h4*5*r2
+	# d0 += h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+	&movdqa		($D1,$T0);
+	&pmuludq	($T0,$T2);			# h0*r0
+	&paddq		($T0,$D0);
+	&movdqa		($D0,$T1);
+	&pmuludq	($T1,$T2);			# h1*r0
+	&pmuludq	($D2,$T2);			# h2*r0
+	&pmuludq	($D3,$T2);			# h3*r0
+	&pmuludq	($D4,$T2);			# h4*r0
+
+	&paddq		($T1,&QWP(16*1,"esp"));
+	&paddq		($D2,&QWP(16*2,"esp"));
+	&paddq		($D3,&QWP(16*3,"esp"));
+	&paddq		($D4,&QWP(16*4,"esp"));
+
+	&pmuladd_alt	(sub {	my $i=shift; &QWP(16*$i,"edx");	});
+
+	&lazy_reduction	();
+
+	&load_input	(16*2,16*5);
+
+	&ja		(&label("loop"));
+
+&set_label("skip_loop");
+	################################################################
+	# multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+	 &pshufd	($T2,&QWP(16*(0-9),"edx"),0x10);# r0^n
+	&add		("ecx",32);
+	&jnz		(&label("long_tail"));
+
+	&paddd		($T0,$D0);			# add hash value
+	&paddd		($T1,$D1);
+	&paddd		($D2,&QWP(16*7,"esp"));
+	&paddd		($D3,&QWP(16*8,"esp"));
+	&paddd		($D4,&QWP(16*9,"esp"));
+
+&set_label("long_tail");
+
+	&movdqa		(&QWP(16*0,"eax"),$T0);
+	&movdqa		(&QWP(16*1,"eax"),$T1);
+	&movdqa		(&QWP(16*2,"eax"),$D2);
+	&movdqa		(&QWP(16*3,"eax"),$D3);
+	&movdqa		(&QWP(16*4,"eax"),$D4);
+
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	&pmuludq	($T0,$T2);			# h0*r0
+	&pmuludq	($T1,$T2);			# h1*r0
+	&pmuludq	($D2,$T2);			# h2*r0
+	&movdqa		($D0,$T0);
+	 &pshufd	($T0,&QWP(16*(1-9),"edx"),0x10);# r1^n
+	&pmuludq	($D3,$T2);			# h3*r0
+	&movdqa		($D1,$T1);
+	&pmuludq	($D4,$T2);			# h4*r0
+
+	&pmuladd	(sub {	my ($reg,$i)=@_;
+				&pshufd ($reg,&QWP(16*($i-9),"edx"),0x10);
+			     },"eax");
+
+	&jz		(&label("short_tail"));
+
+	&load_input	(-16*2,0);
+
+	 &pshufd	($T2,&QWP(16*0,"edx"),0x10);	# r0^n
+	&paddd		($T0,&QWP(16*5,"esp"));		# add hash value
+	&paddd		($T1,&QWP(16*6,"esp"));
+	&paddd		($D2,&QWP(16*7,"esp"));
+	&paddd		($D3,&QWP(16*8,"esp"));
+	&paddd		($D4,&QWP(16*9,"esp"));
+
+	################################################################
+	# multiply inp[0:1] by r^4:r^3 and accumulate
+
+	&movdqa		(&QWP(16*0,"esp"),$T0);
+	&pmuludq	($T0,$T2);			# h0*r0
+	&movdqa		(&QWP(16*1,"esp"),$T1);
+	&pmuludq	($T1,$T2);			# h1*r0
+	&paddq		($D0,$T0);
+	&movdqa		($T0,$D2);
+	&pmuludq	($D2,$T2);			# h2*r0
+	&paddq		($D1,$T1);
+	&movdqa		($T1,$D3);
+	&pmuludq	($D3,$T2);			# h3*r0
+	&paddq		($D2,&QWP(16*2,"esp"));
+	&movdqa		(&QWP(16*2,"esp"),$T0);
+	 &pshufd	($T0,&QWP(16*1,"edx"),0x10);	# r1^n
+	&paddq		($D3,&QWP(16*3,"esp"));
+	&movdqa		(&QWP(16*3,"esp"),$T1);
+	&movdqa		($T1,$D4);
+	&pmuludq	($D4,$T2);			# h4*r0
+	&paddq		($D4,&QWP(16*4,"esp"));
+	&movdqa		(&QWP(16*4,"esp"),$T1);
+
+	&pmuladd	(sub {	my ($reg,$i)=@_;
+				&pshufd ($reg,&QWP(16*$i,"edx"),0x10);
+			     });
+
+&set_label("short_tail");
+
+	################################################################
+	# horizontal addition
+
+	&pshufd		($T1,$D4,0b01001110);
+	&pshufd		($T0,$D3,0b01001110);
+	&paddq		($D4,$T1);
+	&paddq		($D3,$T0);
+	&pshufd		($T1,$D0,0b01001110);
+	&pshufd		($T0,$D1,0b01001110);
+	&paddq		($D0,$T1);
+	&paddq		($D1,$T0);
+	&pshufd		($T1,$D2,0b01001110);
+	#&paddq		($D2,$T1);
+
+	&lazy_reduction	(sub { &paddq ($D2,$T1) });
+
+&set_label("done");
+	&movd		(&DWP(-16*3+4*0,"edi"),$D0);	# store hash value
+	&movd		(&DWP(-16*3+4*1,"edi"),$D1);
+	&movd		(&DWP(-16*3+4*2,"edi"),$D2);
+	&movd		(&DWP(-16*3+4*3,"edi"),$D3);
+	&movd		(&DWP(-16*3+4*4,"edi"),$D4);
+	&mov	("esp","ebp");
+&set_label("nodata");
+&function_end("_poly1305_blocks_sse2");
+
+&align	(32);
+&function_begin("_poly1305_emit_sse2");
+	&mov	("ebp",&wparam(0));		# context
+
+	&cmp	(&DWP(4*5,"ebp"),0);		# is_base2_26?
+	&je	(&label("enter_emit"));
+
+	&mov	("eax",&DWP(4*0,"ebp"));	# load hash value
+	&mov	("edi",&DWP(4*1,"ebp"));
+	&mov	("ecx",&DWP(4*2,"ebp"));
+	&mov	("edx",&DWP(4*3,"ebp"));
+	&mov	("esi",&DWP(4*4,"ebp"));
+
+	&mov	("ebx","edi");			# base 2^26 -> base 2^32
+	&shl	("edi",26);
+	&shr	("ebx",6);
+	&add	("eax","edi");
+	&mov	("edi","ecx");
+	&adc	("ebx",0);
+
+	&shl	("edi",20);
+	&shr	("ecx",12);
+	&add	("ebx","edi");
+	&mov	("edi","edx");
+	&adc	("ecx",0);
+
+	&shl	("edi",14);
+	&shr	("edx",18);
+	&add	("ecx","edi");
+	&mov	("edi","esi");
+	&adc	("edx",0);
+
+	&shl	("edi",8);
+	&shr	("esi",24);
+	&add	("edx","edi");
+	&adc	("esi",0);			# can be partially reduced
+
+	&mov	("edi","esi");			# final reduction
+	&and	("esi",3);
+	&shr	("edi",2);
+	&lea	("ebp",&DWP(0,"edi","edi",4));	# *5
+	 &mov	("edi",&wparam(1));		# output
+	add	("eax","ebp");
+	 &mov	("ebp",&wparam(2));		# key
+	adc	("ebx",0);
+	adc	("ecx",0);
+	adc	("edx",0);
+
+	&movd	($D0,"eax");			# offload original hash value
+	&add	("eax",5);			# compare to modulus
+	&movd	($D1,"ebx");
+	&adc	("ebx",0);
+	&movd	($D2,"ecx");
+	&adc	("ecx",0);
+	&movd	($D3,"edx");
+	&adc	("edx",0);
+	&adc	("esi",0);
+	&shr	("esi",2);			# did it carry/borrow?
+
+	&neg	("esi");			# do we choose (hash-modulus) ...
+	&and	("eax","esi");
+	&and	("ebx","esi");
+	&and	("ecx","esi");
+	&and	("edx","esi");
+	&mov	(&DWP(4*0,"edi"),"eax");
+	&movd	("eax",$D0);
+	&mov	(&DWP(4*1,"edi"),"ebx");
+	&movd	("ebx",$D1);
+	&mov	(&DWP(4*2,"edi"),"ecx");
+	&movd	("ecx",$D2);
+	&mov	(&DWP(4*3,"edi"),"edx");
+	&movd	("edx",$D3);
+
+	&not	("esi");			# ... or original hash value?
+	&and	("eax","esi");
+	&and	("ebx","esi");
+	&or	("eax",&DWP(4*0,"edi"));
+	&and	("ecx","esi");
+	&or	("ebx",&DWP(4*1,"edi"));
+	&and	("edx","esi");
+	&or	("ecx",&DWP(4*2,"edi"));
+	&or	("edx",&DWP(4*3,"edi"));
+
+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate key
+	&adc	("ebx",&DWP(4*1,"ebp"));
+	&mov	(&DWP(4*0,"edi"),"eax");
+	&adc	("ecx",&DWP(4*2,"ebp"));
+	&mov	(&DWP(4*1,"edi"),"ebx");
+	&adc	("edx",&DWP(4*3,"ebp"));
+	&mov	(&DWP(4*2,"edi"),"ecx");
+	&mov	(&DWP(4*3,"edi"),"edx");
+&function_end("_poly1305_emit_sse2");
+
+if ($avx>1) {
+########################################################################
+# Note that poly1305_init_avx2 operates on %xmm, I could have used
+# poly1305_init_sse2...
+
+&align	(32);
+&function_begin_B("_poly1305_init_avx2");
+	&vmovdqu	($D4,&QWP(4*6,"edi"));		# key base 2^32
+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
+	&mov		("ebp","esp");
+	&sub		("esp",16*(9+5));
+	&and		("esp",-16);
+
+	#&vpand		($D4,$D4,&QWP(96,"ebx"));	# magic mask
+	&vmovdqa	($MASK,&QWP(64,"ebx"));
+
+	&vpand		($D0,$D4,$MASK);		# -> base 2^26
+	&vpsrlq		($D1,$D4,26);
+	&vpsrldq	($D3,$D4,6);
+	&vpand		($D1,$D1,$MASK);
+	&vpsrlq		($D2,$D3,4)
+	&vpsrlq		($D3,$D3,30);
+	&vpand		($D2,$D2,$MASK);
+	&vpand		($D3,$D3,$MASK);
+	&vpsrldq	($D4,$D4,13);
+
+	&lea		("edx",&DWP(16*9,"esp"));	# size optimization
+	&mov		("ecx",2);
+&set_label("square");
+	&vmovdqa	(&QWP(16*0,"esp"),$D0);
+	&vmovdqa	(&QWP(16*1,"esp"),$D1);
+	&vmovdqa	(&QWP(16*2,"esp"),$D2);
+	&vmovdqa	(&QWP(16*3,"esp"),$D3);
+	&vmovdqa	(&QWP(16*4,"esp"),$D4);
+
+	&vpslld		($T1,$D1,2);
+	&vpslld		($T0,$D2,2);
+	&vpaddd		($T1,$T1,$D1);			# *5
+	&vpaddd		($T0,$T0,$D2);			# *5
+	&vmovdqa	(&QWP(16*5,"esp"),$T1);
+	&vmovdqa	(&QWP(16*6,"esp"),$T0);
+	&vpslld		($T1,$D3,2);
+	&vpslld		($T0,$D4,2);
+	&vpaddd		($T1,$T1,$D3);			# *5
+	&vpaddd		($T0,$T0,$D4);			# *5
+	&vmovdqa	(&QWP(16*7,"esp"),$T1);
+	&vmovdqa	(&QWP(16*8,"esp"),$T0);
+
+	&vpshufd	($T0,$D0,0b01000100);
+	&vmovdqa	($T1,$D1);
+	&vpshufd	($D1,$D1,0b01000100);
+	&vpshufd	($D2,$D2,0b01000100);
+	&vpshufd	($D3,$D3,0b01000100);
+	&vpshufd	($D4,$D4,0b01000100);
+	&vmovdqa	(&QWP(16*0,"edx"),$T0);
+	&vmovdqa	(&QWP(16*1,"edx"),$D1);
+	&vmovdqa	(&QWP(16*2,"edx"),$D2);
+	&vmovdqa	(&QWP(16*3,"edx"),$D3);
+	&vmovdqa	(&QWP(16*4,"edx"),$D4);
+
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	&vpmuludq	($D4,$D4,$D0);			# h4*r0
+	&vpmuludq	($D3,$D3,$D0);			# h3*r0
+	&vpmuludq	($D2,$D2,$D0);			# h2*r0
+	&vpmuludq	($D1,$D1,$D0);			# h1*r0
+	&vpmuludq	($D0,$T0,$D0);			# h0*r0
+
+	&vpmuludq	($T0,$T1,&QWP(16*3,"edx"));	# r1*h3
+	&vpaddq		($D4,$D4,$T0);
+	&vpmuludq	($T2,$T1,&QWP(16*2,"edx"));	# r1*h2
+	&vpaddq		($D3,$D3,$T2);
+	&vpmuludq	($T0,$T1,&QWP(16*1,"edx"));	# r1*h1
+	&vpaddq		($D2,$D2,$T0);
+	&vmovdqa	($T2,&QWP(16*5,"esp"));		# s1
+	&vpmuludq	($T1,$T1,&QWP(16*0,"edx"));	# r1*h0
+	&vpaddq		($D1,$D1,$T1);
+	 &vmovdqa	($T0,&QWP(16*2,"esp"));		# r2
+	&vpmuludq	($T2,$T2,&QWP(16*4,"edx"));	# s1*h4
+	&vpaddq		($D0,$D0,$T2);
+
+	&vpmuludq	($T1,$T0,&QWP(16*2,"edx"));	# r2*h2
+	&vpaddq		($D4,$D4,$T1);
+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# r2*h1
+	&vpaddq		($D3,$D3,$T2);
+	&vmovdqa	($T1,&QWP(16*6,"esp"));		# s2
+	&vpmuludq	($T0,$T0,&QWP(16*0,"edx"));	# r2*h0
+	&vpaddq		($D2,$D2,$T0);
+	&vpmuludq	($T2,$T1,&QWP(16*4,"edx"));	# s2*h4
+	&vpaddq		($D1,$D1,$T2);
+	 &vmovdqa	($T0,&QWP(16*3,"esp"));		# r3
+	&vpmuludq	($T1,$T1,&QWP(16*3,"edx"));	# s2*h3
+	&vpaddq		($D0,$D0,$T1);
+
+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# r3*h1
+	&vpaddq		($D4,$D4,$T2);
+	&vmovdqa	($T1,&QWP(16*7,"esp"));		# s3
+	&vpmuludq	($T0,$T0,&QWP(16*0,"edx"));	# r3*h0
+	&vpaddq		($D3,$D3,$T0);
+	&vpmuludq	($T2,$T1,&QWP(16*4,"edx"));	# s3*h4
+	&vpaddq		($D2,$D2,$T2);
+	&vpmuludq	($T0,$T1,&QWP(16*3,"edx"));	# s3*h3
+	&vpaddq		($D1,$D1,$T0);
+	 &vmovdqa	($T2,&QWP(16*4,"esp"));		# r4
+	&vpmuludq	($T1,$T1,&QWP(16*2,"edx"));	# s3*h2
+	&vpaddq		($D0,$D0,$T1);
+
+	&vmovdqa	($T0,&QWP(16*8,"esp"));		# s4
+	&vpmuludq	($T2,$T2,&QWP(16*0,"edx"));	# r4*h0
+	&vpaddq		($D4,$D4,$T2);
+	&vpmuludq	($T1,$T0,&QWP(16*4,"edx"));	# s4*h4
+	&vpaddq		($D3,$D3,$T1);
+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# s4*h1
+	&vpaddq		($D0,$D0,$T2);
+	&vpmuludq	($T1,$T0,&QWP(16*2,"edx"));	# s4*h2
+	&vpaddq		($D1,$D1,$T1);
+	 &vmovdqa	($MASK,&QWP(64,"ebx"));
+	&vpmuludq	($T0,$T0,&QWP(16*3,"edx"));	# s4*h3
+	&vpaddq		($D2,$D2,$T0);
+
+	################################################################
+	# lazy reduction
+	 &vpsrlq	($T0,$D3,26);
+	 &vpand		($D3,$D3,$MASK);
+	&vpsrlq		($T1,$D0,26);
+	&vpand		($D0,$D0,$MASK);
+	 &vpaddq	($D4,$D4,$T0);			# h3 -> h4
+	&vpaddq		($D1,$D1,$T1);			# h0 -> h1
+	 &vpsrlq	($T0,$D4,26);
+	 &vpand		($D4,$D4,$MASK);
+	&vpsrlq		($T1,$D1,26);
+	&vpand		($D1,$D1,$MASK);
+	&vpaddq		($D2,$D2,$T1);			# h1 -> h2
+	 &vpaddd	($D0,$D0,$T0);
+	 &vpsllq	($T0,$T0,2);
+	&vpsrlq		($T1,$D2,26);
+	&vpand		($D2,$D2,$MASK);
+	 &vpaddd	($D0,$D0,$T0);			# h4 -> h0
+	&vpaddd		($D3,$D3,$T1);			# h2 -> h3
+	&vpsrlq		($T1,$D3,26);
+	 &vpsrlq	($T0,$D0,26);
+	 &vpand		($D0,$D0,$MASK);
+	&vpand		($D3,$D3,$MASK);
+	 &vpaddd	($D1,$D1,$T0);			# h0 -> h1
+	&vpaddd		($D4,$D4,$T1);			# h3 -> h4
+
+	&dec		("ecx");
+	&jz		(&label("square_break"));
+
+	&vpunpcklqdq	($D0,$D0,&QWP(16*0,"esp"));	# 0:r^1:0:r^2
+	&vpunpcklqdq	($D1,$D1,&QWP(16*1,"esp"));
+	&vpunpcklqdq	($D2,$D2,&QWP(16*2,"esp"));
+	&vpunpcklqdq	($D3,$D3,&QWP(16*3,"esp"));
+	&vpunpcklqdq	($D4,$D4,&QWP(16*4,"esp"));
+	&jmp		(&label("square"));
+
+&set_label("square_break");
+	&vpsllq		($D0,$D0,32);			# -> r^3:0:r^4:0
+	&vpsllq		($D1,$D1,32);
+	&vpsllq		($D2,$D2,32);
+	&vpsllq		($D3,$D3,32);
+	&vpsllq		($D4,$D4,32);
+	&vpor		($D0,$D0,&QWP(16*0,"esp"));	# r^3:r^1:r^4:r^2
+	&vpor		($D1,$D1,&QWP(16*1,"esp"));
+	&vpor		($D2,$D2,&QWP(16*2,"esp"));
+	&vpor		($D3,$D3,&QWP(16*3,"esp"));
+	&vpor		($D4,$D4,&QWP(16*4,"esp"));
+
+	&vpshufd	($D0,$D0,0b10001101);		# -> r^1:r^2:r^3:r^4
+	&vpshufd	($D1,$D1,0b10001101);
+	&vpshufd	($D2,$D2,0b10001101);
+	&vpshufd	($D3,$D3,0b10001101);
+	&vpshufd	($D4,$D4,0b10001101);
+
+	&vmovdqu	(&QWP(16*0,"edi"),$D0);		# save the table
+	&vmovdqu	(&QWP(16*1,"edi"),$D1);
+	&vmovdqu	(&QWP(16*2,"edi"),$D2);
+	&vmovdqu	(&QWP(16*3,"edi"),$D3);
+	&vmovdqu	(&QWP(16*4,"edi"),$D4);
+
+	&vpslld		($T1,$D1,2);
+	&vpslld		($T0,$D2,2);
+	&vpaddd		($T1,$T1,$D1);			# *5
+	&vpaddd		($T0,$T0,$D2);			# *5
+	&vmovdqu	(&QWP(16*5,"edi"),$T1);
+	&vmovdqu	(&QWP(16*6,"edi"),$T0);
+	&vpslld		($T1,$D3,2);
+	&vpslld		($T0,$D4,2);
+	&vpaddd		($T1,$T1,$D3);			# *5
+	&vpaddd		($T0,$T0,$D4);			# *5
+	&vmovdqu	(&QWP(16*7,"edi"),$T1);
+	&vmovdqu	(&QWP(16*8,"edi"),$T0);
+
+	&mov		("esp","ebp");
+	&lea		("edi",&DWP(-16*3,"edi"));	# size de-optimization
+	&ret		();
+&function_end_B("_poly1305_init_avx2");
+
+########################################################################
+# now it's time to switch to %ymm
+
+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("ymm$_",(0..7));
+my $MASK=$T2;
+
+sub X { my $reg=shift; $reg=~s/^ymm/xmm/; $reg; }
+
+&align	(32);
+&function_begin("_poly1305_blocks_avx2");
+	&mov	("edi",&wparam(0));			# ctx
+	&mov	("esi",&wparam(1));			# inp
+	&mov	("ecx",&wparam(2));			# len
+
+	&mov	("eax",&DWP(4*5,"edi"));		# is_base2_26
+	&and	("ecx",-16);
+	&jz	(&label("nodata"));
+	&cmp	("ecx",64);
+	&jae	(&label("enter_avx2"));
+	&test	("eax","eax");				# is_base2_26?
+	&jz	(&label("enter_blocks"));
+
+&set_label("enter_avx2");
+	&vzeroupper	();
+
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop("ebx");
+	&lea	("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
+
+	&test	("eax","eax");				# is_base2_26?
+	&jnz	(&label("base2_26"));
+
+	&call	("_poly1305_init_avx2");
+
+	################################################# base 2^32 -> base 2^26
+	&mov	("eax",&DWP(0,"edi"));
+	&mov	("ecx",&DWP(3,"edi"));
+	&mov	("edx",&DWP(6,"edi"));
+	&mov	("esi",&DWP(9,"edi"));
+	&mov	("ebp",&DWP(13,"edi"));
+
+	&shr	("ecx",2);
+	&and	("eax",0x3ffffff);
+	&shr	("edx",4);
+	&and	("ecx",0x3ffffff);
+	&shr	("esi",6);
+	&and	("edx",0x3ffffff);
+
+	&mov	(&DWP(4*0,"edi"),"eax");
+	&mov	(&DWP(4*1,"edi"),"ecx");
+	&mov	(&DWP(4*2,"edi"),"edx");
+	&mov	(&DWP(4*3,"edi"),"esi");
+	&mov	(&DWP(4*4,"edi"),"ebp");
+	&mov	(&DWP(4*5,"edi"),1);			# is_base2_26
+
+	&mov	("esi",&wparam(1));			# [reload] inp
+	&mov	("ecx",&wparam(2));			# [reload] len
+
+&set_label("base2_26");
+	&mov	("eax",&wparam(3));			# padbit
+	&mov	("ebp","esp");
+
+	&sub	("esp",32*(5+9));
+	&and	("esp",-512);				# ensure that frame
+							# doesn't cross page
+							# boundary, which is
+							# essential for
+							# misaligned 32-byte
+							# loads
+
+	################################################################
+        # expand and copy pre-calculated table to stack
+
+	&vmovdqu	(&X($D0),&QWP(16*(3+0),"edi"));
+	&lea		("edx",&DWP(32*5+128,"esp"));	# +128 size optimization
+	&vmovdqu	(&X($D1),&QWP(16*(3+1),"edi"));
+	&vmovdqu	(&X($D2),&QWP(16*(3+2),"edi"));
+	&vmovdqu	(&X($D3),&QWP(16*(3+3),"edi"));
+	&vmovdqu	(&X($D4),&QWP(16*(3+4),"edi"));
+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
+	&vpermq		($D0,$D0,0b01000000);		# 00001234 -> 12343434
+	&vpermq		($D1,$D1,0b01000000);
+	&vpermq		($D2,$D2,0b01000000);
+	&vpermq		($D3,$D3,0b01000000);
+	&vpermq		($D4,$D4,0b01000000);
+	&vpshufd	($D0,$D0,0b11001000);		# 12343434 -> 14243444
+	&vpshufd	($D1,$D1,0b11001000);
+	&vpshufd	($D2,$D2,0b11001000);
+	&vpshufd	($D3,$D3,0b11001000);
+	&vpshufd	($D4,$D4,0b11001000);
+	&vmovdqa	(&QWP(32*0-128,"edx"),$D0);
+	&vmovdqu	(&X($D0),&QWP(16*5,"edi"));
+	&vmovdqa	(&QWP(32*1-128,"edx"),$D1);
+	&vmovdqu	(&X($D1),&QWP(16*6,"edi"));
+	&vmovdqa	(&QWP(32*2-128,"edx"),$D2);
+	&vmovdqu	(&X($D2),&QWP(16*7,"edi"));
+	&vmovdqa	(&QWP(32*3-128,"edx"),$D3);
+	&vmovdqu	(&X($D3),&QWP(16*8,"edi"));
+	&vmovdqa	(&QWP(32*4-128,"edx"),$D4);
+	&vpermq		($D0,$D0,0b01000000);
+	&vpermq		($D1,$D1,0b01000000);
+	&vpermq		($D2,$D2,0b01000000);
+	&vpermq		($D3,$D3,0b01000000);
+	&vpshufd	($D0,$D0,0b11001000);
+	&vpshufd	($D1,$D1,0b11001000);
+	&vpshufd	($D2,$D2,0b11001000);
+	&vpshufd	($D3,$D3,0b11001000);
+	&vmovdqa	(&QWP(32*5-128,"edx"),$D0);
+	&vmovd		(&X($D0),&DWP(-16*3+4*0,"edi"));# load hash value
+	&vmovdqa	(&QWP(32*6-128,"edx"),$D1);
+	&vmovd		(&X($D1),&DWP(-16*3+4*1,"edi"));
+	&vmovdqa	(&QWP(32*7-128,"edx"),$D2);
+	&vmovd		(&X($D2),&DWP(-16*3+4*2,"edi"));
+	&vmovdqa	(&QWP(32*8-128,"edx"),$D3);
+	&vmovd		(&X($D3),&DWP(-16*3+4*3,"edi"));
+	&vmovd		(&X($D4),&DWP(-16*3+4*4,"edi"));
+	&vmovdqa	($MASK,&QWP(64,"ebx"));
+	&neg		("eax");			# padbit
+
+	&test		("ecx",63);
+	&jz		(&label("even"));
+
+	&mov		("edx","ecx");
+	&and		("ecx",-64);
+	&and		("edx",63);
+
+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));
+	&cmp		("edx",32);
+	&jb		(&label("one"));
+
+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
+	&je		(&label("two"));
+
+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
+	&lea		("esi",&DWP(16*3,"esi"));
+	&lea		("ebx",&DWP(8,"ebx"));		# three padbits
+	&lea		("edx",&DWP(32*5+128+8,"esp"));	# --:r^1:r^2:r^3 (*)
+	&jmp		(&label("tail"));
+
+&set_label("two");
+	&lea		("esi",&DWP(16*2,"esi"));
+	&lea		("ebx",&DWP(16,"ebx"));		# two padbits
+	&lea		("edx",&DWP(32*5+128+16,"esp"));# --:--:r^1:r^2 (*)
+	&jmp		(&label("tail"));
+
+&set_label("one");
+	&lea		("esi",&DWP(16*1,"esi"));
+	&vpxor		($T1,$T1,$T1);
+	&lea		("ebx",&DWP(32,"ebx","eax",8));	# one or no padbits
+	&lea		("edx",&DWP(32*5+128+24,"esp"));# --:--:--:r^1 (*)
+	&jmp		(&label("tail"));
+
+# (*)	spots marked with '--' are data from next table entry, but they
+#	are multiplied by 0 and therefore rendered insignificant
+
+&set_label("even",32);
+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));	# load input
+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
+	&vinserti128	($T1,$T1,&QWP(16*3,"esi"),1);
+	&lea		("esi",&DWP(16*4,"esi"));
+	&sub		("ecx",64);
+	&jz		(&label("tail"));
+
+&set_label("loop");
+	################################################################
+	# ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
+	# ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
+	# ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
+	# ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
+	#   \________/ \_______/
+	################################################################
+
+sub vsplat_input {
+	&vmovdqa	(&QWP(32*2,"esp"),$D2);
+	&vpsrldq	($D2,$T0,6);			# splat input
+	&vmovdqa	(&QWP(32*0,"esp"),$D0);
+	&vpsrldq	($D0,$T1,6);
+	&vmovdqa	(&QWP(32*1,"esp"),$D1);
+	&vpunpckhqdq	($D1,$T0,$T1);			# 4
+	&vpunpcklqdq	($T0,$T0,$T1);			# 0:1
+	&vpunpcklqdq	($D2,$D2,$D0);			# 2:3
+
+	&vpsrlq		($D0,$D2,30);
+	&vpsrlq		($D2,$D2,4);
+	&vpsrlq		($T1,$T0,26);
+	&vpsrlq		($D1,$D1,40);			# 4
+	&vpand		($D2,$D2,$MASK);		# 2
+	&vpand		($T0,$T0,$MASK);		# 0
+	&vpand		($T1,$T1,$MASK);		# 1
+	&vpand		($D0,$D0,$MASK);		# 3 (*)
+	&vpor		($D1,$D1,&QWP(0,"ebx"));	# padbit, yes, always
+
+	# (*)	note that output is counterintuitive, inp[3:4] is
+	#	returned in $D1-2, while $D3-4 are preserved;
+}
+	&vsplat_input	();
+
+sub vpmuladd {
+my $addr = shift;
+
+	&vpaddq		($D2,$D2,&QWP(32*2,"esp"));	# add hash value
+	&vpaddq		($T0,$T0,&QWP(32*0,"esp"));
+	&vpaddq		($T1,$T1,&QWP(32*1,"esp"));
+	&vpaddq		($D0,$D0,$D3);
+	&vpaddq		($D1,$D1,$D4);
+
+	################################################################
+	# d3 = h2*r1   + h0*r3 + h1*r2   + h3*r0   + h4*5*r4
+	# d4 = h2*r2   + h0*r4 + h1*r3   + h3*r1   + h4*r0
+	# d0 = h2*5*r3 + h0*r0 + h1*5*r4 + h3*5*r2 + h4*5*r1
+	# d1 = h2*5*r4 + h0*r1 + h1*r0   + h3*5*r3 + h4*5*r2
+	# d2 = h2*r0   + h0*r2 + h1*r1   + h3*5*r4 + h4*5*r3
+
+	&vpmuludq	($D3,$D2,&$addr(1));		# d3 = h2*r1
+	 &vmovdqa	(QWP(32*1,"esp"),$T1);
+	&vpmuludq	($D4,$D2,&$addr(2));		# d4 = h2*r2
+	 &vmovdqa	(QWP(32*3,"esp"),$D0);
+	&vpmuludq	($D0,$D2,&$addr(7));		# d0 = h2*s3
+	 &vmovdqa	(QWP(32*4,"esp"),$D1);
+	&vpmuludq	($D1,$D2,&$addr(8));		# d1 = h2*s4
+	&vpmuludq	($D2,$D2,&$addr(0));		# d2 = h2*r0
+
+	&vpmuludq	($T2,$T0,&$addr(3));		# h0*r3
+	&vpaddq		($D3,$D3,$T2);			# d3 += h0*r3
+	&vpmuludq	($T1,$T0,&$addr(4));		# h0*r4
+	&vpaddq		($D4,$D4,$T1);			# d4 + h0*r4
+	&vpmuludq	($T2,$T0,&$addr(0));		# h0*r0
+	&vpaddq		($D0,$D0,$T2);			# d0 + h0*r0
+	 &vmovdqa	($T2,&QWP(32*1,"esp"));		# h1
+	&vpmuludq	($T1,$T0,&$addr(1));		# h0*r1
+	&vpaddq		($D1,$D1,$T1);			# d1 += h0*r1
+	&vpmuludq	($T0,$T0,&$addr(2));		# h0*r2
+	&vpaddq		($D2,$D2,$T0);			# d2 += h0*r2
+
+	&vpmuludq	($T1,$T2,&$addr(2));		# h1*r2
+	&vpaddq		($D3,$D3,$T1);			# d3 += h1*r2
+	&vpmuludq	($T0,$T2,&$addr(3));		# h1*r3
+	&vpaddq		($D4,$D4,$T0);			# d4 += h1*r3
+	&vpmuludq	($T1,$T2,&$addr(8));		# h1*s4
+	&vpaddq		($D0,$D0,$T1);			# d0 += h1*s4
+	 &vmovdqa	($T1,&QWP(32*3,"esp"));		# h3
+	&vpmuludq	($T0,$T2,&$addr(0));		# h1*r0
+	&vpaddq		($D1,$D1,$T0);			# d1 += h1*r0
+	&vpmuludq	($T2,$T2,&$addr(1));		# h1*r1
+	&vpaddq		($D2,$D2,$T2);			# d2 += h1*r1
+
+	&vpmuludq	($T0,$T1,&$addr(0));		# h3*r0
+	&vpaddq		($D3,$D3,$T0);			# d3 += h3*r0
+	&vpmuludq	($T2,$T1,&$addr(1));		# h3*r1
+	&vpaddq		($D4,$D4,$T2);			# d4 += h3*r1
+	&vpmuludq	($T0,$T1,&$addr(6));		# h3*s2
+	&vpaddq		($D0,$D0,$T0);			# d0 += h3*s2
+	 &vmovdqa	($T0,&QWP(32*4,"esp"));		# h4
+	&vpmuludq	($T2,$T1,&$addr(7));		# h3*s3
+	&vpaddq		($D1,$D1,$T2);			# d1+= h3*s3
+	&vpmuludq	($T1,$T1,&$addr(8));		# h3*s4
+	&vpaddq		($D2,$D2,$T1);			# d2 += h3*s4
+
+	&vpmuludq	($T2,$T0,&$addr(8));		# h4*s4
+	&vpaddq		($D3,$D3,$T2);			# d3 += h4*s4
+	&vpmuludq	($T1,$T0,&$addr(5));		# h4*s1
+	&vpaddq		($D0,$D0,$T1);			# d0 += h4*s1
+	&vpmuludq	($T2,$T0,&$addr(0));		# h4*r0
+	&vpaddq		($D4,$D4,$T2);			# d4 += h4*r0
+	 &vmovdqa	($MASK,&QWP(64,"ebx"));
+	&vpmuludq	($T1,$T0,&$addr(6));		# h4*s2
+	&vpaddq		($D1,$D1,$T1);			# d1 += h4*s2
+	&vpmuludq	($T0,$T0,&$addr(7));		# h4*s3
+	&vpaddq		($D2,$D2,$T0);			# d2 += h4*s3
+}
+	&vpmuladd	(sub {	my $i=shift; &QWP(32*$i-128,"edx");	});
+
+sub vlazy_reduction {
+	################################################################
+	# lazy reduction
+
+	 &vpsrlq	($T0,$D3,26);
+	 &vpand		($D3,$D3,$MASK);
+	&vpsrlq		($T1,$D0,26);
+	&vpand		($D0,$D0,$MASK);
+	 &vpaddq	($D4,$D4,$T0);			# h3 -> h4
+	&vpaddq		($D1,$D1,$T1);			# h0 -> h1
+	 &vpsrlq	($T0,$D4,26);
+	 &vpand		($D4,$D4,$MASK);
+	&vpsrlq		($T1,$D1,26);
+	&vpand		($D1,$D1,$MASK);
+	&vpaddq		($D2,$D2,$T1);			# h1 -> h2
+	 &vpaddq	($D0,$D0,$T0);
+	 &vpsllq	($T0,$T0,2);
+	&vpsrlq		($T1,$D2,26);
+	&vpand		($D2,$D2,$MASK);
+	 &vpaddq	($D0,$D0,$T0);			# h4 -> h0
+	&vpaddq		($D3,$D3,$T1);			# h2 -> h3
+	&vpsrlq		($T1,$D3,26);
+	 &vpsrlq	($T0,$D0,26);
+	 &vpand		($D0,$D0,$MASK);
+	&vpand		($D3,$D3,$MASK);
+	 &vpaddq	($D1,$D1,$T0);			# h0 -> h1
+	&vpaddq		($D4,$D4,$T1);			# h3 -> h4
+}
+	&vlazy_reduction();
+
+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));	# load input
+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
+	&vinserti128	($T1,$T1,&QWP(16*3,"esi"),1);
+	&lea		("esi",&DWP(16*4,"esi"));
+	&sub		("ecx",64);
+	&jnz		(&label("loop"));
+
+&set_label("tail");
+	&vsplat_input	();
+	&and		("ebx",-64);			# restore pointer
+
+	&vpmuladd	(sub {	my $i=shift; &QWP(4+32*$i-128,"edx");	});
+
+	################################################################
+	# horizontal addition
+
+	&vpsrldq	($T0,$D4,8);
+	&vpsrldq	($T1,$D3,8);
+	&vpaddq		($D4,$D4,$T0);
+	&vpsrldq	($T0,$D0,8);
+	&vpaddq		($D3,$D3,$T1);
+	&vpsrldq	($T1,$D1,8);
+	&vpaddq		($D0,$D0,$T0);
+	&vpsrldq	($T0,$D2,8);
+	&vpaddq		($D1,$D1,$T1);
+	&vpermq		($T1,$D4,2);			# keep folding
+	&vpaddq		($D2,$D2,$T0);
+	&vpermq		($T0,$D3,2);
+	&vpaddq		($D4,$D4,$T1);
+	&vpermq		($T1,$D0,2);
+	&vpaddq		($D3,$D3,$T0);
+	&vpermq		($T0,$D1,2);
+	&vpaddq		($D0,$D0,$T1);
+	&vpermq		($T1,$D2,2);
+	&vpaddq		($D1,$D1,$T0);
+	&vpaddq		($D2,$D2,$T1);
+
+	&vlazy_reduction();
+
+	&cmp		("ecx",0);
+	&je		(&label("done"));
+
+	################################################################
+	# clear all but single word
+
+	&vpshufd	(&X($D0),&X($D0),0b11111100);
+	&lea		("edx",&DWP(32*5+128,"esp"));	# restore pointer
+	&vpshufd	(&X($D1),&X($D1),0b11111100);
+	&vpshufd	(&X($D2),&X($D2),0b11111100);
+	&vpshufd	(&X($D3),&X($D3),0b11111100);
+	&vpshufd	(&X($D4),&X($D4),0b11111100);
+	&jmp		(&label("even"));
+
+&set_label("done",16);
+	&vmovd		(&DWP(-16*3+4*0,"edi"),&X($D0));# store hash value
+	&vmovd		(&DWP(-16*3+4*1,"edi"),&X($D1));
+	&vmovd		(&DWP(-16*3+4*2,"edi"),&X($D2));
+	&vmovd		(&DWP(-16*3+4*3,"edi"),&X($D3));
+	&vmovd		(&DWP(-16*3+4*4,"edi"),&X($D4));
+	&vzeroupper	();
+	&mov	("esp","ebp");
+&set_label("nodata");
+&function_end("_poly1305_blocks_avx2");
+}
+&set_label("const_sse2",64);
+	&data_word(1<<24,0,	1<<24,0,	1<<24,0,	1<<24,0);
+	&data_word(0,0,		0,0,		0,0,		0,0);
+	&data_word(0x03ffffff,0,0x03ffffff,0,	0x03ffffff,0,	0x03ffffff,0);
+	&data_word(0x0fffffff,0x0ffffffc,0x0ffffffc,0x0ffffffc);
+}
+&asciz	("Poly1305 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+&align	(4);
+
+&asm_finish();
diff --git a/src/crypto/poly1305/asm/poly1305-x86_64.pl b/src/crypto/poly1305/asm/poly1305-x86_64.pl
new file mode 100755
index 0000000..3c810c5
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-x86_64.pl
@@ -0,0 +1,2235 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for x86_64.
+#
+# March 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone,
+# measured with rdtsc at fixed clock frequency.
+#
+#		IALU/gcc-4.8(*)	AVX(**)		AVX2
+# P4		4.90/+120%      -
+# Core 2	2.39/+90%	-
+# Westmere	1.86/+120%	-
+# Sandy Bridge	1.39/+140%	1.10
+# Haswell	1.10/+175%	1.11		0.65
+# Skylake	1.12/+120%	0.96		0.51
+# Silvermont	2.83/+95%	-
+# VIA Nano	1.82/+150%	-
+# Sledgehammer	1.38/+160%	-
+# Bulldozer	2.21/+130%	0.97
+#
+# (*)	improvement coefficients relative to clang are more modest and
+#	are ~50% on most processors, in both cases we are comparing to
+#	__int128 code;
+# (**)	SSE2 implementation was attempted, but among non-AVX processors
+#	it was faster than integer-only code only on older Intel P4 and
+#	Core processors, 50-30%, less newer processor is, but slower on
+#	contemporary ones, for example almost 2x slower on Atom, and as
+#	former are naturally disappearing, SSE2 is deemed unnecessary;
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+$avx = 2;
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx");
+my ($mac,$nonce)=($inp,$len);	# *_emit arguments
+my ($d1,$d2,$d3, $r0,$r1,$s1)=map("%r$_",(8..13));
+my ($h0,$h1,$h2)=("%r14","%rbx","%rbp");
+
+sub poly1305_iteration {
+# input:	copy of $r1 in %rax, $h0-$h2, $r0-$r1
+# output:	$h0-$h2 *= $r0-$r1
+$code.=<<___;
+	mulq	$h0			# h0*r1
+	mov	%rax,$d2
+	 mov	$r0,%rax
+	mov	%rdx,$d3
+
+	mulq	$h0			# h0*r0
+	mov	%rax,$h0		# future $h0
+	 mov	$r0,%rax
+	mov	%rdx,$d1
+
+	mulq	$h1			# h1*r0
+	add	%rax,$d2
+	 mov	$s1,%rax
+	adc	%rdx,$d3
+
+	mulq	$h1			# h1*s1
+	 mov	$h2,$h1			# borrow $h1
+	add	%rax,$h0
+	adc	%rdx,$d1
+
+	imulq	$s1,$h1			# h2*s1
+	add	$h1,$d2
+	 mov	$d1,$h1
+	adc	\$0,$d3
+
+	imulq	$r0,$h2			# h2*r0
+	add	$d2,$h1
+	mov	\$-4,%rax		# mask value
+	adc	$h2,$d3
+
+	and	$d3,%rax		# last reduction step
+	mov	$d3,$h2
+	shr	\$2,$d3
+	and	\$3,$h2
+	add	$d3,%rax
+	add	%rax,$h0
+	adc	\$0,$h1
+___
+}
+
+########################################################################
+# Layout of opaque area is following.
+#
+#	unsigned __int64 h[3];		# current hash value base 2^64
+#	unsigned __int64 r[2];		# key value base 2^64
+
+$code.=<<___;
+.text
+
+.extern	OPENSSL_ia32cap_P
+
+.globl	poly1305_init
+.globl	poly1305_blocks
+.globl	poly1305_emit
+.type	poly1305_init,\@function,3
+.align	32
+poly1305_init:
+	xor	%rax,%rax
+	mov	%rax,0($ctx)		# initialize hash value
+	mov	%rax,8($ctx)
+	mov	%rax,16($ctx)
+
+	cmp	\$0,$inp
+	je	.Lno_key
+
+	lea	poly1305_blocks(%rip),%r10
+	lea	poly1305_emit(%rip),%r11
+___
+$code.=<<___	if ($avx);
+	mov	OPENSSL_ia32cap_P+4(%rip),%r9
+	lea	poly1305_blocks_avx(%rip),%rax
+	lea	poly1305_emit_avx(%rip),%rcx
+	bt	\$`60-32`,%r9		# AVX?
+	cmovc	%rax,%r10
+	cmovc	%rcx,%r11
+___
+$code.=<<___	if ($avx>1);
+	lea	poly1305_blocks_avx2(%rip),%rax
+	bt	\$`5+32`,%r9		# AVX2?
+	cmovc	%rax,%r10
+___
+$code.=<<___;
+	mov	\$0x0ffffffc0fffffff,%rax
+	mov	\$0x0ffffffc0ffffffc,%rcx
+	and	0($inp),%rax
+	and	8($inp),%rcx
+	mov	%rax,24($ctx)
+	mov	%rcx,32($ctx)
+___
+$code.=<<___	if ($flavour !~ /elf32/);
+	mov	%r10,0(%rdx)
+	mov	%r11,8(%rdx)
+___
+$code.=<<___	if ($flavour =~ /elf32/);
+	mov	%r10d,0(%rdx)
+	mov	%r11d,4(%rdx)
+___
+$code.=<<___;
+	mov	\$1,%eax
+.Lno_key:
+	ret
+.size	poly1305_init,.-poly1305_init
+
+.type	poly1305_blocks,\@function,4
+.align	32
+poly1305_blocks:
+.Lblocks:
+	sub	\$16,$len		# too short?
+	jc	.Lno_data
+
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lblocks_body:
+
+	mov	$len,%r15		# reassign $len
+
+	mov	24($ctx),$r0		# load r
+	mov	32($ctx),$s1
+
+	mov	0($ctx),$h0		# load hash value
+	mov	8($ctx),$h1
+	mov	16($ctx),$h2
+
+	mov	$s1,$r1
+	shr	\$2,$s1
+	mov	$r1,%rax
+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
+	jmp	.Loop
+
+.align	32
+.Loop:
+	add	0($inp),$h0		# accumulate input
+	adc	8($inp),$h1
+	lea	16($inp),$inp
+	adc	$padbit,$h2
+___
+	&poly1305_iteration();
+$code.=<<___;
+	mov	$r1,%rax
+	sub	\$16,%r15		# len-=16
+	jnc	.Loop
+
+	mov	$h0,0($ctx)		# store hash value
+	mov	$h1,8($ctx)
+	mov	$h2,16($ctx)
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%r12
+	mov	32(%rsp),%rbp
+	mov	40(%rsp),%rbx
+	lea	48(%rsp),%rsp
+.Lno_data:
+.Lblocks_epilogue:
+	ret
+.size	poly1305_blocks,.-poly1305_blocks
+
+.type	poly1305_emit,\@function,3
+.align	32
+poly1305_emit:
+.Lemit:
+	mov	0($ctx),%r8	# load hash value
+	mov	8($ctx),%r9
+	mov	16($ctx),%r10
+
+	mov	%r8,%rax
+	add	\$5,%r8		# compare to modulus
+	mov	%r9,%rcx
+	adc	\$0,%r9
+	adc	\$0,%r10
+	shr	\$2,%r10	# did 130-bit value overfow?
+	cmovnz	%r8,%rax
+	cmovnz	%r9,%rcx
+
+	add	0($nonce),%rax	# accumulate nonce
+	adc	8($nonce),%rcx
+	mov	%rax,0($mac)	# write result
+	mov	%rcx,8($mac)
+
+	ret
+.size	poly1305_emit,.-poly1305_emit
+___
+if ($avx) {
+
+########################################################################
+# Layout of opaque area is following.
+#
+#	unsigned __int32 h[5];		# current hash value base 2^26
+#	unsigned __int32 is_base2_26;
+#	unsigned __int64 r[2];		# key value base 2^64
+#	unsigned __int64 pad;
+#	struct { unsigned __int32 r^2, r^1, r^4, r^3; } r[9];
+#
+# where r^n are base 2^26 digits of degrees of multiplier key. There are
+# 5 digits, but last four are interleaved with multiples of 5, totalling
+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
+
+my ($H0,$H1,$H2,$H3,$H4, $T0,$T1,$T2,$T3,$T4, $D0,$D1,$D2,$D3,$D4, $MASK) =
+    map("%xmm$_",(0..15));
+
+$code.=<<___;
+.type	__poly1305_block,\@abi-omnipotent
+.align	32
+__poly1305_block:
+___
+	&poly1305_iteration();
+$code.=<<___;
+	ret
+.size	__poly1305_block,.-__poly1305_block
+
+.type	__poly1305_init_avx,\@abi-omnipotent
+.align	32
+__poly1305_init_avx:
+	mov	$r0,$h0
+	mov	$r1,$h1
+	xor	$h2,$h2
+
+	lea	48+64($ctx),$ctx	# size optimization
+
+	mov	$r1,%rax
+	call	__poly1305_block	# r^2
+
+	mov	\$0x3ffffff,%eax	# save interleaved r^2 and r base 2^26
+	mov	\$0x3ffffff,%edx
+	mov	$h0,$d1
+	and	$h0#d,%eax
+	mov	$r0,$d2
+	and	$r0#d,%edx
+	mov	%eax,`16*0+0-64`($ctx)
+	shr	\$26,$d1
+	mov	%edx,`16*0+4-64`($ctx)
+	shr	\$26,$d2
+
+	mov	\$0x3ffffff,%eax
+	mov	\$0x3ffffff,%edx
+	and	$d1#d,%eax
+	and	$d2#d,%edx
+	mov	%eax,`16*1+0-64`($ctx)
+	lea	(%rax,%rax,4),%eax	# *5
+	mov	%edx,`16*1+4-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	mov	%eax,`16*2+0-64`($ctx)
+	shr	\$26,$d1
+	mov	%edx,`16*2+4-64`($ctx)
+	shr	\$26,$d2
+
+	mov	$h1,%rax
+	mov	$r1,%rdx
+	shl	\$12,%rax
+	shl	\$12,%rdx
+	or	$d1,%rax
+	or	$d2,%rdx
+	and	\$0x3ffffff,%eax
+	and	\$0x3ffffff,%edx
+	mov	%eax,`16*3+0-64`($ctx)
+	lea	(%rax,%rax,4),%eax	# *5
+	mov	%edx,`16*3+4-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	mov	%eax,`16*4+0-64`($ctx)
+	mov	$h1,$d1
+	mov	%edx,`16*4+4-64`($ctx)
+	mov	$r1,$d2
+
+	mov	\$0x3ffffff,%eax
+	mov	\$0x3ffffff,%edx
+	shr	\$14,$d1
+	shr	\$14,$d2
+	and	$d1#d,%eax
+	and	$d2#d,%edx
+	mov	%eax,`16*5+0-64`($ctx)
+	lea	(%rax,%rax,4),%eax	# *5
+	mov	%edx,`16*5+4-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	mov	%eax,`16*6+0-64`($ctx)
+	shr	\$26,$d1
+	mov	%edx,`16*6+4-64`($ctx)
+	shr	\$26,$d2
+
+	mov	$h2,%rax
+	shl	\$24,%rax
+	or	%rax,$d1
+	mov	$d1#d,`16*7+0-64`($ctx)
+	lea	($d1,$d1,4),$d1		# *5
+	mov	$d2#d,`16*7+4-64`($ctx)
+	lea	($d2,$d2,4),$d2		# *5
+	mov	$d1#d,`16*8+0-64`($ctx)
+	mov	$d2#d,`16*8+4-64`($ctx)
+
+	mov	$r1,%rax
+	call	__poly1305_block	# r^3
+
+	mov	\$0x3ffffff,%eax	# save r^3 base 2^26
+	mov	$h0,$d1
+	and	$h0#d,%eax
+	shr	\$26,$d1
+	mov	%eax,`16*0+12-64`($ctx)
+
+	mov	\$0x3ffffff,%edx
+	and	$d1#d,%edx
+	mov	%edx,`16*1+12-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	shr	\$26,$d1
+	mov	%edx,`16*2+12-64`($ctx)
+
+	mov	$h1,%rax
+	shl	\$12,%rax
+	or	$d1,%rax
+	and	\$0x3ffffff,%eax
+	mov	%eax,`16*3+12-64`($ctx)
+	lea	(%rax,%rax,4),%eax	# *5
+	mov	$h1,$d1
+	mov	%eax,`16*4+12-64`($ctx)
+
+	mov	\$0x3ffffff,%edx
+	shr	\$14,$d1
+	and	$d1#d,%edx
+	mov	%edx,`16*5+12-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	shr	\$26,$d1
+	mov	%edx,`16*6+12-64`($ctx)
+
+	mov	$h2,%rax
+	shl	\$24,%rax
+	or	%rax,$d1
+	mov	$d1#d,`16*7+12-64`($ctx)
+	lea	($d1,$d1,4),$d1		# *5
+	mov	$d1#d,`16*8+12-64`($ctx)
+
+	mov	$r1,%rax
+	call	__poly1305_block	# r^4
+
+	mov	\$0x3ffffff,%eax	# save r^4 base 2^26
+	mov	$h0,$d1
+	and	$h0#d,%eax
+	shr	\$26,$d1
+	mov	%eax,`16*0+8-64`($ctx)
+
+	mov	\$0x3ffffff,%edx
+	and	$d1#d,%edx
+	mov	%edx,`16*1+8-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	shr	\$26,$d1
+	mov	%edx,`16*2+8-64`($ctx)
+
+	mov	$h1,%rax
+	shl	\$12,%rax
+	or	$d1,%rax
+	and	\$0x3ffffff,%eax
+	mov	%eax,`16*3+8-64`($ctx)
+	lea	(%rax,%rax,4),%eax	# *5
+	mov	$h1,$d1
+	mov	%eax,`16*4+8-64`($ctx)
+
+	mov	\$0x3ffffff,%edx
+	shr	\$14,$d1
+	and	$d1#d,%edx
+	mov	%edx,`16*5+8-64`($ctx)
+	lea	(%rdx,%rdx,4),%edx	# *5
+	shr	\$26,$d1
+	mov	%edx,`16*6+8-64`($ctx)
+
+	mov	$h2,%rax
+	shl	\$24,%rax
+	or	%rax,$d1
+	mov	$d1#d,`16*7+8-64`($ctx)
+	lea	($d1,$d1,4),$d1		# *5
+	mov	$d1#d,`16*8+8-64`($ctx)
+
+	lea	-48-64($ctx),$ctx	# size [de-]optimization
+	ret
+.size	__poly1305_init_avx,.-__poly1305_init_avx
+
+.type	poly1305_blocks_avx,\@function,4
+.align	32
+poly1305_blocks_avx:
+	mov	20($ctx),%r8d		# is_base2_26
+	cmp	\$128,$len
+	jae	.Lblocks_avx
+	test	%r8d,%r8d
+	jz	.Lblocks
+
+.Lblocks_avx:
+	and	\$-16,$len
+	jz	.Lno_data_avx
+
+	vzeroupper
+
+	test	%r8d,%r8d
+	jz	.Lbase2_64_avx
+
+	test	\$31,$len
+	jz	.Leven_avx
+
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lblocks_avx_body:
+
+	mov	$len,%r15		# reassign $len
+
+	mov	0($ctx),$d1		# load hash value
+	mov	8($ctx),$d2
+	mov	16($ctx),$h2#d
+
+	mov	24($ctx),$r0		# load r
+	mov	32($ctx),$s1
+
+	################################# base 2^26 -> base 2^64
+	mov	$d1#d,$h0#d
+	and	\$-1<<31,$d1
+	mov	$d2,$r1			# borrow $r1
+	mov	$d2#d,$h1#d
+	and	\$-1<<31,$d2
+
+	shr	\$6,$d1
+	shl	\$52,$r1
+	add	$d1,$h0
+	shr	\$12,$h1
+	shr	\$18,$d2
+	add	$r1,$h0
+	adc	$d2,$h1
+
+	mov	$h2,$d1
+	shl	\$40,$d1
+	shr	\$24,$h2
+	add	$d1,$h1
+	adc	\$0,$h2			# can be partially reduced...
+
+	mov	\$-4,$d2		# ... so reduce
+	mov	$h2,$d1
+	and	$h2,$d2
+	shr	\$2,$d1
+	and	\$3,$h2
+	add	$d2,$d1			# =*5
+	add	$d1,$h0
+	adc	\$0,$h1
+
+	mov	$s1,$r1
+	mov	$s1,%rax
+	shr	\$2,$s1
+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
+
+	add	0($inp),$h0		# accumulate input
+	adc	8($inp),$h1
+	lea	16($inp),$inp
+	adc	$padbit,$h2
+
+	call	__poly1305_block
+
+	test	$padbit,$padbit		# if $padbit is zero,
+	jz	.Lstore_base2_64_avx	# store hash in base 2^64 format
+
+	################################# base 2^64 -> base 2^26
+	mov	$h0,%rax
+	mov	$h0,%rdx
+	shr	\$52,$h0
+	mov	$h1,$r0
+	mov	$h1,$r1
+	shr	\$26,%rdx
+	and	\$0x3ffffff,%rax	# h[0]
+	shl	\$12,$r0
+	and	\$0x3ffffff,%rdx	# h[1]
+	shr	\$14,$h1
+	or	$r0,$h0
+	shl	\$24,$h2
+	and	\$0x3ffffff,$h0		# h[2]
+	shr	\$40,$r1
+	and	\$0x3ffffff,$h1		# h[3]
+	or	$r1,$h2			# h[4]
+
+	sub	\$16,%r15
+	jz	.Lstore_base2_26_avx
+
+	vmovd	%rax#d,$H0
+	vmovd	%rdx#d,$H1
+	vmovd	$h0#d,$H2
+	vmovd	$h1#d,$H3
+	vmovd	$h2#d,$H4
+	jmp	.Lproceed_avx
+
+.align	32
+.Lstore_base2_64_avx:
+	mov	$h0,0($ctx)
+	mov	$h1,8($ctx)
+	mov	$h2,16($ctx)		# note that is_base2_26 is zeroed
+	jmp	.Ldone_avx
+
+.align	16
+.Lstore_base2_26_avx:
+	mov	%rax#d,0($ctx)		# store hash value base 2^26
+	mov	%rdx#d,4($ctx)
+	mov	$h0#d,8($ctx)
+	mov	$h1#d,12($ctx)
+	mov	$h2#d,16($ctx)
+.align	16
+.Ldone_avx:
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%r12
+	mov	32(%rsp),%rbp
+	mov	40(%rsp),%rbx
+	lea	48(%rsp),%rsp
+.Lno_data_avx:
+.Lblocks_avx_epilogue:
+	ret
+
+.align	32
+.Lbase2_64_avx:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lbase2_64_avx_body:
+
+	mov	$len,%r15		# reassign $len
+
+	mov	24($ctx),$r0		# load r
+	mov	32($ctx),$s1
+
+	mov	0($ctx),$h0		# load hash value
+	mov	8($ctx),$h1
+	mov	16($ctx),$h2#d
+
+	mov	$s1,$r1
+	mov	$s1,%rax
+	shr	\$2,$s1
+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
+
+	test	\$31,$len
+	jz	.Linit_avx
+
+	add	0($inp),$h0		# accumulate input
+	adc	8($inp),$h1
+	lea	16($inp),$inp
+	adc	$padbit,$h2
+	sub	\$16,%r15
+
+	call	__poly1305_block
+
+.Linit_avx:
+	################################# base 2^64 -> base 2^26
+	mov	$h0,%rax
+	mov	$h0,%rdx
+	shr	\$52,$h0
+	mov	$h1,$d1
+	mov	$h1,$d2
+	shr	\$26,%rdx
+	and	\$0x3ffffff,%rax	# h[0]
+	shl	\$12,$d1
+	and	\$0x3ffffff,%rdx	# h[1]
+	shr	\$14,$h1
+	or	$d1,$h0
+	shl	\$24,$h2
+	and	\$0x3ffffff,$h0		# h[2]
+	shr	\$40,$d2
+	and	\$0x3ffffff,$h1		# h[3]
+	or	$d2,$h2			# h[4]
+
+	vmovd	%rax#d,$H0
+	vmovd	%rdx#d,$H1
+	vmovd	$h0#d,$H2
+	vmovd	$h1#d,$H3
+	vmovd	$h2#d,$H4
+	movl	\$1,20($ctx)		# set is_base2_26
+
+	call	__poly1305_init_avx
+
+.Lproceed_avx:
+	mov	%r15,$len
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%r12
+	mov	32(%rsp),%rbp
+	mov	40(%rsp),%rbx
+	lea	48(%rsp),%rax
+	lea	48(%rsp),%rsp
+.Lbase2_64_avx_epilogue:
+	jmp	.Ldo_avx
+
+.align	32
+.Leven_avx:
+	vmovd		4*0($ctx),$H0		# load hash value
+	vmovd		4*1($ctx),$H1
+	vmovd		4*2($ctx),$H2
+	vmovd		4*3($ctx),$H3
+	vmovd		4*4($ctx),$H4
+
+.Ldo_avx:
+___
+$code.=<<___	if (!$win64);
+	lea		-0x58(%rsp),%r11
+	sub		\$0x178,%rsp
+___
+$code.=<<___	if ($win64);
+	lea		-0xf8(%rsp),%r11
+	sub		\$0x218,%rsp
+	vmovdqa		%xmm6,0x50(%r11)
+	vmovdqa		%xmm7,0x60(%r11)
+	vmovdqa		%xmm8,0x70(%r11)
+	vmovdqa		%xmm9,0x80(%r11)
+	vmovdqa		%xmm10,0x90(%r11)
+	vmovdqa		%xmm11,0xa0(%r11)
+	vmovdqa		%xmm12,0xb0(%r11)
+	vmovdqa		%xmm13,0xc0(%r11)
+	vmovdqa		%xmm14,0xd0(%r11)
+	vmovdqa		%xmm15,0xe0(%r11)
+.Ldo_avx_body:
+___
+$code.=<<___;
+	sub		\$64,$len
+	lea		-32($inp),%rax
+	cmovc		%rax,$inp
+
+	vmovdqu		`16*3`($ctx),$D4	# preload r0^2
+	lea		`16*3+64`($ctx),$ctx	# size optimization
+	lea		.Lconst(%rip),%rcx
+
+	################################################################
+	# load input
+	vmovdqu		16*2($inp),$T0
+	vmovdqu		16*3($inp),$T1
+	vmovdqa		64(%rcx),$MASK		# .Lmask26
+
+	vpsrldq		\$6,$T0,$T2		# splat input
+	vpsrldq		\$6,$T1,$T3
+	vpunpckhqdq	$T1,$T0,$T4		# 4
+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
+	vpunpcklqdq	$T3,$T2,$T3		# 2:3
+
+	vpsrlq		\$40,$T4,$T4		# 4
+	vpsrlq		\$26,$T0,$T1
+	vpand		$MASK,$T0,$T0		# 0
+	vpsrlq		\$4,$T3,$T2
+	vpand		$MASK,$T1,$T1		# 1
+	vpsrlq		\$30,$T3,$T3
+	vpand		$MASK,$T2,$T2		# 2
+	vpand		$MASK,$T3,$T3		# 3
+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
+
+	jbe		.Lskip_loop_avx
+
+	# expand and copy pre-calculated table to stack
+	vmovdqu		`16*1-64`($ctx),$D1
+	vmovdqu		`16*2-64`($ctx),$D2
+	vpshufd		\$0xEE,$D4,$D3		# 34xx -> 3434
+	vpshufd		\$0x44,$D4,$D0		# xx12 -> 1212
+	vmovdqa		$D3,-0x90(%r11)
+	vmovdqa		$D0,0x00(%rsp)
+	vpshufd		\$0xEE,$D1,$D4
+	vmovdqu		`16*3-64`($ctx),$D0
+	vpshufd		\$0x44,$D1,$D1
+	vmovdqa		$D4,-0x80(%r11)
+	vmovdqa		$D1,0x10(%rsp)
+	vpshufd		\$0xEE,$D2,$D3
+	vmovdqu		`16*4-64`($ctx),$D1
+	vpshufd		\$0x44,$D2,$D2
+	vmovdqa		$D3,-0x70(%r11)
+	vmovdqa		$D2,0x20(%rsp)
+	vpshufd		\$0xEE,$D0,$D4
+	vmovdqu		`16*5-64`($ctx),$D2
+	vpshufd		\$0x44,$D0,$D0
+	vmovdqa		$D4,-0x60(%r11)
+	vmovdqa		$D0,0x30(%rsp)
+	vpshufd		\$0xEE,$D1,$D3
+	vmovdqu		`16*6-64`($ctx),$D0
+	vpshufd		\$0x44,$D1,$D1
+	vmovdqa		$D3,-0x50(%r11)
+	vmovdqa		$D1,0x40(%rsp)
+	vpshufd		\$0xEE,$D2,$D4
+	vmovdqu		`16*7-64`($ctx),$D1
+	vpshufd		\$0x44,$D2,$D2
+	vmovdqa		$D4,-0x40(%r11)
+	vmovdqa		$D2,0x50(%rsp)
+	vpshufd		\$0xEE,$D0,$D3
+	vmovdqu		`16*8-64`($ctx),$D2
+	vpshufd		\$0x44,$D0,$D0
+	vmovdqa		$D3,-0x30(%r11)
+	vmovdqa		$D0,0x60(%rsp)
+	vpshufd		\$0xEE,$D1,$D4
+	vpshufd		\$0x44,$D1,$D1
+	vmovdqa		$D4,-0x20(%r11)
+	vmovdqa		$D1,0x70(%rsp)
+	vpshufd		\$0xEE,$D2,$D3
+	 vmovdqa	0x00(%rsp),$D4		# preload r0^2
+	vpshufd		\$0x44,$D2,$D2
+	vmovdqa		$D3,-0x10(%r11)
+	vmovdqa		$D2,0x80(%rsp)
+
+	jmp		.Loop_avx
+
+.align	32
+.Loop_avx:
+	################################################################
+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+	#   \___________________/
+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+	#   \___________________/ \____________________/
+	#
+	# Note that we start with inp[2:3]*r^2. This is because it
+	# doesn't depend on reduction in previous iteration.
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+	#
+	# though note that $Tx and $Hx are "reversed" in this section,
+	# and $D4 is preloaded with r0^2...
+
+	vpmuludq	$T0,$D4,$D0		# d0 = h0*r0
+	vpmuludq	$T1,$D4,$D1		# d1 = h1*r0
+	  vmovdqa	$H2,0x20(%r11)				# offload hash
+	vpmuludq	$T2,$D4,$D2		# d3 = h2*r0
+	 vmovdqa	0x10(%rsp),$H2		# r1^2
+	vpmuludq	$T3,$D4,$D3		# d3 = h3*r0
+	vpmuludq	$T4,$D4,$D4		# d4 = h4*r0
+
+	  vmovdqa	$H0,0x00(%r11)				#
+	vpmuludq	0x20(%rsp),$T4,$H0	# h4*s1
+	  vmovdqa	$H1,0x10(%r11)				#
+	vpmuludq	$T3,$H2,$H1		# h3*r1
+	vpaddq		$H0,$D0,$D0		# d0 += h4*s1
+	vpaddq		$H1,$D4,$D4		# d4 += h3*r1
+	  vmovdqa	$H3,0x30(%r11)				#
+	vpmuludq	$T2,$H2,$H0		# h2*r1
+	vpmuludq	$T1,$H2,$H1		# h1*r1
+	vpaddq		$H0,$D3,$D3		# d3 += h2*r1
+	 vmovdqa	0x30(%rsp),$H3		# r2^2
+	vpaddq		$H1,$D2,$D2		# d2 += h1*r1
+	  vmovdqa	$H4,0x40(%r11)				#
+	vpmuludq	$T0,$H2,$H2		# h0*r1
+	 vpmuludq	$T2,$H3,$H0		# h2*r2
+	vpaddq		$H2,$D1,$D1		# d1 += h0*r1
+
+	 vmovdqa	0x40(%rsp),$H4		# s2^2
+	vpaddq		$H0,$D4,$D4		# d4 += h2*r2
+	vpmuludq	$T1,$H3,$H1		# h1*r2
+	vpmuludq	$T0,$H3,$H3		# h0*r2
+	vpaddq		$H1,$D3,$D3		# d3 += h1*r2
+	 vmovdqa	0x50(%rsp),$H2		# r3^2
+	vpaddq		$H3,$D2,$D2		# d2 += h0*r2
+	vpmuludq	$T4,$H4,$H0		# h4*s2
+	vpmuludq	$T3,$H4,$H4		# h3*s2
+	vpaddq		$H0,$D1,$D1		# d1 += h4*s2
+	 vmovdqa	0x60(%rsp),$H3		# s3^2
+	vpaddq		$H4,$D0,$D0		# d0 += h3*s2
+
+	 vmovdqa	0x80(%rsp),$H4		# s4^2
+	vpmuludq	$T1,$H2,$H1		# h1*r3
+	vpmuludq	$T0,$H2,$H2		# h0*r3
+	vpaddq		$H1,$D4,$D4		# d4 += h1*r3
+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
+	vpmuludq	$T4,$H3,$H0		# h4*s3
+	vpmuludq	$T3,$H3,$H1		# h3*s3
+	vpaddq		$H0,$D2,$D2		# d2 += h4*s3
+	 vmovdqu	16*0($inp),$H0				# load input
+	vpaddq		$H1,$D1,$D1		# d1 += h3*s3
+	vpmuludq	$T2,$H3,$H3		# h2*s3
+	 vpmuludq	$T2,$H4,$T2		# h2*s4
+	vpaddq		$H3,$D0,$D0		# d0 += h2*s3
+
+	 vmovdqu	16*1($inp),$H1				#
+	vpaddq		$T2,$D1,$D1		# d1 += h2*s4
+	vpmuludq	$T3,$H4,$T3		# h3*s4
+	vpmuludq	$T4,$H4,$T4		# h4*s4
+	 vpsrldq	\$6,$H0,$H2				# splat input
+	vpaddq		$T3,$D2,$D2		# d2 += h3*s4
+	vpaddq		$T4,$D3,$D3		# d3 += h4*s4
+	 vpsrldq	\$6,$H1,$H3				#
+	vpmuludq	0x70(%rsp),$T0,$T4	# h0*r4
+	vpmuludq	$T1,$H4,$T0		# h1*s4
+	 vpunpckhqdq	$H1,$H0,$H4		# 4
+	vpaddq		$T4,$D4,$D4		# d4 += h0*r4
+	 vmovdqa	-0x90(%r11),$T4		# r0^4
+	vpaddq		$T0,$D0,$D0		# d0 += h1*s4
+
+	vpunpcklqdq	$H1,$H0,$H0		# 0:1
+	vpunpcklqdq	$H3,$H2,$H3		# 2:3
+
+	#vpsrlq		\$40,$H4,$H4		# 4
+	vpsrldq		\$`40/8`,$H4,$H4	# 4
+	vpsrlq		\$26,$H0,$H1
+	vpand		$MASK,$H0,$H0		# 0
+	vpsrlq		\$4,$H3,$H2
+	vpand		$MASK,$H1,$H1		# 1
+	vpand		0(%rcx),$H4,$H4		# .Lmask24
+	vpsrlq		\$30,$H3,$H3
+	vpand		$MASK,$H2,$H2		# 2
+	vpand		$MASK,$H3,$H3		# 3
+	vpor		32(%rcx),$H4,$H4	# padbit, yes, always
+
+	vpaddq		0x00(%r11),$H0,$H0	# add hash value
+	vpaddq		0x10(%r11),$H1,$H1
+	vpaddq		0x20(%r11),$H2,$H2
+	vpaddq		0x30(%r11),$H3,$H3
+	vpaddq		0x40(%r11),$H4,$H4
+
+	lea		16*2($inp),%rax
+	lea		16*4($inp),$inp
+	sub		\$64,$len
+	cmovc		%rax,$inp
+
+	################################################################
+	# Now we accumulate (inp[0:1]+hash)*r^4
+	################################################################
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	vpmuludq	$H0,$T4,$T0		# h0*r0
+	vpmuludq	$H1,$T4,$T1		# h1*r0
+	vpaddq		$T0,$D0,$D0
+	vpaddq		$T1,$D1,$D1
+	 vmovdqa	-0x80(%r11),$T2		# r1^4
+	vpmuludq	$H2,$T4,$T0		# h2*r0
+	vpmuludq	$H3,$T4,$T1		# h3*r0
+	vpaddq		$T0,$D2,$D2
+	vpaddq		$T1,$D3,$D3
+	vpmuludq	$H4,$T4,$T4		# h4*r0
+	 vpmuludq	-0x70(%r11),$H4,$T0	# h4*s1
+	vpaddq		$T4,$D4,$D4
+
+	vpaddq		$T0,$D0,$D0		# d0 += h4*s1
+	vpmuludq	$H2,$T2,$T1		# h2*r1
+	vpmuludq	$H3,$T2,$T0		# h3*r1
+	vpaddq		$T1,$D3,$D3		# d3 += h2*r1
+	 vmovdqa	-0x60(%r11),$T3		# r2^4
+	vpaddq		$T0,$D4,$D4		# d4 += h3*r1
+	vpmuludq	$H1,$T2,$T1		# h1*r1
+	vpmuludq	$H0,$T2,$T2		# h0*r1
+	vpaddq		$T1,$D2,$D2		# d2 += h1*r1
+	vpaddq		$T2,$D1,$D1		# d1 += h0*r1
+
+	 vmovdqa	-0x50(%r11),$T4		# s2^4
+	vpmuludq	$H2,$T3,$T0		# h2*r2
+	vpmuludq	$H1,$T3,$T1		# h1*r2
+	vpaddq		$T0,$D4,$D4		# d4 += h2*r2
+	vpaddq		$T1,$D3,$D3		# d3 += h1*r2
+	 vmovdqa	-0x40(%r11),$T2		# r3^4
+	vpmuludq	$H0,$T3,$T3		# h0*r2
+	vpmuludq	$H4,$T4,$T0		# h4*s2
+	vpaddq		$T3,$D2,$D2		# d2 += h0*r2
+	vpaddq		$T0,$D1,$D1		# d1 += h4*s2
+	 vmovdqa	-0x30(%r11),$T3		# s3^4
+	vpmuludq	$H3,$T4,$T4		# h3*s2
+	 vpmuludq	$H1,$T2,$T1		# h1*r3
+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
+
+	 vmovdqa	-0x10(%r11),$T4		# s4^4
+	vpaddq		$T1,$D4,$D4		# d4 += h1*r3
+	vpmuludq	$H0,$T2,$T2		# h0*r3
+	vpmuludq	$H4,$T3,$T0		# h4*s3
+	vpaddq		$T2,$D3,$D3		# d3 += h0*r3
+	vpaddq		$T0,$D2,$D2		# d2 += h4*s3
+	 vmovdqu	16*2($inp),$T0				# load input
+	vpmuludq	$H3,$T3,$T2		# h3*s3
+	vpmuludq	$H2,$T3,$T3		# h2*s3
+	vpaddq		$T2,$D1,$D1		# d1 += h3*s3
+	 vmovdqu	16*3($inp),$T1				#
+	vpaddq		$T3,$D0,$D0		# d0 += h2*s3
+
+	vpmuludq	$H2,$T4,$H2		# h2*s4
+	vpmuludq	$H3,$T4,$H3		# h3*s4
+	 vpsrldq	\$6,$T0,$T2				# splat input
+	vpaddq		$H2,$D1,$D1		# d1 += h2*s4
+	vpmuludq	$H4,$T4,$H4		# h4*s4
+	 vpsrldq	\$6,$T1,$T3				#
+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*s4
+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*s4
+	vpmuludq	-0x20(%r11),$H0,$H4	# h0*r4
+	vpmuludq	$H1,$T4,$H0
+	 vpunpckhqdq	$T1,$T0,$T4		# 4
+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
+
+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
+	vpunpcklqdq	$T3,$T2,$T3		# 2:3
+
+	#vpsrlq		\$40,$T4,$T4		# 4
+	vpsrldq		\$`40/8`,$T4,$T4	# 4
+	vpsrlq		\$26,$T0,$T1
+	 vmovdqa	0x00(%rsp),$D4		# preload r0^2
+	vpand		$MASK,$T0,$T0		# 0
+	vpsrlq		\$4,$T3,$T2
+	vpand		$MASK,$T1,$T1		# 1
+	vpand		0(%rcx),$T4,$T4		# .Lmask24
+	vpsrlq		\$30,$T3,$T3
+	vpand		$MASK,$T2,$T2		# 2
+	vpand		$MASK,$T3,$T3		# 3
+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
+
+	################################################################
+	# lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+	# and P. Schwabe
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$D1,$H1		# h0 -> h1
+
+	vpsrlq		\$26,$H4,$D0
+	vpand		$MASK,$H4,$H4
+
+	vpsrlq		\$26,$H1,$D1
+	vpand		$MASK,$H1,$H1
+	vpaddq		$D1,$H2,$H2		# h1 -> h2
+
+	vpaddq		$D0,$H0,$H0
+	vpsllq		\$2,$D0,$D0
+	vpaddq		$D0,$H0,$H0		# h4 -> h0
+
+	vpsrlq		\$26,$H2,$D2
+	vpand		$MASK,$H2,$H2
+	vpaddq		$D2,$H3,$H3		# h2 -> h3
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$H1,$H1		# h0 -> h1
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	ja		.Loop_avx
+
+.Lskip_loop_avx:
+	################################################################
+	# multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+	vpshufd		\$0x10,$D4,$D4		# r0^n, xx12 -> x1x2
+	add		\$32,$len
+	jnz		.Long_tail_avx
+
+	vpaddq		$H2,$T2,$T2
+	vpaddq		$H0,$T0,$T0
+	vpaddq		$H1,$T1,$T1
+	vpaddq		$H3,$T3,$T3
+	vpaddq		$H4,$T4,$T4
+
+.Long_tail_avx:
+	vmovdqa		$H2,0x20(%r11)
+	vmovdqa		$H0,0x00(%r11)
+	vmovdqa		$H1,0x10(%r11)
+	vmovdqa		$H3,0x30(%r11)
+	vmovdqa		$H4,0x40(%r11)
+
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+	vpmuludq	$T2,$D4,$D2		# d2 = h2*r0
+	vpmuludq	$T0,$D4,$D0		# d0 = h0*r0
+	 vpshufd	\$0x10,`16*1-64`($ctx),$H2		# r1^n
+	vpmuludq	$T1,$D4,$D1		# d1 = h1*r0
+	vpmuludq	$T3,$D4,$D3		# d3 = h3*r0
+	vpmuludq	$T4,$D4,$D4		# d4 = h4*r0
+
+	vpmuludq	$T3,$H2,$H0		# h3*r1
+	vpaddq		$H0,$D4,$D4		# d4 += h3*r1
+	 vpshufd	\$0x10,`16*2-64`($ctx),$H3		# s1^n
+	vpmuludq	$T2,$H2,$H1		# h2*r1
+	vpaddq		$H1,$D3,$D3		# d3 += h2*r1
+	 vpshufd	\$0x10,`16*3-64`($ctx),$H4		# r2^n
+	vpmuludq	$T1,$H2,$H0		# h1*r1
+	vpaddq		$H0,$D2,$D2		# d2 += h1*r1
+	vpmuludq	$T0,$H2,$H2		# h0*r1
+	vpaddq		$H2,$D1,$D1		# d1 += h0*r1
+	vpmuludq	$T4,$H3,$H3		# h4*s1
+	vpaddq		$H3,$D0,$D0		# d0 += h4*s1
+
+	 vpshufd	\$0x10,`16*4-64`($ctx),$H2		# s2^n
+	vpmuludq	$T2,$H4,$H1		# h2*r2
+	vpaddq		$H1,$D4,$D4		# d4 += h2*r2
+	vpmuludq	$T1,$H4,$H0		# h1*r2
+	vpaddq		$H0,$D3,$D3		# d3 += h1*r2
+	 vpshufd	\$0x10,`16*5-64`($ctx),$H3		# r3^n
+	vpmuludq	$T0,$H4,$H4		# h0*r2
+	vpaddq		$H4,$D2,$D2		# d2 += h0*r2
+	vpmuludq	$T4,$H2,$H1		# h4*s2
+	vpaddq		$H1,$D1,$D1		# d1 += h4*s2
+	 vpshufd	\$0x10,`16*6-64`($ctx),$H4		# s3^n
+	vpmuludq	$T3,$H2,$H2		# h3*s2
+	vpaddq		$H2,$D0,$D0		# d0 += h3*s2
+
+	vpmuludq	$T1,$H3,$H0		# h1*r3
+	vpaddq		$H0,$D4,$D4		# d4 += h1*r3
+	vpmuludq	$T0,$H3,$H3		# h0*r3
+	vpaddq		$H3,$D3,$D3		# d3 += h0*r3
+	 vpshufd	\$0x10,`16*7-64`($ctx),$H2		# r4^n
+	vpmuludq	$T4,$H4,$H1		# h4*s3
+	vpaddq		$H1,$D2,$D2		# d2 += h4*s3
+	 vpshufd	\$0x10,`16*8-64`($ctx),$H3		# s4^n
+	vpmuludq	$T3,$H4,$H0		# h3*s3
+	vpaddq		$H0,$D1,$D1		# d1 += h3*s3
+	vpmuludq	$T2,$H4,$H4		# h2*s3
+	vpaddq		$H4,$D0,$D0		# d0 += h2*s3
+
+	vpmuludq	$T0,$H2,$H2		# h0*r4
+	vpaddq		$H2,$D4,$D4		# h4 = d4 + h0*r4
+	vpmuludq	$T4,$H3,$H1		# h4*s4
+	vpaddq		$H1,$D3,$D3		# h3 = d3 + h4*s4
+	vpmuludq	$T3,$H3,$H0		# h3*s4
+	vpaddq		$H0,$D2,$D2		# h2 = d2 + h3*s4
+	vpmuludq	$T2,$H3,$H1		# h2*s4
+	vpaddq		$H1,$D1,$D1		# h1 = d1 + h2*s4
+	vpmuludq	$T1,$H3,$H3		# h1*s4
+	vpaddq		$H3,$D0,$D0		# h0 = d0 + h1*s4
+
+	jz		.Lshort_tail_avx
+
+	vmovdqu		16*0($inp),$H0		# load input
+	vmovdqu		16*1($inp),$H1
+
+	vpsrldq		\$6,$H0,$H2		# splat input
+	vpsrldq		\$6,$H1,$H3
+	vpunpckhqdq	$H1,$H0,$H4		# 4
+	vpunpcklqdq	$H1,$H0,$H0		# 0:1
+	vpunpcklqdq	$H3,$H2,$H3		# 2:3
+
+	vpsrlq		\$40,$H4,$H4		# 4
+	vpsrlq		\$26,$H0,$H1
+	vpand		$MASK,$H0,$H0		# 0
+	vpsrlq		\$4,$H3,$H2
+	vpand		$MASK,$H1,$H1		# 1
+	vpsrlq		\$30,$H3,$H3
+	vpand		$MASK,$H2,$H2		# 2
+	vpand		$MASK,$H3,$H3		# 3
+	vpor		32(%rcx),$H4,$H4	# padbit, yes, always
+
+	vpshufd		\$0x32,`16*0-64`($ctx),$T4	# r0^n, 34xx -> x3x4
+	vpaddq		0x00(%r11),$H0,$H0
+	vpaddq		0x10(%r11),$H1,$H1
+	vpaddq		0x20(%r11),$H2,$H2
+	vpaddq		0x30(%r11),$H3,$H3
+	vpaddq		0x40(%r11),$H4,$H4
+
+	################################################################
+	# multiply (inp[0:1]+hash) by r^4:r^3 and accumulate
+
+	vpmuludq	$H0,$T4,$T0		# h0*r0
+	vpaddq		$T0,$D0,$D0		# d0 += h0*r0
+	vpmuludq	$H1,$T4,$T1		# h1*r0
+	vpaddq		$T1,$D1,$D1		# d1 += h1*r0
+	vpmuludq	$H2,$T4,$T0		# h2*r0
+	vpaddq		$T0,$D2,$D2		# d2 += h2*r0
+	 vpshufd	\$0x32,`16*1-64`($ctx),$T2		# r1^n
+	vpmuludq	$H3,$T4,$T1		# h3*r0
+	vpaddq		$T1,$D3,$D3		# d3 += h3*r0
+	vpmuludq	$H4,$T4,$T4		# h4*r0
+	vpaddq		$T4,$D4,$D4		# d4 += h4*r0
+
+	vpmuludq	$H3,$T2,$T0		# h3*r1
+	vpaddq		$T0,$D4,$D4		# d4 += h3*r1
+	 vpshufd	\$0x32,`16*2-64`($ctx),$T3		# s1
+	vpmuludq	$H2,$T2,$T1		# h2*r1
+	vpaddq		$T1,$D3,$D3		# d3 += h2*r1
+	 vpshufd	\$0x32,`16*3-64`($ctx),$T4		# r2
+	vpmuludq	$H1,$T2,$T0		# h1*r1
+	vpaddq		$T0,$D2,$D2		# d2 += h1*r1
+	vpmuludq	$H0,$T2,$T2		# h0*r1
+	vpaddq		$T2,$D1,$D1		# d1 += h0*r1
+	vpmuludq	$H4,$T3,$T3		# h4*s1
+	vpaddq		$T3,$D0,$D0		# d0 += h4*s1
+
+	 vpshufd	\$0x32,`16*4-64`($ctx),$T2		# s2
+	vpmuludq	$H2,$T4,$T1		# h2*r2
+	vpaddq		$T1,$D4,$D4		# d4 += h2*r2
+	vpmuludq	$H1,$T4,$T0		# h1*r2
+	vpaddq		$T0,$D3,$D3		# d3 += h1*r2
+	 vpshufd	\$0x32,`16*5-64`($ctx),$T3		# r3
+	vpmuludq	$H0,$T4,$T4		# h0*r2
+	vpaddq		$T4,$D2,$D2		# d2 += h0*r2
+	vpmuludq	$H4,$T2,$T1		# h4*s2
+	vpaddq		$T1,$D1,$D1		# d1 += h4*s2
+	 vpshufd	\$0x32,`16*6-64`($ctx),$T4		# s3
+	vpmuludq	$H3,$T2,$T2		# h3*s2
+	vpaddq		$T2,$D0,$D0		# d0 += h3*s2
+
+	vpmuludq	$H1,$T3,$T0		# h1*r3
+	vpaddq		$T0,$D4,$D4		# d4 += h1*r3
+	vpmuludq	$H0,$T3,$T3		# h0*r3
+	vpaddq		$T3,$D3,$D3		# d3 += h0*r3
+	 vpshufd	\$0x32,`16*7-64`($ctx),$T2		# r4
+	vpmuludq	$H4,$T4,$T1		# h4*s3
+	vpaddq		$T1,$D2,$D2		# d2 += h4*s3
+	 vpshufd	\$0x32,`16*8-64`($ctx),$T3		# s4
+	vpmuludq	$H3,$T4,$T0		# h3*s3
+	vpaddq		$T0,$D1,$D1		# d1 += h3*s3
+	vpmuludq	$H2,$T4,$T4		# h2*s3
+	vpaddq		$T4,$D0,$D0		# d0 += h2*s3
+
+	vpmuludq	$H0,$T2,$T2		# h0*r4
+	vpaddq		$T2,$D4,$D4		# d4 += h0*r4
+	vpmuludq	$H4,$T3,$T1		# h4*s4
+	vpaddq		$T1,$D3,$D3		# d3 += h4*s4
+	vpmuludq	$H3,$T3,$T0		# h3*s4
+	vpaddq		$T0,$D2,$D2		# d2 += h3*s4
+	vpmuludq	$H2,$T3,$T1		# h2*s4
+	vpaddq		$T1,$D1,$D1		# d1 += h2*s4
+	vpmuludq	$H1,$T3,$T3		# h1*s4
+	vpaddq		$T3,$D0,$D0		# d0 += h1*s4
+
+.Lshort_tail_avx:
+	################################################################
+	# horizontal addition
+
+	vpsrldq		\$8,$D4,$T4
+	vpsrldq		\$8,$D3,$T3
+	vpsrldq		\$8,$D1,$T1
+	vpsrldq		\$8,$D0,$T0
+	vpsrldq		\$8,$D2,$T2
+	vpaddq		$T3,$D3,$D3
+	vpaddq		$T4,$D4,$D4
+	vpaddq		$T0,$D0,$D0
+	vpaddq		$T1,$D1,$D1
+	vpaddq		$T2,$D2,$D2
+
+	################################################################
+	# lazy reduction
+
+	vpsrlq		\$26,$D3,$H3
+	vpand		$MASK,$D3,$D3
+	vpaddq		$H3,$D4,$D4		# h3 -> h4
+
+	vpsrlq		\$26,$D0,$H0
+	vpand		$MASK,$D0,$D0
+	vpaddq		$H0,$D1,$D1		# h0 -> h1
+
+	vpsrlq		\$26,$D4,$H4
+	vpand		$MASK,$D4,$D4
+
+	vpsrlq		\$26,$D1,$H1
+	vpand		$MASK,$D1,$D1
+	vpaddq		$H1,$D2,$D2		# h1 -> h2
+
+	vpaddq		$H4,$D0,$D0
+	vpsllq		\$2,$H4,$H4
+	vpaddq		$H4,$D0,$D0		# h4 -> h0
+
+	vpsrlq		\$26,$D2,$H2
+	vpand		$MASK,$D2,$D2
+	vpaddq		$H2,$D3,$D3		# h2 -> h3
+
+	vpsrlq		\$26,$D0,$H0
+	vpand		$MASK,$D0,$D0
+	vpaddq		$H0,$D1,$D1		# h0 -> h1
+
+	vpsrlq		\$26,$D3,$H3
+	vpand		$MASK,$D3,$D3
+	vpaddq		$H3,$D4,$D4		# h3 -> h4
+
+	vmovd		$D0,`4*0-48-64`($ctx)	# save partially reduced
+	vmovd		$D1,`4*1-48-64`($ctx)
+	vmovd		$D2,`4*2-48-64`($ctx)
+	vmovd		$D3,`4*3-48-64`($ctx)
+	vmovd		$D4,`4*4-48-64`($ctx)
+___
+$code.=<<___	if ($win64);
+	vmovdqa		0x50(%r11),%xmm6
+	vmovdqa		0x60(%r11),%xmm7
+	vmovdqa		0x70(%r11),%xmm8
+	vmovdqa		0x80(%r11),%xmm9
+	vmovdqa		0x90(%r11),%xmm10
+	vmovdqa		0xa0(%r11),%xmm11
+	vmovdqa		0xb0(%r11),%xmm12
+	vmovdqa		0xc0(%r11),%xmm13
+	vmovdqa		0xd0(%r11),%xmm14
+	vmovdqa		0xe0(%r11),%xmm15
+	lea		0xf8(%r11),%rsp
+.Ldo_avx_epilogue:
+___
+$code.=<<___	if (!$win64);
+	lea		0x58(%r11),%rsp
+___
+$code.=<<___;
+	vzeroupper
+	ret
+.size	poly1305_blocks_avx,.-poly1305_blocks_avx
+
+.type	poly1305_emit_avx,\@function,3
+.align	32
+poly1305_emit_avx:
+	cmpl	\$0,20($ctx)	# is_base2_26?
+	je	.Lemit
+
+	mov	0($ctx),%eax	# load hash value base 2^26
+	mov	4($ctx),%ecx
+	mov	8($ctx),%r8d
+	mov	12($ctx),%r11d
+	mov	16($ctx),%r10d
+
+	shl	\$26,%rcx	# base 2^26 -> base 2^64
+	mov	%r8,%r9
+	shl	\$52,%r8
+	add	%rcx,%rax
+	shr	\$12,%r9
+	add	%rax,%r8	# h0
+	adc	\$0,%r9
+
+	shl	\$14,%r11
+	mov	%r10,%rax
+	shr	\$24,%r10
+	add	%r11,%r9
+	shl	\$40,%rax
+	add	%rax,%r9	# h1
+	adc	\$0,%r10	# h2
+
+	mov	%r10,%rax	# could be partially reduced, so reduce
+	mov	%r10,%rcx
+	and	\$3,%r10
+	shr	\$2,%rax
+	and	\$-4,%rcx
+	add	%rcx,%rax
+	add	%rax,%r8
+	adc	\$0,%r9
+
+	mov	%r8,%rax
+	add	\$5,%r8		# compare to modulus
+	mov	%r9,%rcx
+	adc	\$0,%r9
+	adc	\$0,%r10
+	shr	\$2,%r10	# did 130-bit value overfow?
+	cmovnz	%r8,%rax
+	cmovnz	%r9,%rcx
+
+	add	0($nonce),%rax	# accumulate nonce
+	adc	8($nonce),%rcx
+	mov	%rax,0($mac)	# write result
+	mov	%rcx,8($mac)
+
+	ret
+.size	poly1305_emit_avx,.-poly1305_emit_avx
+___
+
+if ($avx>1) {
+my ($H0,$H1,$H2,$H3,$H4, $MASK, $T4,$T0,$T1,$T2,$T3, $D0,$D1,$D2,$D3,$D4) =
+    map("%ymm$_",(0..15));
+my $S4=$MASK;
+
+$code.=<<___;
+.type	poly1305_blocks_avx2,\@function,4
+.align	32
+poly1305_blocks_avx2:
+	mov	20($ctx),%r8d		# is_base2_26
+	cmp	\$128,$len
+	jae	.Lblocks_avx2
+	test	%r8d,%r8d
+	jz	.Lblocks
+
+.Lblocks_avx2:
+	and	\$-16,$len
+	jz	.Lno_data_avx2
+
+	vzeroupper
+
+	test	%r8d,%r8d
+	jz	.Lbase2_64_avx2
+
+	test	\$63,$len
+	jz	.Leven_avx2
+
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lblocks_avx2_body:
+
+	mov	$len,%r15		# reassign $len
+
+	mov	0($ctx),$d1		# load hash value
+	mov	8($ctx),$d2
+	mov	16($ctx),$h2#d
+
+	mov	24($ctx),$r0		# load r
+	mov	32($ctx),$s1
+
+	################################# base 2^26 -> base 2^64
+	mov	$d1#d,$h0#d
+	and	\$-1<<31,$d1
+	mov	$d2,$r1			# borrow $r1
+	mov	$d2#d,$h1#d
+	and	\$-1<<31,$d2
+
+	shr	\$6,$d1
+	shl	\$52,$r1
+	add	$d1,$h0
+	shr	\$12,$h1
+	shr	\$18,$d2
+	add	$r1,$h0
+	adc	$d2,$h1
+
+	mov	$h2,$d1
+	shl	\$40,$d1
+	shr	\$24,$h2
+	add	$d1,$h1
+	adc	\$0,$h2			# can be partially reduced...
+
+	mov	\$-4,$d2		# ... so reduce
+	mov	$h2,$d1
+	and	$h2,$d2
+	shr	\$2,$d1
+	and	\$3,$h2
+	add	$d2,$d1			# =*5
+	add	$d1,$h0
+	adc	\$0,$h1
+
+	mov	$s1,$r1
+	mov	$s1,%rax
+	shr	\$2,$s1
+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
+
+.Lbase2_26_pre_avx2:
+	add	0($inp),$h0		# accumulate input
+	adc	8($inp),$h1
+	lea	16($inp),$inp
+	adc	$padbit,$h2
+	sub	\$16,%r15
+
+	call	__poly1305_block
+	mov	$r1,%rax
+
+	test	\$63,%r15
+	jnz	.Lbase2_26_pre_avx2
+
+	test	$padbit,$padbit		# if $padbit is zero,
+	jz	.Lstore_base2_64_avx2	# store hash in base 2^64 format
+
+	################################# base 2^64 -> base 2^26
+	mov	$h0,%rax
+	mov	$h0,%rdx
+	shr	\$52,$h0
+	mov	$h1,$r0
+	mov	$h1,$r1
+	shr	\$26,%rdx
+	and	\$0x3ffffff,%rax	# h[0]
+	shl	\$12,$r0
+	and	\$0x3ffffff,%rdx	# h[1]
+	shr	\$14,$h1
+	or	$r0,$h0
+	shl	\$24,$h2
+	and	\$0x3ffffff,$h0		# h[2]
+	shr	\$40,$r1
+	and	\$0x3ffffff,$h1		# h[3]
+	or	$r1,$h2			# h[4]
+
+	test	%r15,%r15
+	jz	.Lstore_base2_26_avx2
+
+	vmovd	%rax#d,%x#$H0
+	vmovd	%rdx#d,%x#$H1
+	vmovd	$h0#d,%x#$H2
+	vmovd	$h1#d,%x#$H3
+	vmovd	$h2#d,%x#$H4
+	jmp	.Lproceed_avx2
+
+.align	32
+.Lstore_base2_64_avx2:
+	mov	$h0,0($ctx)
+	mov	$h1,8($ctx)
+	mov	$h2,16($ctx)		# note that is_base2_26 is zeroed
+	jmp	.Ldone_avx2
+
+.align	16
+.Lstore_base2_26_avx2:
+	mov	%rax#d,0($ctx)		# store hash value base 2^26
+	mov	%rdx#d,4($ctx)
+	mov	$h0#d,8($ctx)
+	mov	$h1#d,12($ctx)
+	mov	$h2#d,16($ctx)
+.align	16
+.Ldone_avx2:
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%r12
+	mov	32(%rsp),%rbp
+	mov	40(%rsp),%rbx
+	lea	48(%rsp),%rsp
+.Lno_data_avx2:
+.Lblocks_avx2_epilogue:
+	ret
+
+.align	32
+.Lbase2_64_avx2:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lbase2_64_avx2_body:
+
+	mov	$len,%r15		# reassign $len
+
+	mov	24($ctx),$r0		# load r
+	mov	32($ctx),$s1
+
+	mov	0($ctx),$h0		# load hash value
+	mov	8($ctx),$h1
+	mov	16($ctx),$h2#d
+
+	mov	$s1,$r1
+	mov	$s1,%rax
+	shr	\$2,$s1
+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
+
+	test	\$63,$len
+	jz	.Linit_avx2
+
+.Lbase2_64_pre_avx2:
+	add	0($inp),$h0		# accumulate input
+	adc	8($inp),$h1
+	lea	16($inp),$inp
+	adc	$padbit,$h2
+	sub	\$16,%r15
+
+	call	__poly1305_block
+	mov	$r1,%rax
+
+	test	\$63,%r15
+	jnz	.Lbase2_64_pre_avx2
+
+.Linit_avx2:
+	################################# base 2^64 -> base 2^26
+	mov	$h0,%rax
+	mov	$h0,%rdx
+	shr	\$52,$h0
+	mov	$h1,$d1
+	mov	$h1,$d2
+	shr	\$26,%rdx
+	and	\$0x3ffffff,%rax	# h[0]
+	shl	\$12,$d1
+	and	\$0x3ffffff,%rdx	# h[1]
+	shr	\$14,$h1
+	or	$d1,$h0
+	shl	\$24,$h2
+	and	\$0x3ffffff,$h0		# h[2]
+	shr	\$40,$d2
+	and	\$0x3ffffff,$h1		# h[3]
+	or	$d2,$h2			# h[4]
+
+	vmovd	%rax#d,%x#$H0
+	vmovd	%rdx#d,%x#$H1
+	vmovd	$h0#d,%x#$H2
+	vmovd	$h1#d,%x#$H3
+	vmovd	$h2#d,%x#$H4
+	movl	\$1,20($ctx)		# set is_base2_26
+
+	call	__poly1305_init_avx
+
+.Lproceed_avx2:
+	mov	%r15,$len
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%r12
+	mov	32(%rsp),%rbp
+	mov	40(%rsp),%rbx
+	lea	48(%rsp),%rax
+	lea	48(%rsp),%rsp
+.Lbase2_64_avx2_epilogue:
+	jmp	.Ldo_avx2
+
+.align	32
+.Leven_avx2:
+	vmovd		4*0($ctx),%x#$H0	# load hash value base 2^26
+	vmovd		4*1($ctx),%x#$H1
+	vmovd		4*2($ctx),%x#$H2
+	vmovd		4*3($ctx),%x#$H3
+	vmovd		4*4($ctx),%x#$H4
+
+.Ldo_avx2:
+___
+$code.=<<___	if (!$win64);
+	lea		-8(%rsp),%r11
+	sub		\$0x128,%rsp
+___
+$code.=<<___	if ($win64);
+	lea		-0xf8(%rsp),%r11
+	sub		\$0x1c8,%rsp
+	vmovdqa		%xmm6,0x50(%r11)
+	vmovdqa		%xmm7,0x60(%r11)
+	vmovdqa		%xmm8,0x70(%r11)
+	vmovdqa		%xmm9,0x80(%r11)
+	vmovdqa		%xmm10,0x90(%r11)
+	vmovdqa		%xmm11,0xa0(%r11)
+	vmovdqa		%xmm12,0xb0(%r11)
+	vmovdqa		%xmm13,0xc0(%r11)
+	vmovdqa		%xmm14,0xd0(%r11)
+	vmovdqa		%xmm15,0xe0(%r11)
+.Ldo_avx2_body:
+___
+$code.=<<___;
+	lea		48+64($ctx),$ctx	# size optimization
+	lea		.Lconst(%rip),%rcx
+
+	# expand and copy pre-calculated table to stack
+	vmovdqu		`16*0-64`($ctx),%x#$T2
+	and		\$-512,%rsp
+	vmovdqu		`16*1-64`($ctx),%x#$T3
+	vmovdqu		`16*2-64`($ctx),%x#$T4
+	vmovdqu		`16*3-64`($ctx),%x#$D0
+	vmovdqu		`16*4-64`($ctx),%x#$D1
+	vmovdqu		`16*5-64`($ctx),%x#$D2
+	vmovdqu		`16*6-64`($ctx),%x#$D3
+	vpermq		\$0x15,$T2,$T2		# 00003412 -> 12343434
+	vmovdqu		`16*7-64`($ctx),%x#$D4
+	vpermq		\$0x15,$T3,$T3
+	vpshufd		\$0xc8,$T2,$T2		# 12343434 -> 14243444
+	vmovdqu		`16*8-64`($ctx),%x#$MASK
+	vpermq		\$0x15,$T4,$T4
+	vpshufd		\$0xc8,$T3,$T3
+	vmovdqa		$T2,0x00(%rsp)
+	vpermq		\$0x15,$D0,$D0
+	vpshufd		\$0xc8,$T4,$T4
+	vmovdqa		$T3,0x20(%rsp)
+	vpermq		\$0x15,$D1,$D1
+	vpshufd		\$0xc8,$D0,$D0
+	vmovdqa		$T4,0x40(%rsp)
+	vpermq		\$0x15,$D2,$D2
+	vpshufd		\$0xc8,$D1,$D1
+	vmovdqa		$D0,0x60(%rsp)
+	vpermq		\$0x15,$D3,$D3
+	vpshufd		\$0xc8,$D2,$D2
+	vmovdqa		$D1,0x80(%rsp)
+	vpermq		\$0x15,$D4,$D4
+	vpshufd		\$0xc8,$D3,$D3
+	vmovdqa		$D2,0xa0(%rsp)
+	vpermq		\$0x15,$MASK,$MASK
+	vpshufd		\$0xc8,$D4,$D4
+	vmovdqa		$D3,0xc0(%rsp)
+	vpshufd		\$0xc8,$MASK,$MASK
+	vmovdqa		$D4,0xe0(%rsp)
+	vmovdqa		$MASK,0x100(%rsp)
+	vmovdqa		64(%rcx),$MASK		# .Lmask26
+
+	################################################################
+	# load input
+	vmovdqu		16*0($inp),%x#$T0
+	vmovdqu		16*1($inp),%x#$T1
+	vinserti128	\$1,16*2($inp),$T0,$T0
+	vinserti128	\$1,16*3($inp),$T1,$T1
+	lea		16*4($inp),$inp
+
+	vpsrldq		\$6,$T0,$T2		# splat input
+	vpsrldq		\$6,$T1,$T3
+	vpunpckhqdq	$T1,$T0,$T4		# 4
+	vpunpcklqdq	$T3,$T2,$T2		# 2:3
+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
+
+	vpsrlq		\$30,$T2,$T3
+	vpsrlq		\$4,$T2,$T2
+	vpsrlq		\$26,$T0,$T1
+	vpsrlq		\$40,$T4,$T4		# 4
+	vpand		$MASK,$T2,$T2		# 2
+	vpand		$MASK,$T0,$T0		# 0
+	vpand		$MASK,$T1,$T1		# 1
+	vpand		$MASK,$T3,$T3		# 3
+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
+
+	lea		0x90(%rsp),%rax		# size optimization
+	vpaddq		$H2,$T2,$H2		# accumulate input
+	sub		\$64,$len
+	jz		.Ltail_avx2
+	jmp		.Loop_avx2
+
+.align	32
+.Loop_avx2:
+	################################################################
+	# ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
+	# ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
+	# ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
+	# ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
+	#   \________/\________/
+	################################################################
+	#vpaddq		$H2,$T2,$H2		# accumulate input
+	vpaddq		$H0,$T0,$H0
+	vmovdqa		`32*0`(%rsp),$T0	# r0^4
+	vpaddq		$H1,$T1,$H1
+	vmovdqa		`32*1`(%rsp),$T1	# r1^4
+	vpaddq		$H3,$T3,$H3
+	vmovdqa		`32*3`(%rsp),$T2	# r2^4
+	vpaddq		$H4,$T4,$H4
+	vmovdqa		`32*6-0x90`(%rax),$T3	# s3^4
+	vmovdqa		`32*8-0x90`(%rax),$S4	# s4^4
+
+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+	#
+	# however, as h2 is "chronologically" first one available pull
+	# corresponding operations up, so it's
+	#
+	# d4 = h2*r2   + h4*r0 + h3*r1             + h1*r3   + h0*r4
+	# d3 = h2*r1   + h3*r0           + h1*r2   + h0*r3   + h4*5*r4
+	# d2 = h2*r0           + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
+	# d1 = h2*5*r4 + h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3
+	# d0 = h2*5*r3 + h0*r0 + h4*5*r1 + h3*5*r2           + h1*5*r4
+
+	vpmuludq	$H2,$T0,$D2		# d2 = h2*r0
+	vpmuludq	$H2,$T1,$D3		# d3 = h2*r1
+	vpmuludq	$H2,$T2,$D4		# d4 = h2*r2
+	vpmuludq	$H2,$T3,$D0		# d0 = h2*s3
+	vpmuludq	$H2,$S4,$D1		# d1 = h2*s4
+
+	vpmuludq	$H0,$T1,$T4		# h0*r1
+	vpmuludq	$H1,$T1,$H2		# h1*r1, borrow $H2 as temp
+	vpaddq		$T4,$D1,$D1		# d1 += h0*r1
+	vpaddq		$H2,$D2,$D2		# d2 += h1*r1
+	vpmuludq	$H3,$T1,$T4		# h3*r1
+	vpmuludq	`32*2`(%rsp),$H4,$H2	# h4*s1
+	vpaddq		$T4,$D4,$D4		# d4 += h3*r1
+	vpaddq		$H2,$D0,$D0		# d0 += h4*s1
+	 vmovdqa	`32*4-0x90`(%rax),$T1	# s2
+
+	vpmuludq	$H0,$T0,$T4		# h0*r0
+	vpmuludq	$H1,$T0,$H2		# h1*r0
+	vpaddq		$T4,$D0,$D0		# d0 += h0*r0
+	vpaddq		$H2,$D1,$D1		# d1 += h1*r0
+	vpmuludq	$H3,$T0,$T4		# h3*r0
+	vpmuludq	$H4,$T0,$H2		# h4*r0
+	 vmovdqu	16*0($inp),%x#$T0	# load input
+	vpaddq		$T4,$D3,$D3		# d3 += h3*r0
+	vpaddq		$H2,$D4,$D4		# d4 += h4*r0
+	 vinserti128	\$1,16*2($inp),$T0,$T0
+
+	vpmuludq	$H3,$T1,$T4		# h3*s2
+	vpmuludq	$H4,$T1,$H2		# h4*s2
+	 vmovdqu	16*1($inp),%x#$T1
+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
+	vpaddq		$H2,$D1,$D1		# d1 += h4*s2
+	 vmovdqa	`32*5-0x90`(%rax),$H2	# r3
+	vpmuludq	$H1,$T2,$T4		# h1*r2
+	vpmuludq	$H0,$T2,$T2		# h0*r2
+	vpaddq		$T4,$D3,$D3		# d3 += h1*r2
+	vpaddq		$T2,$D2,$D2		# d2 += h0*r2
+	 vinserti128	\$1,16*3($inp),$T1,$T1
+	 lea		16*4($inp),$inp
+
+	vpmuludq	$H1,$H2,$T4		# h1*r3
+	vpmuludq	$H0,$H2,$H2		# h0*r3
+	 vpsrldq	\$6,$T0,$T2		# splat input
+	vpaddq		$T4,$D4,$D4		# d4 += h1*r3
+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
+	vpmuludq	$H3,$T3,$T4		# h3*s3
+	vpmuludq	$H4,$T3,$H2		# h4*s3
+	 vpsrldq	\$6,$T1,$T3
+	vpaddq		$T4,$D1,$D1		# d1 += h3*s3
+	vpaddq		$H2,$D2,$D2		# d2 += h4*s3
+	 vpunpckhqdq	$T1,$T0,$T4		# 4
+
+	vpmuludq	$H3,$S4,$H3		# h3*s4
+	vpmuludq	$H4,$S4,$H4		# h4*s4
+	 vpunpcklqdq	$T1,$T0,$T0		# 0:1
+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*r4
+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*r4
+	 vpunpcklqdq	$T3,$T2,$T3		# 2:3
+	vpmuludq	`32*7-0x90`(%rax),$H0,$H4	# h0*r4
+	vpmuludq	$H1,$S4,$H0		# h1*s4
+	vmovdqa		64(%rcx),$MASK		# .Lmask26
+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
+
+	################################################################
+	# lazy reduction (interleaved with tail of input splat)
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$D1,$H1		# h0 -> h1
+
+	vpsrlq		\$26,$H4,$D4
+	vpand		$MASK,$H4,$H4
+
+	 vpsrlq		\$4,$T3,$T2
+
+	vpsrlq		\$26,$H1,$D1
+	vpand		$MASK,$H1,$H1
+	vpaddq		$D1,$H2,$H2		# h1 -> h2
+
+	vpaddq		$D4,$H0,$H0
+	vpsllq		\$2,$D4,$D4
+	vpaddq		$D4,$H0,$H0		# h4 -> h0
+
+	 vpand		$MASK,$T2,$T2		# 2
+	 vpsrlq		\$26,$T0,$T1
+
+	vpsrlq		\$26,$H2,$D2
+	vpand		$MASK,$H2,$H2
+	vpaddq		$D2,$H3,$H3		# h2 -> h3
+
+	 vpaddq		$T2,$H2,$H2		# modulo-scheduled
+	 vpsrlq		\$30,$T3,$T3
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$H1,$H1		# h0 -> h1
+
+	 vpsrlq		\$40,$T4,$T4		# 4
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	 vpand		$MASK,$T0,$T0		# 0
+	 vpand		$MASK,$T1,$T1		# 1
+	 vpand		$MASK,$T3,$T3		# 3
+	 vpor		32(%rcx),$T4,$T4	# padbit, yes, always
+
+	sub		\$64,$len
+	jnz		.Loop_avx2
+
+	.byte		0x66,0x90
+.Ltail_avx2:
+	################################################################
+	# while above multiplications were by r^4 in all lanes, in last
+	# iteration we multiply least significant lane by r^4 and most
+	# significant one by r, so copy of above except that references
+	# to the precomputed table are displaced by 4...
+
+	#vpaddq		$H2,$T2,$H2		# accumulate input
+	vpaddq		$H0,$T0,$H0
+	vmovdqu		`32*0+4`(%rsp),$T0	# r0^4
+	vpaddq		$H1,$T1,$H1
+	vmovdqu		`32*1+4`(%rsp),$T1	# r1^4
+	vpaddq		$H3,$T3,$H3
+	vmovdqu		`32*3+4`(%rsp),$T2	# r2^4
+	vpaddq		$H4,$T4,$H4
+	vmovdqu		`32*6+4-0x90`(%rax),$T3	# s3^4
+	vmovdqu		`32*8+4-0x90`(%rax),$S4	# s4^4
+
+	vpmuludq	$H2,$T0,$D2		# d2 = h2*r0
+	vpmuludq	$H2,$T1,$D3		# d3 = h2*r1
+	vpmuludq	$H2,$T2,$D4		# d4 = h2*r2
+	vpmuludq	$H2,$T3,$D0		# d0 = h2*s3
+	vpmuludq	$H2,$S4,$D1		# d1 = h2*s4
+
+	vpmuludq	$H0,$T1,$T4		# h0*r1
+	vpmuludq	$H1,$T1,$H2		# h1*r1
+	vpaddq		$T4,$D1,$D1		# d1 += h0*r1
+	vpaddq		$H2,$D2,$D2		# d2 += h1*r1
+	vpmuludq	$H3,$T1,$T4		# h3*r1
+	vpmuludq	`32*2+4`(%rsp),$H4,$H2	# h4*s1
+	vpaddq		$T4,$D4,$D4		# d4 += h3*r1
+	vpaddq		$H2,$D0,$D0		# d0 += h4*s1
+
+	vpmuludq	$H0,$T0,$T4		# h0*r0
+	vpmuludq	$H1,$T0,$H2		# h1*r0
+	vpaddq		$T4,$D0,$D0		# d0 += h0*r0
+	 vmovdqu	`32*4+4-0x90`(%rax),$T1	# s2
+	vpaddq		$H2,$D1,$D1		# d1 += h1*r0
+	vpmuludq	$H3,$T0,$T4		# h3*r0
+	vpmuludq	$H4,$T0,$H2		# h4*r0
+	vpaddq		$T4,$D3,$D3		# d3 += h3*r0
+	vpaddq		$H2,$D4,$D4		# d4 += h4*r0
+
+	vpmuludq	$H3,$T1,$T4		# h3*s2
+	vpmuludq	$H4,$T1,$H2		# h4*s2
+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
+	vpaddq		$H2,$D1,$D1		# d1 += h4*s2
+	 vmovdqu	`32*5+4-0x90`(%rax),$H2	# r3
+	vpmuludq	$H1,$T2,$T4		# h1*r2
+	vpmuludq	$H0,$T2,$T2		# h0*r2
+	vpaddq		$T4,$D3,$D3		# d3 += h1*r2
+	vpaddq		$T2,$D2,$D2		# d2 += h0*r2
+
+	vpmuludq	$H1,$H2,$T4		# h1*r3
+	vpmuludq	$H0,$H2,$H2		# h0*r3
+	vpaddq		$T4,$D4,$D4		# d4 += h1*r3
+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
+	vpmuludq	$H3,$T3,$T4		# h3*s3
+	vpmuludq	$H4,$T3,$H2		# h4*s3
+	vpaddq		$T4,$D1,$D1		# d1 += h3*s3
+	vpaddq		$H2,$D2,$D2		# d2 += h4*s3
+
+	vpmuludq	$H3,$S4,$H3		# h3*s4
+	vpmuludq	$H4,$S4,$H4		# h4*s4
+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*r4
+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*r4
+	vpmuludq	`32*7+4-0x90`(%rax),$H0,$H4		# h0*r4
+	vpmuludq	$H1,$S4,$H0		# h1*s4
+	vmovdqa		64(%rcx),$MASK		# .Lmask26
+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
+
+	################################################################
+	# horizontal addition
+
+	vpsrldq		\$8,$D1,$T1
+	vpsrldq		\$8,$H2,$T2
+	vpsrldq		\$8,$H3,$T3
+	vpsrldq		\$8,$H4,$T4
+	vpsrldq		\$8,$H0,$T0
+	vpaddq		$T1,$D1,$D1
+	vpaddq		$T2,$H2,$H2
+	vpaddq		$T3,$H3,$H3
+	vpaddq		$T4,$H4,$H4
+	vpaddq		$T0,$H0,$H0
+
+	vpermq		\$0x2,$H3,$T3
+	vpermq		\$0x2,$H4,$T4
+	vpermq		\$0x2,$H0,$T0
+	vpermq		\$0x2,$D1,$T1
+	vpermq		\$0x2,$H2,$T2
+	vpaddq		$T3,$H3,$H3
+	vpaddq		$T4,$H4,$H4
+	vpaddq		$T0,$H0,$H0
+	vpaddq		$T1,$D1,$D1
+	vpaddq		$T2,$H2,$H2
+
+	################################################################
+	# lazy reduction
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$D1,$H1		# h0 -> h1
+
+	vpsrlq		\$26,$H4,$D4
+	vpand		$MASK,$H4,$H4
+
+	vpsrlq		\$26,$H1,$D1
+	vpand		$MASK,$H1,$H1
+	vpaddq		$D1,$H2,$H2		# h1 -> h2
+
+	vpaddq		$D4,$H0,$H0
+	vpsllq		\$2,$D4,$D4
+	vpaddq		$D4,$H0,$H0		# h4 -> h0
+
+	vpsrlq		\$26,$H2,$D2
+	vpand		$MASK,$H2,$H2
+	vpaddq		$D2,$H3,$H3		# h2 -> h3
+
+	vpsrlq		\$26,$H0,$D0
+	vpand		$MASK,$H0,$H0
+	vpaddq		$D0,$H1,$H1		# h0 -> h1
+
+	vpsrlq		\$26,$H3,$D3
+	vpand		$MASK,$H3,$H3
+	vpaddq		$D3,$H4,$H4		# h3 -> h4
+
+	vmovd		%x#$H0,`4*0-48-64`($ctx)# save partially reduced
+	vmovd		%x#$H1,`4*1-48-64`($ctx)
+	vmovd		%x#$H2,`4*2-48-64`($ctx)
+	vmovd		%x#$H3,`4*3-48-64`($ctx)
+	vmovd		%x#$H4,`4*4-48-64`($ctx)
+___
+$code.=<<___	if ($win64);
+	vmovdqa		0x50(%r11),%xmm6
+	vmovdqa		0x60(%r11),%xmm7
+	vmovdqa		0x70(%r11),%xmm8
+	vmovdqa		0x80(%r11),%xmm9
+	vmovdqa		0x90(%r11),%xmm10
+	vmovdqa		0xa0(%r11),%xmm11
+	vmovdqa		0xb0(%r11),%xmm12
+	vmovdqa		0xc0(%r11),%xmm13
+	vmovdqa		0xd0(%r11),%xmm14
+	vmovdqa		0xe0(%r11),%xmm15
+	lea		0xf8(%r11),%rsp
+.Ldo_avx2_epilogue:
+___
+$code.=<<___	if (!$win64);
+	lea		8(%r11),%rsp
+___
+$code.=<<___;
+	vzeroupper
+	ret
+.size	poly1305_blocks_avx2,.-poly1305_blocks_avx2
+___
+}
+$code.=<<___;
+.align	64
+.Lconst:
+.Lmask24:
+.long	0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0
+.L129:
+.long	1<<24,0,1<<24,0,1<<24,0,1<<24,0
+.Lmask26:
+.long	0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0
+.Lfive:
+.long	5,0,5,0,5,0,5,0
+___
+}
+
+$code.=<<___;
+.asciz	"Poly1305 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	16
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lcommon_seh_tail
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lcommon_seh_tail
+
+	lea	48(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R14
+
+	jmp	.Lcommon_seh_tail
+.size	se_handler,.-se_handler
+
+.type	avx_handler,\@abi-omnipotent
+.align	16
+avx_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lcommon_seh_tail
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lcommon_seh_tail
+
+	mov	208($context),%rax	# pull context->R11
+
+	lea	0x50(%rax),%rsi
+	lea	0xf8(%rax),%rax
+	lea	512($context),%rdi	# &context.Xmm6
+	mov	\$20,%ecx
+	.long	0xa548f3fc		# cld; rep movsq
+
+.Lcommon_seh_tail:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	avx_handler,.-avx_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_poly1305_init
+	.rva	.LSEH_end_poly1305_init
+	.rva	.LSEH_info_poly1305_init
+
+	.rva	.LSEH_begin_poly1305_blocks
+	.rva	.LSEH_end_poly1305_blocks
+	.rva	.LSEH_info_poly1305_blocks
+
+	.rva	.LSEH_begin_poly1305_emit
+	.rva	.LSEH_end_poly1305_emit
+	.rva	.LSEH_info_poly1305_emit
+___
+$code.=<<___ if ($avx);
+	.rva	.LSEH_begin_poly1305_blocks_avx
+	.rva	.Lbase2_64_avx
+	.rva	.LSEH_info_poly1305_blocks_avx_1
+
+	.rva	.Lbase2_64_avx
+	.rva	.Leven_avx
+	.rva	.LSEH_info_poly1305_blocks_avx_2
+
+	.rva	.Leven_avx
+	.rva	.LSEH_end_poly1305_blocks_avx
+	.rva	.LSEH_info_poly1305_blocks_avx_3
+
+	.rva	.LSEH_begin_poly1305_emit_avx
+	.rva	.LSEH_end_poly1305_emit_avx
+	.rva	.LSEH_info_poly1305_emit_avx
+___
+$code.=<<___ if ($avx>1);
+	.rva	.LSEH_begin_poly1305_blocks_avx2
+	.rva	.Lbase2_64_avx2
+	.rva	.LSEH_info_poly1305_blocks_avx2_1
+
+	.rva	.Lbase2_64_avx2
+	.rva	.Leven_avx2
+	.rva	.LSEH_info_poly1305_blocks_avx2_2
+
+	.rva	.Leven_avx2
+	.rva	.LSEH_end_poly1305_blocks_avx2
+	.rva	.LSEH_info_poly1305_blocks_avx2_3
+___
+$code.=<<___;
+.section	.xdata
+.align	8
+.LSEH_info_poly1305_init:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.LSEH_begin_poly1305_init,.LSEH_begin_poly1305_init
+
+.LSEH_info_poly1305_blocks:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.Lblocks_body,.Lblocks_epilogue
+
+.LSEH_info_poly1305_emit:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.LSEH_begin_poly1305_emit,.LSEH_begin_poly1305_emit
+___
+$code.=<<___ if ($avx);
+.LSEH_info_poly1305_blocks_avx_1:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.Lblocks_avx_body,.Lblocks_avx_epilogue		# HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx_2:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.Lbase2_64_avx_body,.Lbase2_64_avx_epilogue	# HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx_3:
+	.byte	9,0,0,0
+	.rva	avx_handler
+	.rva	.Ldo_avx_body,.Ldo_avx_epilogue			# HandlerData[]
+
+.LSEH_info_poly1305_emit_avx:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.LSEH_begin_poly1305_emit_avx,.LSEH_begin_poly1305_emit_avx
+___
+$code.=<<___ if ($avx>1);
+.LSEH_info_poly1305_blocks_avx2_1:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.Lblocks_avx2_body,.Lblocks_avx2_epilogue	# HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx2_2:
+	.byte	9,0,0,0
+	.rva	se_handler
+	.rva	.Lbase2_64_avx2_body,.Lbase2_64_avx2_epilogue	# HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx2_3:
+	.byte	9,0,0,0
+	.rva	avx_handler
+	.rva	.Ldo_avx2_body,.Ldo_avx2_epilogue		# HandlerData[]
+___
+}
+
+foreach (split('\n',$code)) {
+	s/\`([^\`]*)\`/eval($1)/ge;
+	s/%r([a-z]+)#d/%e$1/g;
+	s/%r([0-9]+)#d/%r$1d/g;
+	s/%x#%y/%x/g;
+
+	print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/poly1305/internal.h b/src/crypto/poly1305/internal.h
new file mode 100644
index 0000000..df6769e
--- /dev/null
+++ b/src/crypto/poly1305/internal.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H
+#define OPENSSL_HEADER_POLY1305_INTERNAL_H
+
+#include <openssl/base.h>
+#include <openssl/poly1305.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
+void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]);
+
+void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
+                                 size_t in_len);
+
+void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]);
+#endif
+
+
+#if defined(__cplusplus)
+}  /* extern C */
+#endif
+
+#endif  /* OPENSSL_HEADER_POLY1305_INTERNAL_H */
diff --git a/src/crypto/poly1305/poly1305.c b/src/crypto/poly1305/poly1305.c
index 5a49e2d..dc2d6a6 100644
--- a/src/crypto/poly1305/poly1305.c
+++ b/src/crypto/poly1305/poly1305.c
@@ -22,6 +22,8 @@
 
 #include <openssl/cpu.h>
 
+#include "internal.h"
+
 
 #if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64)
 
@@ -48,15 +50,6 @@
 }
 #endif
 
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]);
-
-void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
-                                 size_t in_len);
-
-void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]);
-#endif
-
 static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; }
 
 struct poly1305_state_st {
@@ -170,7 +163,7 @@
   uint32_t t0, t1, t2, t3;
 
 #if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-  if (CRYPTO_is_NEON_functional()) {
+  if (CRYPTO_is_NEON_capable()) {
     CRYPTO_poly1305_init_neon(statep, key);
     return;
   }
@@ -217,7 +210,7 @@
   struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
 
 #if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-  if (CRYPTO_is_NEON_functional()) {
+  if (CRYPTO_is_NEON_capable()) {
     CRYPTO_poly1305_update_neon(statep, in, in_len);
     return;
   }
@@ -263,7 +256,7 @@
   uint32_t b, nb;
 
 #if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-  if (CRYPTO_is_NEON_functional()) {
+  if (CRYPTO_is_NEON_capable()) {
     CRYPTO_poly1305_finish_neon(statep, mac);
     return;
   }
diff --git a/src/crypto/poly1305/poly1305_arm.c b/src/crypto/poly1305/poly1305_arm.c
index 5e78dc0..de31d6b 100644
--- a/src/crypto/poly1305/poly1305_arm.c
+++ b/src/crypto/poly1305/poly1305_arm.c
@@ -21,6 +21,9 @@
 
 #include <string.h>
 
+#include "../internal.h"
+#include "internal.h"
+
 
 typedef struct {
   uint32_t v[12]; /* for alignment; only using 10 */
@@ -170,7 +173,7 @@
   }
 }
 
-static const fe1305x2 zero __attribute__((aligned(16)));
+static const alignas(16) fe1305x2 zero;
 
 struct poly1305_state_st {
   uint8_t data[sizeof(fe1305x2[5]) + 128];
diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc
index 3a72668..2c25e93 100644
--- a/src/crypto/poly1305/poly1305_test.cc
+++ b/src/crypto/poly1305/poly1305_test.cc
@@ -20,16 +20,57 @@
 #include <openssl/crypto.h>
 #include <openssl/poly1305.h>
 
+#include "../internal.h"
 #include "../test/file_test.h"
 
 
-// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
-#if defined(OPENSSL_WINDOWS)
-// MSVC doesn't support C++11 |alignas|.
-#define ALIGNED __declspec(align(16))
-#else
-#define ALIGNED alignas(16)
-#endif
+static bool TestSIMD(FileTest *t, unsigned excess,
+                     const std::vector<uint8_t> &key,
+                     const std::vector<uint8_t> &in,
+                     const std::vector<uint8_t> &mac) {
+  poly1305_state state;
+  CRYPTO_poly1305_init(&state, key.data());
+
+  size_t done = 0;
+
+  // Feed 16 bytes in. Some implementations begin in non-SIMD mode and upgrade
+  // on-demand. Stress the upgrade path.
+  size_t todo = 16;
+  if (todo > in.size()) {
+    todo = in.size();
+  }
+  CRYPTO_poly1305_update(&state, in.data(), todo);
+  done += todo;
+
+  for (;;) {
+    // Feed 128 + |excess| bytes to test SIMD mode.
+    if (done + 128 + excess > in.size()) {
+      break;
+    }
+    CRYPTO_poly1305_update(&state, in.data() + done, 128 + excess);
+    done += 128 + excess;
+
+    // Feed |excess| bytes to ensure SIMD mode can handle short inputs.
+    if (done + excess > in.size()) {
+      break;
+    }
+    CRYPTO_poly1305_update(&state, in.data() + done, excess);
+    done += excess;
+  }
+
+  // Consume the remainder and finish.
+  CRYPTO_poly1305_update(&state, in.data() + done, in.size() - done);
+
+  // |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
+  alignas(16) uint8_t out[16];
+  CRYPTO_poly1305_finish(&state, out);
+  if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
+    t->PrintLine("SIMD pattern %u failed.", excess);
+    return false;
+  }
+
+  return true;
+}
 
 static bool TestPoly1305(FileTest *t, void *arg) {
   std::vector<uint8_t> key, in, mac;
@@ -47,7 +88,8 @@
   poly1305_state state;
   CRYPTO_poly1305_init(&state, key.data());
   CRYPTO_poly1305_update(&state, in.data(), in.size());
-  ALIGNED uint8_t out[16];
+  // |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
+  alignas(16) uint8_t out[16];
   CRYPTO_poly1305_finish(&state, out);
   if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
     t->PrintLine("Single-shot Poly1305 failed.");
@@ -60,11 +102,20 @@
     CRYPTO_poly1305_update(&state, &in[i], 1);
   }
   CRYPTO_poly1305_finish(&state, out);
-  if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
+  if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
     t->PrintLine("Streaming Poly1305 failed.");
     return false;
   }
 
+  // Test SIMD stress patterns. OpenSSL's AVX2 assembly needs a multiple of
+  // four blocks, so test up to three blocks of excess.
+  if (!TestSIMD(t, 0, key, in, mac) ||
+      !TestSIMD(t, 16, key, in, mac) ||
+      !TestSIMD(t, 32, key, in, mac) ||
+      !TestSIMD(t, 48, key, in, mac)) {
+    return false;
+  }
+
   return true;
 }
 
diff --git a/src/crypto/poly1305/poly1305_test.txt b/src/crypto/poly1305/poly1305_test.txt
index ad40699..611007a 100644
--- a/src/crypto/poly1305/poly1305_test.txt
+++ b/src/crypto/poly1305/poly1305_test.txt
@@ -50,3 +50,110 @@
 Key = 0100000000000000040000000000000000000000000000000000000000000000
 Input = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000
 MAC = 13000000000000000000000000000000
+
+
+# Additional test vectors that are long enough to ensure OpenSSL's SIMD
+# assembly is fully tested.
+
+# Length 2048.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfed
+MAC = 69d28f73dd09d39a92aa179da354b7ea
+
+# Length 2049.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc8
+MAC = d6a26654b88572e875d9661c83471c1b
+
+# Length 2050.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852
+MAC = 9fbbb7f7adcd0cd5b46a4a520b22499a
+
+# Length 2051.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f5
+MAC = eb7cdceb97ade2a07622f8f5a4b1ce15
+
+# Length 2052.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f590
+MAC = d41c310927cd92e14784ea78b85503db
+
+# Length 2053.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073
+MAC = 16af133c423f783a14c49d9f526384cf
+
+# Length 2054.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4
+MAC = 00c75db8f0636b22f195645b03091f5f
+
+# Length 2055.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f434
+MAC = 4a532bc740f581555831345f3b75bf33
+
+# Length 2056.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a
+MAC = 698c7d32c5923871d124a2479e521706
+
+# Length 2057.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c
+MAC = a677187dbf3c927aeeafb9ebce0f61dc
+
+# Length 2058.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a
+MAC = 201fed7eee981b31d2cc42ff6c38141a
+
+# Length 2059.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28
+MAC = 0c3d3d01a37f347c4f7c5826bcafb3e1
+
+# Length 2060.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c9
+MAC = 33a4e0e0bed7c84c5cc5dd4784410f07
+
+# Length 2061.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e
+MAC = 8e41c40a2f8ec58fe594f3a3a2de4ae1
+
+# Length 2062.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21
+MAC = c6e5d1810fd878ac6b844c66cef36a22
+
+# Length 2063.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21df
+MAC = f6eaae369c3cb5c05748e8d919178e00
+
+# Regression test for https://rt.openssl.org/Ticket/Display.html?id=4439
+Key = 2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea
+Input = 89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a91c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a620334270372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f141300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595
+MAC = c85d15ed44c378d6b00e23064c7bcd51
+
+# Regression tests for https://rt.openssl.org/Ticket/Display.html?id=4483
+
+Key = 7f1b02640000000000000000000000000000000000000000cccccccccccccccc
+Input = cccccccccccccccccccccccccccccccccccccccccccccccccc80ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccceccccccccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccccccccccccce3ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaccccccccccccccccccccce6cccccccccc000000afccccccccccccccccccfffffff5000000000000000000000000000000000000000000000000000000ffffffe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000719205a8521dfc
+MAC = 8559b876eceed66eb37798c0457baff9
+
+Key = e00016000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Input = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000800264
+MAC = 00bd1258978e205444c9aaaa82006fed
+
+Key = 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
+Input = 02fc
+MAC = 06120c0c0c0c0c0c0c0c0c0c0c0c0c0c
+
+Key = 00ff000000000000000000000000000000000000001e00000000000000007b7b
+Input = 7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff0009000000000000000000000000100000000009000000640000000000000000000000001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff00090000000000000000007a000010000000000900000064000000000000000000000000000000000000000000000000fc
+MAC = 33205bbf9e9f8f7212ab9e2ab9b7e4a5
diff --git a/src/crypto/poly1305/poly1305_vec.c b/src/crypto/poly1305/poly1305_vec.c
index 07578d0..3045a2f 100644
--- a/src/crypto/poly1305/poly1305_vec.c
+++ b/src/crypto/poly1305/poly1305_vec.c
@@ -20,42 +20,40 @@
 
 #include <openssl/poly1305.h>
 
+#include "../internal.h"
+
 
 #if !defined(OPENSSL_WINDOWS) && defined(OPENSSL_X86_64)
 
 #include <emmintrin.h>
 
-#define ALIGN(x) __attribute__((aligned(x)))
-/* inline is not a keyword in C89. */
-#define INLINE 
-#define U8TO64_LE(m) (*(uint64_t *)(m))
-#define U8TO32_LE(m) (*(uint32_t *)(m))
+#define U8TO64_LE(m) (*(const uint64_t *)(m))
+#define U8TO32_LE(m) (*(const uint32_t *)(m))
 #define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v
 
 typedef __m128i xmmi;
-typedef unsigned __int128 uint128_t;
 
-static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = {
+static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = {
     (1 << 26) - 1, 0, (1 << 26) - 1, 0};
-static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
-static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = {(1 << 24), 0,
-                                                                (1 << 24), 0};
+static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
+static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = {
+    (1 << 24), 0, (1 << 24), 0};
 
-static uint128_t INLINE add128(uint128_t a, uint128_t b) { return a + b; }
+static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; }
 
-static uint128_t INLINE add128_64(uint128_t a, uint64_t b) { return a + b; }
+static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; }
 
-static uint128_t INLINE mul64x64_128(uint64_t a, uint64_t b) {
+static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) {
   return (uint128_t)a * b;
 }
 
-static uint64_t INLINE lo128(uint128_t a) { return (uint64_t)a; }
+static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; }
 
-static uint64_t INLINE shr128(uint128_t v, const int shift) {
+static inline uint64_t shr128(uint128_t v, const int shift) {
   return (uint64_t)(v >> shift);
 }
 
-static uint64_t INLINE shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
+static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
   return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
 }
 
@@ -82,32 +80,32 @@
 } poly1305_state_internal; /* 448 bytes total + 63 bytes for
                               alignment = 511 bytes raw */
 
-static poly1305_state_internal INLINE *poly1305_aligned_state(
+static inline poly1305_state_internal *poly1305_aligned_state(
     poly1305_state *state) {
   return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
 }
 
 /* copy 0-63 bytes */
-static void INLINE
+static inline void
 poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
   size_t offset = src - dst;
   if (bytes & 32) {
     _mm_storeu_si128((xmmi *)(dst + 0),
-                     _mm_loadu_si128((xmmi *)(dst + offset + 0)));
+                     _mm_loadu_si128((const xmmi *)(dst + offset + 0)));
     _mm_storeu_si128((xmmi *)(dst + 16),
-                     _mm_loadu_si128((xmmi *)(dst + offset + 16)));
+                     _mm_loadu_si128((const xmmi *)(dst + offset + 16)));
     dst += 32;
   }
   if (bytes & 16) {
-    _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset)));
+    _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((const xmmi *)(dst + offset)));
     dst += 16;
   }
   if (bytes & 8) {
-    *(uint64_t *)dst = *(uint64_t *)(dst + offset);
+    *(uint64_t *)dst = *(const uint64_t *)(dst + offset);
     dst += 8;
   }
   if (bytes & 4) {
-    *(uint32_t *)dst = *(uint32_t *)(dst + offset);
+    *(uint32_t *)dst = *(const uint32_t *)(dst + offset);
     dst += 4;
   }
   if (bytes & 2) {
@@ -120,7 +118,7 @@
 }
 
 /* zero 0-15 bytes */
-static void INLINE poly1305_block_zero(uint8_t *dst, size_t bytes) {
+static inline void poly1305_block_zero(uint8_t *dst, size_t bytes) {
   if (bytes & 8) {
     *(uint64_t *)dst = 0;
     dst += 8;
@@ -138,7 +136,7 @@
   }
 }
 
-static size_t INLINE poly1305_min(size_t a, size_t b) {
+static inline size_t poly1305_min(size_t a, size_t b) {
   return (a < b) ? a : b;
 }
 
@@ -186,9 +184,9 @@
 
 static void poly1305_first_block(poly1305_state_internal *st,
                                  const uint8_t *m) {
-  const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
-  const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
-  const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+  const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+  const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
+  const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
   xmmi T5, T6;
   poly1305_power *p;
   uint128_t d[3];
@@ -265,10 +263,10 @@
   p->R24.d[3] = (uint32_t)(pad1 >> 32);
 
   /* H = [Mx,My] */
-  T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
-                          _mm_loadl_epi64((xmmi *)(m + 16)));
-  T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
-                          _mm_loadl_epi64((xmmi *)(m + 24)));
+  T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+                          _mm_loadl_epi64((const xmmi *)(m + 16)));
+  T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+                          _mm_loadl_epi64((const xmmi *)(m + 24)));
   st->H[0] = _mm_and_si128(MMASK, T5);
   st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
   T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -279,9 +277,9 @@
 
 static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m,
                             size_t bytes) {
-  const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
-  const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
-  const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+  const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+  const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
+  const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
 
   poly1305_power *p;
   xmmi H0, H1, H2, H3, H4;
@@ -345,10 +343,10 @@
     T4 = _mm_add_epi64(T4, T5);
 
     /* H += [Mx,My]*[r^2,r^2] */
-    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
-                            _mm_loadl_epi64((xmmi *)(m + 16)));
-    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
-                            _mm_loadl_epi64((xmmi *)(m + 24)));
+    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+                            _mm_loadl_epi64((const xmmi *)(m + 16)));
+    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+                            _mm_loadl_epi64((const xmmi *)(m + 24)));
     M0 = _mm_and_si128(MMASK, T5);
     M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
     T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -409,10 +407,10 @@
     T4 = _mm_add_epi64(T4, T5);
 
     /* H += [Mx,My] */
-    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)),
-                            _mm_loadl_epi64((xmmi *)(m + 48)));
-    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)),
-                            _mm_loadl_epi64((xmmi *)(m + 56)));
+    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)),
+                            _mm_loadl_epi64((const xmmi *)(m + 48)));
+    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)),
+                            _mm_loadl_epi64((const xmmi *)(m + 56)));
     M0 = _mm_and_si128(MMASK, T5);
     M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
     T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -469,9 +467,9 @@
 
 static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m,
                                size_t bytes) {
-  const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
-  const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
-  const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
+  const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+  const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
+  const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
 
   poly1305_power *p;
   xmmi H0, H1, H2, H3, H4;
@@ -542,10 +540,10 @@
     T4 = _mm_add_epi64(T4, T5);
 
     /* H += [Mx,My] */
-    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
-                            _mm_loadl_epi64((xmmi *)(m + 16)));
-    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
-                            _mm_loadl_epi64((xmmi *)(m + 24)));
+    T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+                            _mm_loadl_epi64((const xmmi *)(m + 16)));
+    T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+                            _mm_loadl_epi64((const xmmi *)(m + 24)));
     M0 = _mm_and_si128(MMASK, T5);
     M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
     T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -703,9 +701,9 @@
   t0 &= 0x3ffffff;
   t1 = t1 + c;
 
-  st->HH[0] = ((t0) | (t1 << 26)) & 0xfffffffffffull;
-  st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
-  st->HH[2] = ((t3 >> 10) | (t4 << 16)) & 0x3ffffffffffull;
+  st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff);
+  st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff);
+  st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff);
 
   return consumed;
 }
diff --git a/src/crypto/rand/CMakeLists.txt b/src/crypto/rand/CMakeLists.txt
index eedf81b..c66d2ee 100644
--- a/src/crypto/rand/CMakeLists.txt
+++ b/src/crypto/rand/CMakeLists.txt
@@ -13,6 +13,7 @@
 
   OBJECT
 
+  deterministic.c
   rand.c
   urandom.c
   windows.c
diff --git a/src/crypto/rand/deterministic.c b/src/crypto/rand/deterministic.c
new file mode 100644
index 0000000..e6b7bb7
--- /dev/null
+++ b/src/crypto/rand/deterministic.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/rand.h>
+
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+
+#include <string.h>
+
+#include <openssl/chacha.h>
+
+#include "internal.h"
+
+
+/* g_num_calls is the number of calls to |CRYPTO_sysrand| that have occured.
+ *
+ * TODO(davidben): This is intentionally not thread-safe. If the fuzzer mode is
+ * ever used in a multi-threaded program, replace this with a thread-local. (A
+ * mutex would not be deterministic.) */
+static uint64_t g_num_calls = 0;
+
+void RAND_cleanup(void) {}
+
+void RAND_reset_for_fuzzing(void) { g_num_calls = 0; }
+
+void CRYPTO_sysrand(uint8_t *out, size_t requested) {
+  static const uint8_t kZeroKey[32];
+
+  uint8_t nonce[12];
+  memset(nonce, 0, sizeof(nonce));
+  memcpy(nonce, &g_num_calls, sizeof(g_num_calls));
+
+  memset(out, 0, requested);
+  CRYPTO_chacha_20(out, out, requested, kZeroKey, nonce, 0);
+  g_num_calls++;
+}
+
+#endif  /* BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index 892b4ba..5a1bec2 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -72,7 +72,8 @@
   OPENSSL_free(state);
 }
 
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
+    !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
 
 /* These functions are defined in asm/rdrand-x86_64.pl */
 extern int CRYPTO_rdrand(uint8_t out[8]);
@@ -209,6 +210,8 @@
   }
 }
 
+const char *RAND_file_name(char *buf, size_t num) { return NULL; }
+
 void RAND_add(const void *buf, int num, double entropy) {}
 
 int RAND_egd(const char *path) {
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 5bf5c73..a519983 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -14,7 +14,7 @@
 
 #include <openssl/rand.h>
 
-#if !defined(OPENSSL_WINDOWS)
+#if !defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
 
 #include <assert.h>
 #include <errno.h>
@@ -220,4 +220,4 @@
   }
 }
 
-#endif  /* !OPENSSL_WINDOWS */
+#endif  /* !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rand/windows.c b/src/crypto/rand/windows.c
index 1a0cb8b..9d7dd78 100644
--- a/src/crypto/rand/windows.c
+++ b/src/crypto/rand/windows.c
@@ -14,7 +14,7 @@
 
 #include <openssl/rand.h>
 
-#if defined(OPENSSL_WINDOWS)
+#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
 
 #include <limits.h>
 #include <stdlib.h>
@@ -53,4 +53,4 @@
   return;
 }
 
-#endif  /* OPENSSL_WINDOWS */
+#endif  /* OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rc4/asm/rc4-586.pl b/src/crypto/rc4/asm/rc4-586.pl
index fc860ae..8d3ccb7 100644
--- a/src/crypto/rc4/asm/rc4-586.pl
+++ b/src/crypto/rc4/asm/rc4-586.pl
@@ -384,31 +384,5 @@
 	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
 &function_end("asm_RC4_set_key");
 
-# const char *RC4_options(void);
-&function_begin_B("RC4_options");
-	&call	(&label("pic_point"));
-&set_label("pic_point");
-	&blindpop("eax");
-	&lea	("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
-	&picmeup("edx","OPENSSL_ia32cap_P");
-	&mov	("edx",&DWP(0,"edx"));
-	&bt	("edx",20);
-	&jc	(&label("1xchar"));
-	&bt	("edx",26);
-	&jnc	(&label("ret"));
-	&add	("eax",25);
-	&ret	();
-&set_label("1xchar");
-	&add	("eax",12);
-&set_label("ret");
-	&ret	();
-&set_label("opts",64);
-&asciz	("rc4(4x,int)");
-&asciz	("rc4(1x,char)");
-&asciz	("rc4(8x,mmx)");
-&asciz	("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
-&align	(64);
-&function_end_B("RC4_options");
-
 &asm_finish();
 
diff --git a/src/crypto/rsa/blinding.c b/src/crypto/rsa/blinding.c
index d21633f..d9d90c2 100644
--- a/src/crypto/rsa/blinding.c
+++ b/src/crypto/rsa/blinding.c
@@ -113,7 +113,6 @@
 #include <openssl/bn.h>
 #include <openssl/mem.h>
 #include <openssl/err.h>
-#include <openssl/thread.h>
 
 #include "internal.h"
 
@@ -121,54 +120,35 @@
 #define BN_BLINDING_COUNTER 32
 
 struct bn_blinding_st {
-  BIGNUM *A;
-  BIGNUM *Ai;
-  BIGNUM *e;
-  BIGNUM *mod; /* just a reference */
-  int counter;
-  unsigned long flags;
-  /* mont is the Montgomery context used for this |BN_BLINDING|. It is not
-   * owned and must outlive this structure. */
-  const BN_MONT_CTX *mont;
-  int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-                    const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont);
+  BIGNUM *A; /* The base blinding factor, Montgomery-encoded. */
+  BIGNUM *Ai; /* The inverse of the blinding factor, Montgomery-encoded. */
+  unsigned counter;
 };
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
-  BN_BLINDING *ret = NULL;
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+                                    const BN_MONT_CTX *mont, BN_CTX *ctx);
 
-  ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING));
+BN_BLINDING *BN_BLINDING_new(void) {
+  BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
   memset(ret, 0, sizeof(BN_BLINDING));
-  if (A != NULL) {
-    ret->A = BN_dup(A);
-    if (ret->A == NULL) {
-      goto err;
-    }
-  }
-  if (Ai != NULL) {
-    ret->Ai = BN_dup(Ai);
-    if (ret->Ai == NULL) {
-      goto err;
-    }
-  }
 
-  /* save a copy of mod in the BN_BLINDING structure */
-  ret->mod = BN_dup(mod);
-  if (ret->mod == NULL) {
+  ret->A = BN_new();
+  if (ret->A == NULL) {
     goto err;
   }
-  if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) {
-    BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+  ret->Ai = BN_new();
+  if (ret->Ai == NULL) {
+    goto err;
   }
 
-  /* Set the counter to the special value -1
-   * to indicate that this is never-used fresh blinding
-   * that does not need updating before first use. */
-  ret->counter = -1;
+  /* The blinding values need to be created before this blinding can be used. */
+  ret->counter = BN_BLINDING_COUNTER - 1;
+
   return ret;
 
 err:
@@ -183,280 +163,105 @@
 
   BN_free(r->A);
   BN_free(r->Ai);
-  BN_free(r->e);
-  BN_free(r->mod);
   OPENSSL_free(r);
 }
 
-int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) {
-  int ret = 0;
-
-  if (b->A == NULL || b->Ai == NULL) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
-    goto err;
-  }
-
-  if (b->counter == -1) {
-    b->counter = 0;
-  }
-
-  if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
-      !(b->flags & BN_BLINDING_NO_RECREATE)) {
+static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
+                              const BN_MONT_CTX *mont, BN_CTX *ctx) {
+  if (++b->counter == BN_BLINDING_COUNTER) {
     /* re-create blinding parameters */
-    if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) {
+    if (!bn_blinding_create_param(b, e, mont, ctx)) {
       goto err;
     }
-  } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
-    if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) {
-      goto err;
-    }
-    if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) {
+    b->counter = 0;
+  } else {
+    if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) ||
+        !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) {
       goto err;
     }
   }
 
-  ret = 1;
+  return 1;
 
 err:
-  if (b->counter == BN_BLINDING_COUNTER) {
-    b->counter = 0;
-  }
-  return ret;
+  /* |A| and |Ai| may be in an inconsistent state so they both need to be
+   * replaced the next time this blinding is used. Note that this is only
+   * sufficient because support for |BN_BLINDING_NO_UPDATE| and
+   * |BN_BLINDING_NO_RECREATE| was previously dropped. */
+  b->counter = BN_BLINDING_COUNTER - 1;
+
+  return 0;
 }
 
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) {
-  return BN_BLINDING_convert_ex(n, NULL, b, ctx);
-}
-
-int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) {
-  int ret = 1;
-
-  if (b->A == NULL || b->Ai == NULL) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+                        const BN_MONT_CTX *mont, BN_CTX *ctx) {
+  /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+   * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+   */
+  if (!bn_blinding_update(b, e, mont, ctx) ||
+      !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
     return 0;
   }
 
-  if (b->counter == -1) {
-    /* Fresh blinding, doesn't need updating. */
-    b->counter = 0;
-  } else if (!BN_BLINDING_update(b, ctx)) {
-    return 0;
-  }
-
-  if (r != NULL) {
-    if (!BN_copy(r, b->Ai)) {
-      ret = 0;
-    }
-  }
-
-  if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) {
-    ret = 0;
-  }
-
-  return ret;
+  return 1;
 }
 
-int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) {
-  return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont,
+                       BN_CTX *ctx) {
+  /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+   * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+   */
+  return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
 }
 
-int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
-                          BN_CTX *ctx) {
-  int ret;
-
-  if (r != NULL) {
-    ret = BN_mod_mul(n, n, r, b->mod, ctx);
-  } else {
-    if (b->Ai == NULL) {
-      OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
-      return 0;
-    }
-    ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
-  }
-
-  return ret;
-}
-
-unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) { return b->flags; }
-
-void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) {
-  b->flags = flags;
-}
-
-BN_BLINDING *BN_BLINDING_create_param(
-    BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
-    int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-                      const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont),
-    const BN_MONT_CTX *mont) {
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+                                    const BN_MONT_CTX *mont, BN_CTX *ctx) {
+  BIGNUM mont_N_consttime;
+  BN_init(&mont_N_consttime);
+  BN_with_flags(&mont_N_consttime, &mont->N, BN_FLG_CONSTTIME);
   int retry_counter = 32;
-  BN_BLINDING *ret = NULL;
-
-  if (b == NULL) {
-    ret = BN_BLINDING_new(NULL, NULL, m);
-  } else {
-    ret = b;
-  }
-
-  if (ret == NULL) {
-    goto err;
-  }
-
-  if (ret->A == NULL && (ret->A = BN_new()) == NULL) {
-    goto err;
-  }
-  if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) {
-    goto err;
-  }
-
-  if (e != NULL) {
-    BN_free(ret->e);
-    ret->e = BN_dup(e);
-  }
-  if (ret->e == NULL) {
-    goto err;
-  }
-
-  if (bn_mod_exp != NULL) {
-    ret->bn_mod_exp = bn_mod_exp;
-  }
-  if (mont != NULL) {
-    ret->mont = mont;
-  }
 
   do {
-    if (!BN_rand_range(ret->A, ret->mod)) {
-      goto err;
+    if (!BN_rand_range(b->A, &mont->N)) {
+      OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+      return 0;
+    }
+
+    /* |BN_from_montgomery| + |BN_mod_inverse_no_branch| is equivalent to, but
+     * more efficient than, |BN_mod_inverse_no_branch| + |BN_to_montgomery|. */
+    if (!BN_from_montgomery(b->Ai, b->A, mont, ctx)) {
+      OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+      return 0;
     }
 
     int no_inverse;
-    if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) {
+    if (BN_mod_inverse_ex(b->Ai, &no_inverse, b->Ai, &mont_N_consttime, ctx) ==
+        NULL) {
       /* this should almost never happen for good RSA keys */
       if (no_inverse) {
         if (retry_counter-- == 0) {
           OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
-          goto err;
+          return 0;
         }
         ERR_clear_error();
       } else {
-        goto err;
+        OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+        return 0;
       }
     } else {
       break;
     }
   } while (1);
 
-  if (ret->bn_mod_exp != NULL && ret->mont != NULL) {
-    if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->mont)) {
-      goto err;
-    }
-  } else {
-    if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) {
-      goto err;
-    }
+  if (!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont)) {
+    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+    return 0;
   }
 
-  return ret;
-
-err:
-  if (b == NULL) {
-    BN_BLINDING_free(ret);
-    ret = NULL;
+  if (!BN_to_montgomery(b->A, b->A, mont, ctx)) {
+    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+    return 0;
   }
 
-  return ret;
-}
-
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
-                                  const BIGNUM *q, BN_CTX *ctx) {
-  BIGNUM *ret = NULL, *r0, *r1, *r2;
-
-  if (d == NULL || p == NULL || q == NULL) {
-    return NULL;
-  }
-
-  BN_CTX_start(ctx);
-  r0 = BN_CTX_get(ctx);
-  r1 = BN_CTX_get(ctx);
-  r2 = BN_CTX_get(ctx);
-  if (r2 == NULL) {
-    goto err;
-  }
-
-  if (!BN_sub(r1, p, BN_value_one())) {
-    goto err;
-  }
-  if (!BN_sub(r2, q, BN_value_one())) {
-    goto err;
-  }
-  if (!BN_mul(r0, r1, r2, ctx)) {
-    goto err;
-  }
-
-  ret = BN_mod_inverse(NULL, d, r0, ctx);
-
-err:
-  BN_CTX_end(ctx);
-  return ret;
-}
-
-BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
-  BIGNUM local_n;
-  BIGNUM *e, *n;
-  BN_CTX *ctx;
-  BN_BLINDING *ret = NULL;
-  BN_MONT_CTX *mont_ctx = NULL;
-
-  if (in_ctx == NULL) {
-    ctx = BN_CTX_new();
-    if (ctx == NULL) {
-      return 0;
-    }
-  } else {
-    ctx = in_ctx;
-  }
-
-  BN_CTX_start(ctx);
-  e = BN_CTX_get(ctx);
-  if (e == NULL) {
-    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (rsa->e == NULL) {
-    e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
-    if (e == NULL) {
-      OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
-      goto err;
-    }
-  } else {
-    e = rsa->e;
-  }
-
-  n = &local_n;
-  BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
-
-  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
-    mont_ctx = BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx);
-    if (mont_ctx == NULL) {
-      goto err;
-    }
-  }
-
-  ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
-                                 mont_ctx);
-  if (ret == NULL) {
-    OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
-    goto err;
-  }
-
-err:
-  BN_CTX_end(ctx);
-  if (in_ctx == NULL) {
-    BN_CTX_free(ctx);
-  }
-  if (rsa->e == NULL) {
-    BN_free(e);
-  }
-
-  return ret;
+  return 1;
 }
diff --git a/src/crypto/rsa/internal.h b/src/crypto/rsa/internal.h
index 4e896e2..c6ea97f 100644
--- a/src/crypto/rsa/internal.h
+++ b/src/crypto/rsa/internal.h
@@ -77,9 +77,6 @@
                          int padding);
 int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                         const uint8_t *in, size_t in_len, int padding);
-int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
-                           size_t max_out, const uint8_t *in, size_t in_len,
-                           int padding);
 int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
                                   size_t len);
 int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
@@ -90,25 +87,12 @@
 #define RSA_PKCS1_PADDING_SIZE 11
 
 
-/* BN_BLINDING flags */
-#define BN_BLINDING_NO_UPDATE 0x00000001
-#define BN_BLINDING_NO_RECREATE 0x00000002
-
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+BN_BLINDING *BN_BLINDING_new(void);
 void BN_BLINDING_free(BN_BLINDING *b);
-int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
-int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
-unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
-void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
-BN_BLINDING *BN_BLINDING_create_param(
-    BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
-    int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-                      const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont),
-    const BN_MONT_CTX *mont);
-BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+                        const BN_MONT_CTX *mont_ctx, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx,
+                       BN_CTX *ctx);
 
 
 int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c
index 032df2e..12147ea 100644
--- a/src/crypto/rsa/padding.c
+++ b/src/crypto/rsa/padding.c
@@ -59,6 +59,7 @@
 #include <limits.h>
 #include <string.h>
 
+#include <openssl/bn.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
@@ -73,7 +74,6 @@
 int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
                                  const uint8_t *from, unsigned from_len) {
   unsigned j;
-  uint8_t *p;
 
   if (to_len < RSA_PKCS1_PADDING_SIZE) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
@@ -85,7 +85,7 @@
     return 0;
   }
 
-  p = (uint8_t *)to;
+  uint8_t *p = to;
 
   *(p++) = 0;
   *(p++) = 1; /* Private Key BT (Block Type) */
@@ -95,7 +95,7 @@
   memset(p, 0xff, j);
   p += j;
   *(p++) = 0;
-  memcpy(p, from, (unsigned int)from_len);
+  memcpy(p, from, from_len);
   return 1;
 }
 
@@ -154,7 +154,6 @@
 int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned to_len,
                                  const uint8_t *from, unsigned from_len) {
   unsigned i, j;
-  uint8_t *p;
 
   if (to_len < RSA_PKCS1_PADDING_SIZE) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
@@ -166,7 +165,7 @@
     return 0;
   }
 
-  p = (unsigned char *)to;
+  uint8_t *p = to;
 
   *(p++) = 0;
   *(p++) = 2; /* Public Key BT (Block Type) */
@@ -189,7 +188,7 @@
 
   *(p++) = 0;
 
-  memcpy(p, from, (unsigned int)from_len);
+  memcpy(p, from, from_len);
   return 1;
 }
 
@@ -271,12 +270,12 @@
     return 0;
   }
 
-  memcpy(to, from, (unsigned int)from_len);
+  memcpy(to, from, from_len);
   return 1;
 }
 
-int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
-               unsigned seedlen, const EVP_MD *dgst) {
+static int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
+                      unsigned seedlen, const EVP_MD *dgst) {
   unsigned outlen = 0;
   uint32_t i;
   uint8_t cnt[4];
@@ -357,7 +356,7 @@
   seed = to + 1;
   db = to + mdlen + 1;
 
-  if (!EVP_Digest((void *)param, param_len, db, NULL, md, NULL)) {
+  if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) {
     return 0;
   }
   memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1);
@@ -443,7 +442,7 @@
     db[i] ^= maskeddb[i];
   }
 
-  if (!EVP_Digest((void *)param, param_len, phash, NULL, md, NULL)) {
+  if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) {
     goto err;
   }
 
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 6c28ad7..e5f9891 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -64,7 +64,7 @@
 #include <openssl/err.h>
 #include <openssl/ex_data.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/thread.h>
 
 #include "internal.h"
@@ -76,7 +76,7 @@
 RSA *RSA_new(void) { return RSA_new_method(NULL); }
 
 RSA *RSA_new_method(const ENGINE *engine) {
-  RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA));
+  RSA *rsa = OPENSSL_malloc(sizeof(RSA));
   if (rsa == NULL) {
     OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -258,16 +258,6 @@
   return out_len;
 }
 
-int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                   const uint8_t *in, size_t in_len, int padding) {
-  if (rsa->meth->verify_raw) {
-    return rsa->meth->verify_raw(rsa, out_len, out, max_out, in, in_len, padding);
-  }
-
-  return rsa_default_verify_raw(rsa, out_len, out, max_out, in, in_len,
-                                padding);
-}
-
 int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
                        int padding) {
   size_t out_len;
@@ -473,6 +463,11 @@
 
 int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
                const uint8_t *sig, size_t sig_len, RSA *rsa) {
+  if (rsa->n == NULL || rsa->e == NULL) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+    return 0;
+  }
+
   const size_t rsa_size = RSA_size(rsa);
   uint8_t *buf = NULL;
   int ret = 0;
@@ -480,15 +475,6 @@
   size_t signed_msg_len, len;
   int signed_msg_is_alloced = 0;
 
-  if (rsa->meth->verify) {
-    return rsa->meth->verify(hash_nid, msg, msg_len, sig, sig_len, rsa);
-  }
-
-  if (sig_len != rsa_size) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_WRONG_SIGNATURE_LENGTH);
-    return 0;
-  }
-
   if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
     return 0;
@@ -510,7 +496,7 @@
     goto out;
   }
 
-  if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) {
+  if (len != signed_msg_len || memcmp(buf, signed_msg, len) != 0) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
     goto out;
   }
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index b73a0e1..d14ecae 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -59,14 +59,13 @@
 #include <limits.h>
 #include <string.h>
 
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
 #include <openssl/bn.h>
 #include <openssl/bytestring.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
 #include "internal.h"
+#include "../bytestring/internal.h"
 
 
 static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
@@ -76,9 +75,9 @@
     return 0;
   }
   if (buggy) {
-    return BN_cbs2unsigned_buggy(cbs, *out);
+    return BN_parse_asn1_unsigned_buggy(cbs, *out);
   }
-  return BN_cbs2unsigned(cbs, *out);
+  return BN_parse_asn1_unsigned(cbs, *out);
 }
 
 static int parse_integer(CBS *cbs, BIGNUM **out) {
@@ -91,7 +90,7 @@
     OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
     return 0;
   }
-  return BN_bn2cbb(cbb, bn);
+  return BN_marshal_asn1(cbb, bn);
 }
 
 static RSA *parse_public_key(CBS *cbs, int buggy) {
@@ -232,9 +231,11 @@
     goto err;
   }
 
-  /* Multi-prime RSA requires a newer version. */
-  if (version == kVersionMulti &&
-      CBS_peek_asn1_tag(&child, CBS_ASN1_SEQUENCE)) {
+  if (version == kVersionMulti) {
+    /* Although otherPrimeInfos is written as OPTIONAL in RFC 3447, it later
+     * says "[otherPrimeInfos] shall be omitted if version is 0 and shall
+     * contain at least one instance of OtherPrimeInfo if version is 1." The
+     * OPTIONAL is just so both versions share a single definition. */
     CBS other_prime_infos;
     if (!CBS_get_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE) ||
         CBS_len(&other_prime_infos) == 0) {
@@ -379,32 +380,18 @@
     RSA_free(*out);
     *out = ret;
   }
-  *inp += (size_t)len - CBS_len(&cbs);
+  *inp = CBS_data(&cbs);
   return ret;
 }
 
 int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) {
-  uint8_t *der;
-  size_t der_len;
-  if (!RSA_public_key_to_bytes(&der, &der_len, in)) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !RSA_marshal_public_key(&cbb, in)) {
+    CBB_cleanup(&cbb);
     return -1;
   }
-  if (der_len > INT_MAX) {
-    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
-    OPENSSL_free(der);
-    return -1;
-  }
-  if (outp != NULL) {
-    if (*outp == NULL) {
-      *outp = der;
-      der = NULL;
-    } else {
-      memcpy(*outp, der, der_len);
-      *outp += der_len;
-    }
-  }
-  OPENSSL_free(der);
-  return (int)der_len;
+  return CBB_finish_i2d(&cbb, outp);
 }
 
 RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
@@ -421,43 +408,20 @@
     RSA_free(*out);
     *out = ret;
   }
-  *inp += (size_t)len - CBS_len(&cbs);
+  *inp = CBS_data(&cbs);
   return ret;
 }
 
 int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) {
-  uint8_t *der;
-  size_t der_len;
-  if (!RSA_private_key_to_bytes(&der, &der_len, in)) {
+  CBB cbb;
+  if (!CBB_init(&cbb, 0) ||
+      !RSA_marshal_private_key(&cbb, in)) {
+    CBB_cleanup(&cbb);
     return -1;
   }
-  if (der_len > INT_MAX) {
-    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
-    OPENSSL_free(der);
-    return -1;
-  }
-  if (outp != NULL) {
-    if (*outp == NULL) {
-      *outp = der;
-      der = NULL;
-    } else {
-      memcpy(*outp, der, der_len);
-      *outp += der_len;
-    }
-  }
-  OPENSSL_free(der);
-  return (int)der_len;
+  return CBB_finish_i2d(&cbb, outp);
 }
 
-ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
-  ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
-  ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
-  ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
-  ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3),
-} ASN1_SEQUENCE_END(RSA_PSS_PARAMS);
-
-IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
-
 RSA *RSAPublicKey_dup(const RSA *rsa) {
   uint8_t *der;
   size_t der_len;
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index b1cfaa6..3e30d89 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -56,6 +56,7 @@
 
 #include <openssl/rsa.h>
 
+#include <assert.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -67,11 +68,42 @@
 #include "../internal.h"
 
 
-#define OPENSSL_RSA_MAX_MODULUS_BITS 16384
-#define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
-#define OPENSSL_RSA_MAX_PUBEXP_BITS \
-  64 /* exponent limit enforced for "large" modulus only */
+static int check_modulus_and_exponent_sizes(const RSA *rsa) {
+  unsigned rsa_bits = BN_num_bits(rsa->n);
 
+  if (rsa_bits > 16 * 1024) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
+    return 0;
+  }
+
+  /* Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as
+   * the limit based on the recommendations in [1] and [2]. Windows CryptoAPI
+   * doesn't support values larger than 32 bits [3], so it is unlikely that
+   * exponents larger than 32 bits are being used for anything Windows commonly
+   * does.
+   *
+   * [1] https://www.imperialviolet.org/2012/03/16/rsae.html
+   * [2] https://www.imperialviolet.org/2012/03/17/rsados.html
+   * [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx */
+  static const unsigned kMaxExponentBits = 33;
+
+  if (BN_num_bits(rsa->e) > kMaxExponentBits) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
+    return 0;
+  }
+
+  /* Verify |n > e|. Comparing |rsa_bits| to |kMaxExponentBits| is a small
+   * shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits|
+   * is much smaller than the minimum RSA key size that any application should
+   * accept. */
+  if (rsa_bits <= kMaxExponentBits) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
+    return 0;
+  }
+  assert(BN_ucmp(rsa->n, rsa->e) > 0);
+
+  return 1;
+}
 
 size_t rsa_default_size(const RSA *rsa) {
   return BN_num_bytes(rsa->n);
@@ -85,25 +117,12 @@
   BN_CTX *ctx = NULL;
   int i, ret = 0;
 
-  if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
-    return 0;
-  }
-
   if (max_out < rsa_size) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (BN_ucmp(rsa->n, rsa->e) <= 0) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
-    return 0;
-  }
-
-  /* for large moduli, enforce exponent limit */
-  if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
-      BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
+  if (!check_modulus_and_exponent_sizes(rsa)) {
     return 0;
   }
 
@@ -152,13 +171,8 @@
     goto err;
   }
 
-  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
-    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
-      goto err;
-    }
-  }
-
-  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
+  if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+      !BN_mod_exp_mont(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
     goto err;
   }
 
@@ -199,6 +213,9 @@
  * |*index_used| and must be passed to |rsa_blinding_release| when finished. */
 static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
                                      BN_CTX *ctx) {
+  assert(ctx != NULL);
+  assert(rsa->mont_n != NULL);
+
   BN_BLINDING *ret = NULL;
   BN_BLINDING **new_blindings;
   uint8_t *new_blindings_inuse;
@@ -227,7 +244,7 @@
    * the arrays by one and use the newly created element. */
 
   CRYPTO_MUTEX_unlock(&rsa->lock);
-  ret = rsa_setup_blinding(rsa, ctx);
+  ret = BN_BLINDING_new();
   if (ret == NULL) {
     return NULL;
   }
@@ -407,46 +424,49 @@
   return ret;
 }
 
-int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
-                           size_t max_out, const uint8_t *in, size_t in_len,
-                           int padding) {
+static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+
+int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+                   const uint8_t *in, size_t in_len, int padding) {
+  if (rsa->n == NULL || rsa->e == NULL) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+    return 0;
+  }
+
   const unsigned rsa_size = RSA_size(rsa);
   BIGNUM *f, *result;
-  int ret = 0;
   int r = -1;
-  uint8_t *buf = NULL;
-  BN_CTX *ctx = NULL;
-
-  if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
-    return 0;
-  }
-
-  if (BN_ucmp(rsa->n, rsa->e) <= 0) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
-    return 0;
-  }
 
   if (max_out < rsa_size) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  /* for large moduli, enforce exponent limit */
-  if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
-      BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
+  if (in_len != rsa_size) {
+    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
     return 0;
   }
 
-  ctx = BN_CTX_new();
-  if (ctx == NULL) {
-    goto err;
+  if (!check_modulus_and_exponent_sizes(rsa)) {
+    return 0;
   }
 
+  BN_CTX *ctx = BN_CTX_new();
+  if (ctx == NULL) {
+    return 0;
+  }
+
+  int ret = 0;
+  uint8_t *buf = NULL;
+
   BN_CTX_start(ctx);
   f = BN_CTX_get(ctx);
   result = BN_CTX_get(ctx);
+  if (f == NULL || result == NULL) {
+    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
+
   if (padding == RSA_NO_PADDING) {
     buf = out;
   } else {
@@ -457,15 +477,6 @@
       goto err;
     }
   }
-  if (!f || !result) {
-    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (in_len != rsa_size) {
-    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
-    goto err;
-  }
 
   if (BN_bin2bn(in, in_len, f) == NULL) {
     goto err;
@@ -476,13 +487,8 @@
     goto err;
   }
 
-  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
-    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
-      goto err;
-    }
-  }
-
-  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
+  if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+      !BN_mod_exp_mont(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
     goto err;
   }
 
@@ -511,12 +517,9 @@
   }
 
 err:
-  if (ctx != NULL) {
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-  }
-  if (padding != RSA_NO_PADDING && buf != NULL) {
-    OPENSSL_cleanse(buf, rsa_size);
+  BN_CTX_end(ctx);
+  BN_CTX_free(ctx);
+  if (buf != out) {
     OPENSSL_free(buf);
   }
   return ret;
@@ -554,20 +557,31 @@
   }
 
   if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+    /* Keys without public exponents must have blinding explicitly disabled to
+     * be used. */
+    if (rsa->e == NULL) {
+      OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
+      goto err;
+    }
+
+    if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
+      OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+      goto err;
+    }
+
     blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
     if (blinding == NULL) {
       OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
       goto err;
     }
-    if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
+    if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) {
       goto err;
     }
   }
 
-  if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
-      ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
-       (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
-    if (!rsa->meth->mod_exp(result, f, rsa, ctx)) {
+  if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL &&
+      rsa->dmq1 != NULL && rsa->iqmp != NULL) {
+    if (!mod_exp(result, f, rsa, ctx)) {
       goto err;
     }
   } else {
@@ -578,20 +592,14 @@
     d = &local_d;
     BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
 
-    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
-      if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ==
-          NULL) {
-        goto err;
-      }
-    }
-
-    if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->mont_n)) {
+    if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+        !BN_mod_exp_mont_consttime(result, f, d, rsa->n, ctx, rsa->mont_n)) {
       goto err;
     }
   }
 
   if (blinding) {
-    if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) {
+    if (!BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) {
       goto err;
     }
   }
@@ -616,6 +624,17 @@
 }
 
 static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
+  assert(ctx != NULL);
+
+  assert(rsa->n != NULL);
+  assert(rsa->e != NULL);
+  assert(rsa->d != NULL);
+  assert(rsa->p != NULL);
+  assert(rsa->q != NULL);
+  assert(rsa->dmp1 != NULL);
+  assert(rsa->dmq1 != NULL);
+  assert(rsa->iqmp != NULL);
+
   BIGNUM *r1, *m1, *vrfy;
   BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
   BIGNUM *dmp1, *dmq1, *c, *pr1;
@@ -630,6 +649,11 @@
   r1 = BN_CTX_get(ctx);
   m1 = BN_CTX_get(ctx);
   vrfy = BN_CTX_get(ctx);
+  if (r1 == NULL ||
+      m1 == NULL ||
+      vrfy == NULL) {
+    goto err;
+  }
 
   {
     BIGNUM local_p, local_q;
@@ -645,20 +669,14 @@
     q = &local_q;
     BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
 
-    if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
-      if (BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) == NULL) {
-        goto err;
-      }
-      if (BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx) == NULL) {
-        goto err;
-      }
+    if (!BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) ||
+        !BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx)) {
+      goto err;
     }
   }
 
-  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
-    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
-      goto err;
-    }
+  if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
+    goto err;
   }
 
   /* compute I mod q */
@@ -671,7 +689,7 @@
   /* compute r1^dmq1 mod q */
   dmq1 = &local_dmq1;
   BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
-  if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) {
+  if (!BN_mod_exp_mont_consttime(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) {
     goto err;
   }
 
@@ -685,7 +703,7 @@
   /* compute r1^dmp1 mod p */
   dmp1 = &local_dmp1;
   BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
-  if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->mont_p)) {
+  if (!BN_mod_exp_mont_consttime(r0, r1, dmp1, rsa->p, ctx, rsa->mont_p)) {
     goto err;
   }
 
@@ -745,12 +763,8 @@
       goto err;
     }
 
-    if ((rsa->flags & RSA_FLAG_CACHE_PRIVATE) &&
-        !BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx)) {
-      goto err;
-    }
-
-    if (!rsa->meth->bn_mod_exp(m1, r1, exp, prime, ctx, ap->mont)) {
+    if (!BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx) ||
+        !BN_mod_exp_mont_consttime(m1, r1, exp, prime, ctx, ap->mont)) {
       goto err;
     }
 
@@ -766,38 +780,35 @@
     }
   }
 
-  if (rsa->e && rsa->n) {
-    if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->mont_n)) {
+  if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, rsa->mont_n)) {
+    goto err;
+  }
+  /* If 'I' was greater than (or equal to) rsa->n, the operation will be
+   * equivalent to using 'I mod n'. However, the result of the verify will
+   * *always* be less than 'n' so we don't check for absolute equality, just
+   * congruency. */
+  if (!BN_sub(vrfy, vrfy, I)) {
+    goto err;
+  }
+  if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
+    goto err;
+  }
+  if (BN_is_negative(vrfy)) {
+    if (!BN_add(vrfy, vrfy, rsa->n)) {
       goto err;
     }
-    /* If 'I' was greater than (or equal to) rsa->n, the operation
-     * will be equivalent to using 'I mod n'. However, the result of
-     * the verify will *always* be less than 'n' so we don't check
-     * for absolute equality, just congruency. */
-    if (!BN_sub(vrfy, vrfy, I)) {
-      goto err;
-    }
-    if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
-      goto err;
-    }
-    if (BN_is_negative(vrfy)) {
-      if (!BN_add(vrfy, vrfy, rsa->n)) {
-        goto err;
-      }
-    }
-    if (!BN_is_zero(vrfy)) {
-      /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
-       * miscalculated CRT output, just do a raw (slower)
-       * mod_exp and return that instead. */
+  }
+  if (!BN_is_zero(vrfy)) {
+    /* 'I' and 'vrfy' aren't congruent mod n. Don't leak miscalculated CRT
+     * output, just do a raw (slower) mod_exp and return that instead. */
 
-      BIGNUM local_d;
-      BIGNUM *d = NULL;
+    BIGNUM local_d;
+    BIGNUM *d = NULL;
 
-      d = &local_d;
-      BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-      if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->mont_n)) {
-        goto err;
-      }
+    d = &local_d;
+    BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+    if (!BN_mod_exp_mont_consttime(r0, I, d, rsa->n, ctx, rsa->mont_n)) {
+      goto err;
     }
   }
   ret = 1;
@@ -1101,9 +1112,9 @@
                                         cb);
 }
 
-/* Many of these methods are NULL to more easily drop unused functions. The
- * wrapper functions will select the appropriate |rsa_default_*| for all
- * methods. */
+/* All of the methods are NULL to make it easier for the compiler/linker to drop
+ * unused functions. The wrapper functions will select the appropriate
+ * |rsa_default_*| implementation. */
 const RSA_METHOD RSA_default_method = {
   {
     0 /* references */,
@@ -1126,8 +1137,8 @@
 
   NULL /* private_transform (defaults to rsa_default_private_transform) */,
 
-  mod_exp,
-  BN_mod_exp_mont /* bn_mod_exp */,
+  NULL /* mod_exp (ignored) */,
+  NULL /* bn_mod_exp (ignored) */,
 
   RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
 
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
index 5545161..62177a4 100644
--- a/src/crypto/rsa/rsa_test.cc
+++ b/src/crypto/rsa/rsa_test.cc
@@ -63,7 +63,7 @@
 #include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "../test/scoped_types.h"
 
@@ -593,6 +593,7 @@
       fprintf(stderr, "Corrupt data decrypted!\n");
       return false;
     }
+    ERR_clear_error();
     ciphertext[i] ^= 1;
   }
 
@@ -603,6 +604,7 @@
       fprintf(stderr, "Corrupt data decrypted!\n");
       return false;
     }
+    ERR_clear_error();
   }
 
   return true;
@@ -693,25 +695,27 @@
 }
 
 static bool TestOnlyDGiven() {
+  static const char kN[] =
+      "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd09ac42b2662"
+      "1cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e5808c659";
+  static const char kE[] = "010001";
+  static const char kD[] =
+      "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea316eaeca21a"
+      "73ac365e58713195f2ae9849348525ca855386b6d028e437a9495a01";
+
   uint8_t buf[64];
   unsigned buf_len = sizeof(buf);
   ScopedRSA key(RSA_new());
   if (!key ||
-      !BN_hex2bn(&key->n,
-                 "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd"
-                 "09ac42b26621cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e"
-                 "5808c659") ||
-      !BN_hex2bn(&key->e, "010001") ||
-      !BN_hex2bn(&key->d,
-                 "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea"
-                 "316eaeca21a73ac365e58713195f2ae9849348525ca855386b6d028e437a9"
-                 "495a01") ||
+      !BN_hex2bn(&key->n, kN) ||
+      !BN_hex2bn(&key->e, kE) ||
+      !BN_hex2bn(&key->d, kD) ||
       RSA_size(key.get()) > sizeof(buf)) {
     return false;
   }
 
   if (!RSA_check_key(key.get())) {
-    fprintf(stderr, "RSA_check_key failed with only d given.\n");
+    fprintf(stderr, "RSA_check_key failed with only n, d, and e given.\n");
     ERR_print_errors_fp(stderr);
     return false;
   }
@@ -720,14 +724,46 @@
 
   if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
                 key.get())) {
-    fprintf(stderr, "RSA_sign failed with only d given.\n");
+    fprintf(stderr, "RSA_sign failed with only n, d, and e given.\n");
     ERR_print_errors_fp(stderr);
     return false;
   }
 
   if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
                   key.get())) {
-    fprintf(stderr, "RSA_verify failed with only d given.\n");
+    fprintf(stderr, "RSA_verify failed with only n, d, and e given.\n");
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  // Keys without the public exponent must continue to work when blinding is
+  // disabled to support Java's RSAPrivateKeySpec API. See
+  // https://bugs.chromium.org/p/boringssl/issues/detail?id=12.
+  ScopedRSA key2(RSA_new());
+  if (!key2 ||
+      !BN_hex2bn(&key2->n, kN) ||
+      !BN_hex2bn(&key2->d, kD)) {
+    return false;
+  }
+  key2->flags |= RSA_FLAG_NO_BLINDING;
+
+  if (RSA_size(key2.get()) > sizeof(buf)) {
+    return false;
+  }
+
+  if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+                key2.get())) {
+    fprintf(stderr, "RSA_sign failed with only n and d given.\n");
+    ERR_print_errors_fp(stderr);
+    return false;
+  }
+
+  // Verify the signature with |key|. |key2| has no public exponent.
+  if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
+                  key.get())) {
+    fprintf(stderr,
+            "Could not verify signature produced from key with only n and d "
+            "given.\n");
     ERR_print_errors_fp(stderr);
     return false;
   }
diff --git a/src/crypto/sha/asm/sha512-armv4.pl b/src/crypto/sha/asm/sha512-armv4.pl
index cd3662a..15d50f2 100644
--- a/src/crypto/sha/asm/sha512-armv4.pl
+++ b/src/crypto/sha/asm/sha512-armv4.pl
@@ -291,7 +291,7 @@
 #ifdef	__APPLE__
 	ldr	r12,[r12]
 #endif
-	tst	r12,#1
+	tst	r12,#ARMV7_NEON
 	bne	.LNEON
 #endif
 	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c
index 0ddacba..58f7c42 100644
--- a/src/crypto/sha/sha256.c
+++ b/src/crypto/sha/sha256.c
@@ -104,8 +104,8 @@
     out = buf;
   }
   SHA224_Init(&ctx);
-  SHA256_Update(&ctx, data, len);
-  SHA256_Final(out, &ctx);
+  SHA224_Update(&ctx, data, len);
+  SHA224_Final(out, &ctx);
   OPENSSL_cleanse(&ctx, sizeof(ctx));
   return out;
 }
diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c
index 6ad8d40..f473046 100644
--- a/src/crypto/sha/sha512.c
+++ b/src/crypto/sha/sha512.c
@@ -129,8 +129,8 @@
   }
 
   SHA384_Init(&ctx);
-  SHA512_Update(&ctx, data, len);
-  SHA512_Final(out, &ctx);
+  SHA384_Update(&ctx, data, len);
+  SHA384_Final(out, &ctx);
   OPENSSL_cleanse(&ctx, sizeof(ctx));
   return out;
 }
diff --git a/src/crypto/stack/stack.c b/src/crypto/stack/stack.c
index c584515..e893221 100644
--- a/src/crypto/stack/stack.c
+++ b/src/crypto/stack/stack.c
@@ -329,7 +329,7 @@
 void sk_sort(_STACK *sk) {
   int (*comp_func)(const void *,const void *);
 
-  if (sk == NULL || sk->sorted) {
+  if (sk == NULL || sk->comp == NULL || sk->sorted) {
     return;
   }
 
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 4752f04..d684aa0 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -14,6 +14,8 @@
 
 #include "file_test.h"
 
+#include <memory>
+
 #include <ctype.h>
 #include <errno.h>
 #include <stdarg.h>
@@ -63,30 +65,23 @@
 }
 
 FileTest::ReadResult FileTest::ReadNext() {
-  // If the previous test had unused attributes or block, it is an error.
+  // If the previous test had unused attributes, it is an error.
   if (!unused_attributes_.empty()) {
     for (const std::string &key : unused_attributes_) {
       PrintLine("Unused attribute: %s", key.c_str());
     }
     return kReadError;
   }
-  if (!block_.empty() && !used_block_) {
-    PrintLine("Unused block");
-    return kReadError;
-  }
 
   ClearTest();
 
-  bool in_block = false;
+  static const size_t kBufLen = 64 + 8192*2;
+  std::unique_ptr<char[]> buf(new char[kBufLen]);
+
   while (true) {
     // Read the next line.
-    char buf[4096];
-    if (fgets(buf, sizeof(buf), file_) == nullptr) {
+    if (fgets(buf.get(), kBufLen, file_) == nullptr) {
       if (feof(file_)) {
-        if (in_block) {
-          fprintf(stderr, "Unterminated block.\n");
-          return kReadError;
-        }
         // EOF is a valid terminator for a test.
         return start_line_ > 0 ? kReadSuccess : kReadEOF;
       }
@@ -95,42 +90,28 @@
     }
 
     line_++;
-    size_t len = strlen(buf);
+    size_t len = strlen(buf.get());
     // Check for truncation.
     if (len > 0 && buf[len - 1] != '\n' && !feof(file_)) {
       fprintf(stderr, "Line %u too long.\n", line_);
       return kReadError;
     }
 
-    bool is_delimiter = strncmp(buf, "---", 3) == 0;
-    if (in_block) {
-      block_ += buf;
-      if (is_delimiter) {
-        // Ending the block completes the test.
-        return kReadSuccess;
-      }
-    } else if (is_delimiter) {
-      if (start_line_ == 0) {
-        fprintf(stderr, "Line %u: Unexpected block.\n", line_);
-        return kReadError;
-      }
-      in_block = true;
-      block_ += buf;
-    } else if (buf[0] == '\n' || buf[0] == '\0') {
+    if (buf[0] == '\n' || buf[0] == '\0') {
       // Empty lines delimit tests.
       if (start_line_ > 0) {
         return kReadSuccess;
       }
     } else if (buf[0] != '#') {  // Comment lines are ignored.
       // Parse the line as an attribute.
-      const char *delimiter = FindDelimiter(buf);
+      const char *delimiter = FindDelimiter(buf.get());
       if (delimiter == nullptr) {
         fprintf(stderr, "Line %u: Could not parse attribute.\n", line_);
         return kReadError;
       }
-      std::string key = StripSpace(buf, delimiter - buf);
+      std::string key = StripSpace(buf.get(), delimiter - buf.get());
       std::string value = StripSpace(delimiter + 1,
-                                     buf + len - delimiter - 1);
+                                     buf.get() + len - delimiter - 1);
 
       unused_attributes_.insert(key);
       attributes_[key] = value;
@@ -165,11 +146,6 @@
   return parameter_;
 }
 
-const std::string &FileTest::GetBlock() {
-  used_block_ = true;
-  return block_;
-}
-
 bool FileTest::HasAttribute(const std::string &key) {
   OnKeyUsed(key);
   return attributes_.count(key) > 0;
@@ -224,6 +200,7 @@
     PrintLine("Error decoding value: %s", value.c_str());
     return false;
   }
+  out->clear();
   out->reserve(value.size() / 2);
   for (size_t i = 0; i < value.size(); i += 2) {
     uint8_t hi, lo;
@@ -266,9 +243,7 @@
   type_.clear();
   parameter_.clear();
   attributes_.clear();
-  block_.clear();
   unused_attributes_.clear();
-  used_block_ = false;
 }
 
 void FileTest::OnKeyUsed(const std::string &key) {
@@ -304,6 +279,7 @@
                      t.GetAttributeOrDie("Error").c_str(),
                      ERR_reason_error_string(err));
         failed = true;
+        ERR_clear_error();
         continue;
       }
       ERR_clear_error();
diff --git a/src/crypto/test/file_test.h b/src/crypto/test/file_test.h
index 24651ab..e90cc86 100644
--- a/src/crypto/test/file_test.h
+++ b/src/crypto/test/file_test.h
@@ -15,6 +15,8 @@
 #ifndef OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
 #define OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
 
+#include <openssl/base.h>
+
 #include <stdint.h>
 #include <stdio.h>
 
@@ -36,7 +38,7 @@
 //
 // This module provides a file-based test framework. The file format is based on
 // that of OpenSSL upstream's evp_test and BoringSSL's aead_test. Each input
-// file is a sequence of attributes, blocks, and blank lines.
+// file is a sequence of attributes and blank lines.
 //
 // Each attribute has the form:
 //
@@ -45,15 +47,11 @@
 // Either '=' or ':' may be used to delimit the name from the value. Both the
 // name and value have leading and trailing spaces stripped.
 //
-// Blocks are delimited by lines beginning with three hyphens, "---". One such
-// line begins a block and another ends it. Blocks are intended as a convenient
-// way to embed PEM data and include their delimiters.
+// Lines beginning with # are ignored.
 //
-// Outside a block, lines beginning with # are ignored.
-//
-// A test is a sequence of one or more attributes followed by a block or blank
-// line. Blank lines are otherwise ignored. For tests that process multiple
-// kinds of test cases, the first attribute is parsed out as the test's type and
+// A test is a sequence of one or more attributes followed by a blank line.
+// Blank lines are otherwise ignored. For tests that process multiple kinds of
+// test cases, the first attribute is parsed out as the test's type and
 // parameter. Otherwise, attributes are unordered. The first attribute is also
 // included in the set of attributes, so tests which do not dispatch may ignore
 // this mechanism.
@@ -88,11 +86,7 @@
 
   // PrintLine is a variant of printf which prepends the line number and appends
   // a trailing newline.
-  void PrintLine(const char *format, ...)
-#ifdef __GNUC__
-      __attribute__((__format__(__printf__, 2, 3)))
-#endif
-  ;
+  void PrintLine(const char *format, ...) OPENSSL_PRINTF_FORMAT_FUNC(2, 3);
 
   unsigned start_line() const { return start_line_; }
 
@@ -100,9 +94,6 @@
   const std::string &GetType();
   // GetParameter returns the value of the first attribute of the current test.
   const std::string &GetParameter();
-  // GetBlock returns the optional block of the current test, or the empty
-  // if there was no block.
-  const std::string &GetBlock();
 
   // HasAttribute returns true if the current test has an attribute named |key|.
   bool HasAttribute(const std::string &key);
@@ -113,7 +104,7 @@
   bool GetAttribute(std::string *out_value, const std::string &key);
 
   // GetAttributeOrDie looks up the attribute with key |key| and aborts if it is
-  // missing. It only be used after a |HasAttribute| call.
+  // missing. It should only be used after a |HasAttribute| call.
   const std::string &GetAttributeOrDie(const std::string &key);
 
   // GetBytes looks up the attribute with key |key| and decodes it as a byte
@@ -144,13 +135,9 @@
   std::string parameter_;
   // attributes_ contains all attributes in the test, including the first.
   std::map<std::string, std::string> attributes_;
-  // block_, if non-empty, is the test's optional trailing block.
-  std::string block_;
 
   // unused_attributes_ is the set of attributes that have been queried.
   std::set<std::string> unused_attributes_;
-  // used_block_ is true if the block has been queried.
-  bool used_block_ = false;
 
   FileTest(const FileTest&) = delete;
   FileTest &operator=(const FileTest&) = delete;
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index 590f926..5c49a7e 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -21,13 +21,16 @@
 #include <memory>
 
 #include <openssl/aead.h>
+#include <openssl/asn1.h>
 #include <openssl/bio.h>
 #include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/cmac.h>
+#include <openssl/curve25519.h>
 #include <openssl/dh.h>
+#include <openssl/ecdsa.h>
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
-#include <openssl/ecdsa.h>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/mem.h>
@@ -95,6 +98,7 @@
   T ctx_;
 };
 
+using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
 using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
 using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
 using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
@@ -110,10 +114,12 @@
 using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
                                                     PKCS8_PRIV_KEY_INFO_free>;
 using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
+using ScopedSPAKE2_CTX = ScopedOpenSSLType<SPAKE2_CTX, SPAKE2_CTX_free>;
 using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
 using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
 using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
 using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
+using ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
 
 using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
 
diff --git a/src/crypto/test/test_util.h b/src/crypto/test/test_util.h
index 972e206..89e70c6 100644
--- a/src/crypto/test/test_util.h
+++ b/src/crypto/test/test_util.h
@@ -28,6 +28,14 @@
 void hexdump(FILE *fp, const char *msg, const void *in, size_t len);
 
 
+#if defined(_MSC_VER) && _MSC_VER < 1900
+/* https://msdn.microsoft.com/en-us/library/tcxf1dw6(v=vs.120).aspx */
+#define OPENSSL_PR_SIZE_T "Iu"
+#else
+#define OPENSSL_PR_SIZE_T "zu"
+#endif
+
+
 #if defined(__cplusplus)
 }
 #endif
diff --git a/src/crypto/thread_pthread.c b/src/crypto/thread_pthread.c
index 68aaab5..2a1c9f8 100644
--- a/src/crypto/thread_pthread.c
+++ b/src/crypto/thread_pthread.c
@@ -17,7 +17,6 @@
 #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
 
 #include <pthread.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -76,8 +75,6 @@
 
 void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
   if (pthread_once(once, init) != 0) {
-    fprintf(stderr,
-            "pthread_once failed. Did you link against a threading library?\n");
     abort();
   }
 }
diff --git a/src/crypto/thread_test.c b/src/crypto/thread_test.c
index e028b1b..92a5373 100644
--- a/src/crypto/thread_test.c
+++ b/src/crypto/thread_test.c
@@ -53,6 +53,8 @@
 #else
 
 #include <pthread.h>
+#include <string.h>
+#include <time.h>
 
 typedef pthread_t thread_t;
 
@@ -77,6 +79,17 @@
 
 static void once_init(void) {
   g_once_init_called++;
+
+  /* Sleep briefly so one |call_once_thread| instance will call |CRYPTO_once|
+   * while the other is running this function. */
+#if defined(OPENSSL_WINDOWS)
+  Sleep(1 /* milliseconds */);
+#else
+  struct timespec req;
+  memset(&req, 0, sizeof(req));
+  req.tv_nsec = 1000000;
+  nanosleep(&req, NULL);
+#endif
 }
 
 static CRYPTO_once_t g_test_once = CRYPTO_ONCE_INIT;
@@ -91,9 +104,11 @@
     return 0;
   }
 
-  thread_t thread;
-  if (!run_thread(&thread, call_once_thread) ||
-      !wait_for_thread(thread)) {
+  thread_t thread1, thread2;
+  if (!run_thread(&thread1, call_once_thread) ||
+      !run_thread(&thread2, call_once_thread) ||
+      !wait_for_thread(thread1) ||
+      !wait_for_thread(thread2)) {
     fprintf(stderr, "thread failed.\n");
     return 0;
   }
diff --git a/src/crypto/thread_win.c b/src/crypto/thread_win.c
index 5efd8be..2632565 100644
--- a/src/crypto/thread_win.c
+++ b/src/crypto/thread_win.c
@@ -20,7 +20,6 @@
 #include <windows.h>
 #pragma warning(pop)
 
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -31,61 +30,16 @@
 OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(CRITICAL_SECTION),
                        CRYPTO_MUTEX_too_small);
 
-static void run_once(CRYPTO_once_t *in_once, void (*init)(void *), void *arg) {
-  volatile LONG *once = in_once;
-
-  /* Values must be aligned. */
-  assert((((uintptr_t) once) & 3) == 0);
-
-  /* This assumes that reading *once has acquire semantics. This should be true
-   * on x86 and x86-64, where we expect Windows to run. */
-#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64)
-#error "Windows once code may not work on other platforms." \
-       "You can use InitOnceBeginInitialize on >=Vista"
-#endif
-  if (*once == 1) {
-    return;
-  }
-
-  for (;;) {
-    switch (InterlockedCompareExchange(once, 2, 0)) {
-      case 0:
-        /* The value was zero so we are the first thread to call |CRYPTO_once|
-         * on it. */
-        init(arg);
-        /* Write one to indicate that initialisation is complete. */
-        InterlockedExchange(once, 1);
-        return;
-
-      case 1:
-        /* Another thread completed initialisation between our fast-path check
-         * and |InterlockedCompareExchange|. */
-        return;
-
-      case 2:
-        /* Another thread is running the initialisation. Switch to it then try
-         * again. */
-        SwitchToThread();
-        break;
-
-      default:
-        abort();
-    }
-  }
+static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) {
+  void (**init)(void) = (void (**)(void))arg;
+  (**init)();
+  return TRUE;
 }
 
-static void call_once_init(void *arg) {
-  void (*init_func)(void);
-  /* MSVC does not like casting between data and function pointers. */
-  memcpy(&init_func, &arg, sizeof(void *));
-  init_func();
-}
-
-void CRYPTO_once(CRYPTO_once_t *in_once, void (*init)(void)) {
-  void *arg;
-  /* MSVC does not like casting between data and function pointers. */
-  memcpy(&arg, &init, sizeof(void *));
-  run_once(in_once, call_once_init, arg);
+void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
+  if (!InitOnceExecuteOnce(once, call_once_init, &init, NULL)) {
+    abort();
+  }
 }
 
 void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
@@ -111,16 +65,21 @@
   DeleteCriticalSection((CRITICAL_SECTION *) lock);
 }
 
-static void static_lock_init(void *arg) {
+static BOOL CALLBACK static_lock_init(INIT_ONCE *once, void *arg, void **out) {
   struct CRYPTO_STATIC_MUTEX *lock = arg;
   if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0x400)) {
     abort();
   }
+  return TRUE;
 }
 
 void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
-  /* Since we have to support Windows XP, read locks are actually exclusive. */
-  run_once(&lock->once, static_lock_init, lock);
+  /* TODO(davidben): Consider replacing these with SRWLOCK now that we no longer
+   * need to support Windows XP. Currently, read locks are actually
+   * exclusive. */
+  if (!InitOnceExecuteOnce(&lock->once, static_lock_init, lock, NULL)) {
+    abort();
+  }
   EnterCriticalSection(&lock->lock);
 }
 
@@ -148,9 +107,14 @@
   g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES);
 }
 
-static void NTAPI thread_local_destructor(PVOID module,
-                                          DWORD reason, PVOID reserved) {
-  if (DLL_THREAD_DETACH != reason && DLL_PROCESS_DETACH != reason) {
+static void NTAPI thread_local_destructor(PVOID module, DWORD reason,
+                                          PVOID reserved) {
+  /* Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In
+   * VS2015's debug runtime, the C runtime has been unloaded by the time
+   * |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent
+   * with |pthread_key_create| which does not call destructors on process exit,
+   * only thread exit. */
+  if (reason != DLL_THREAD_DETACH) {
     return;
   }
 
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 8ffeaa0..5d82e0a 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -9,11 +9,13 @@
   a_sign.c
   a_strex.c
   a_verify.c
+  algorithm.c
   asn1_gen.c
   by_dir.c
   by_file.c
   i2d_pr.c
   pkcs7.c
+  rsa_pss.c
   t_crl.c
   t_req.c
   t_x509.c
@@ -64,5 +66,14 @@
   $<TARGET_OBJECTS:test_support>
 )
 
+add_executable(
+  x509_test
+
+  x509_test.cc
+
+  $<TARGET_OBJECTS:test_support>
+)
+
 target_link_libraries(pkcs7_test crypto)
-add_dependencies(all_tests pkcs7_test)
+target_link_libraries(x509_test crypto)
+add_dependencies(all_tests pkcs7_test x509_test)
diff --git a/src/crypto/x509/a_digest.c b/src/crypto/x509/a_digest.c
index 430e2e6..b88d6ac 100644
--- a/src/crypto/x509/a_digest.c
+++ b/src/crypto/x509/a_digest.c
@@ -61,37 +61,36 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-
 int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
-		unsigned char *md, unsigned int *len)
-	{
-	int i, ret;
-	unsigned char *str,*p;
+                unsigned char *md, unsigned int *len)
+{
+    int i, ret;
+    unsigned char *str, *p;
 
-	i=i2d(data,NULL);
-	if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	p=str;
-	i2d(data,&p);
+    i = i2d(data, NULL);
+    if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    p = str;
+    i2d(data, &p);
 
-	ret = EVP_Digest(str, i, md, len, type, NULL);
-	OPENSSL_free(str);
-	return ret;
-	}
+    ret = EVP_Digest(str, i, md, len, type, NULL);
+    OPENSSL_free(str);
+    return ret;
+}
 
 int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
-		unsigned char *md, unsigned int *len)
-	{
-	int i, ret;
-	unsigned char *str = NULL;
+                     unsigned char *md, unsigned int *len)
+{
+    int i, ret;
+    unsigned char *str = NULL;
 
-	i=ASN1_item_i2d(asn,&str, it);
-	if (!str) return(0);
+    i = ASN1_item_i2d(asn, &str, it);
+    if (!str)
+        return (0);
 
-	ret = EVP_Digest(str, i, md, len, type, NULL);
-	OPENSSL_free(str);
-	return ret;
-	}
+    ret = EVP_Digest(str, i, md, len, type, NULL);
+    OPENSSL_free(str);
+    return ret;
+}
diff --git a/src/crypto/x509/a_sign.c b/src/crypto/x509/a_sign.c
index 4e9be8a..13a3ac2 100644
--- a/src/crypto/x509/a_sign.c
+++ b/src/crypto/x509/a_sign.c
@@ -62,75 +62,74 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-#include "../evp/internal.h"
+#include "internal.h"
 
-
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
-	     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
-	     const EVP_MD *type)
-	{
-	EVP_MD_CTX ctx;
-	EVP_MD_CTX_init(&ctx);
-	if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
-		{
-		EVP_MD_CTX_cleanup(&ctx);
-		return 0;
-		}
-	return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
-	}
-		
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
+                   EVP_PKEY *pkey, const EVP_MD *type)
+{
+    EVP_MD_CTX ctx;
+    EVP_MD_CTX_init(&ctx);
+    if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
+        EVP_MD_CTX_cleanup(&ctx);
+        return 0;
+    }
+    return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+}
 
 int ASN1_item_sign_ctx(const ASN1_ITEM *it,
-		X509_ALGOR *algor1, X509_ALGOR *algor2,
-	     	ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
-	{
-	EVP_PKEY *pkey;
-	unsigned char *buf_in=NULL,*buf_out=NULL;
-	size_t inl=0,outl=0,outll=0;
+                       X509_ALGOR *algor1, X509_ALGOR *algor2,
+                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+    EVP_PKEY *pkey;
+    unsigned char *buf_in = NULL, *buf_out = NULL;
+    size_t inl = 0, outl = 0, outll = 0;
 
-	pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+    pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
 
-	/* Write out the requested copies of the AlgorithmIdentifier. */
-	if (algor1 && !EVP_DigestSignAlgorithm(ctx, algor1))
-		{
-		goto err;
-		}
-	if (algor2 && !EVP_DigestSignAlgorithm(ctx, algor2))
-		{
-		goto err;
-		}
+    /* Write out the requested copies of the AlgorithmIdentifier. */
+    if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) {
+        goto err;
+    }
+    if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) {
+        goto err;
+    }
 
-	inl=ASN1_item_i2d(asn,&buf_in, it);
-	outll=outl=EVP_PKEY_size(pkey);
-	buf_out=OPENSSL_malloc((unsigned int)outl);
-	if ((buf_in == NULL) || (buf_out == NULL))
-		{
-		outl=0;
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    inl = ASN1_item_i2d(asn, &buf_in, it);
+    outll = outl = EVP_PKEY_size(pkey);
+    buf_out = OPENSSL_malloc((unsigned int)outl);
+    if ((buf_in == NULL) || (buf_out == NULL)) {
+        outl = 0;
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
-		|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
-		{
-		outl=0;
-		OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
-		goto err;
-		}
-	if (signature->data != NULL) OPENSSL_free(signature->data);
-	signature->data=buf_out;
-	buf_out=NULL;
-	signature->length=outl;
-	/* In the interests of compatibility, I'll make sure that
-	 * the bit string has a 'not-used bits' value of 0
-	 */
-	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
-	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
-err:
-	EVP_MD_CTX_cleanup(ctx);
-	if (buf_in != NULL)
-		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
-	if (buf_out != NULL)
-		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
-	return(outl);
-	}
+    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+        outl = 0;
+        OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+        goto err;
+    }
+    if (signature->data != NULL)
+        OPENSSL_free(signature->data);
+    signature->data = buf_out;
+    buf_out = NULL;
+    signature->length = outl;
+    /*
+     * In the interests of compatibility, I'll make sure that the bit string
+     * has a 'not-used bits' value of 0
+     */
+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+    EVP_MD_CTX_cleanup(ctx);
+    if (buf_in != NULL) {
+        OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
+        OPENSSL_free(buf_in);
+    }
+    if (buf_out != NULL) {
+        OPENSSL_cleanse((char *)buf_out, outll);
+        OPENSSL_free(buf_out);
+    }
+    return (outl);
+}
diff --git a/src/crypto/x509/a_strex.c b/src/crypto/x509/a_strex.c
index b194d18..aa2501a 100644
--- a/src/crypto/x509/a_strex.c
+++ b/src/crypto/x509/a_strex.c
@@ -64,501 +64,570 @@
 
 #include "charmap.h"
 
-
-/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
- * Enhanced string and name printing routines handling
- * multibyte characters, RFC2253 and a host of other
- * options.
+/*
+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+ * printing routines handling multibyte characters, RFC2253 and a host of
+ * other options.
  */
 
-
-#define CHARTYPE_BS_ESC		(ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+#define CHARTYPE_BS_ESC         (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
 
 #define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
-		  ASN1_STRFLGS_ESC_QUOTE | \
-		  ASN1_STRFLGS_ESC_CTRL | \
-		  ASN1_STRFLGS_ESC_MSB)
-
+                  ASN1_STRFLGS_ESC_QUOTE | \
+                  ASN1_STRFLGS_ESC_CTRL | \
+                  ASN1_STRFLGS_ESC_MSB)
 
 static int send_bio_chars(void *arg, const void *buf, int len)
 {
-	if(!arg) return 1;
-	if(BIO_write(arg, buf, len) != len) return 0;
-	return 1;
+    if (!arg)
+        return 1;
+    if (BIO_write(arg, buf, len) != len)
+        return 0;
+    return 1;
 }
 
 static int send_fp_chars(void *arg, const void *buf, int len)
 {
-	if(!arg) return 1;
-	if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
-	return 1;
+    if (!arg)
+        return 1;
+    if (fwrite(buf, 1, len, arg) != (unsigned int)len)
+        return 0;
+    return 1;
 }
 
-typedef int char_io(void *arg, const void *buf, int len);
+typedef int char_io (void *arg, const void *buf, int len);
 
-/* This function handles display of
- * strings, one character at a time.
- * It is passed an unsigned long for each
- * character because it could come from 2 or even
- * 4 byte forms.
+/*
+ * This function handles display of strings, one character at a time. It is
+ * passed an unsigned long for each character because it could come from 2 or
+ * even 4 byte forms.
  */
 
 #define HEX_SIZE(type) (sizeof(type)*2)
 
-static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
+                       char_io *io_ch, void *arg)
 {
-	unsigned char chflgs, chtmp;
-	char tmphex[HEX_SIZE(long)+3];
+    unsigned char chflgs, chtmp;
+    char tmphex[HEX_SIZE(long) + 3];
 
-	if(c > 0xffffffffL)
-		return -1;
-	if(c > 0xffff) {
-		BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
-		if(!io_ch(arg, tmphex, 10)) return -1;
-		return 10;
-	}
-	if(c > 0xff) {
-		BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
-		if(!io_ch(arg, tmphex, 6)) return -1;
-		return 6;
-	}
-	chtmp = (unsigned char)c;
-	if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
-	else chflgs = char_type[chtmp] & flags;
-	if(chflgs & CHARTYPE_BS_ESC) {
-		/* If we don't escape with quotes, signal we need quotes */
-		if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
-			if(do_quotes) *do_quotes = 1;
-			if(!io_ch(arg, &chtmp, 1)) return -1;
-			return 1;
-		}
-		if(!io_ch(arg, "\\", 1)) return -1;
-		if(!io_ch(arg, &chtmp, 1)) return -1;
-		return 2;
-	}
-	if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
-		BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
-		if(!io_ch(arg, tmphex, 3)) return -1;
-		return 3;
-	}
-	/* If we get this far and do any escaping at all must escape 
-	 * the escape character itself: backslash.
-	 */
-	if (chtmp == '\\' && flags & ESC_FLAGS) {
-		if(!io_ch(arg, "\\\\", 2)) return -1;
-		return 2;
-	}
-	if(!io_ch(arg, &chtmp, 1)) return -1;
-	return 1;
+    if (c > 0xffffffffL)
+        return -1;
+    if (c > 0xffff) {
+        BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+        if (!io_ch(arg, tmphex, 10))
+            return -1;
+        return 10;
+    }
+    if (c > 0xff) {
+        BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+        if (!io_ch(arg, tmphex, 6))
+            return -1;
+        return 6;
+    }
+    chtmp = (unsigned char)c;
+    if (chtmp > 0x7f)
+        chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+    else
+        chflgs = char_type[chtmp] & flags;
+    if (chflgs & CHARTYPE_BS_ESC) {
+        /* If we don't escape with quotes, signal we need quotes */
+        if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+            if (do_quotes)
+                *do_quotes = 1;
+            if (!io_ch(arg, &chtmp, 1))
+                return -1;
+            return 1;
+        }
+        if (!io_ch(arg, "\\", 1))
+            return -1;
+        if (!io_ch(arg, &chtmp, 1))
+            return -1;
+        return 2;
+    }
+    if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) {
+        BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+        if (!io_ch(arg, tmphex, 3))
+            return -1;
+        return 3;
+    }
+    /*
+     * If we get this far and do any escaping at all must escape the escape
+     * character itself: backslash.
+     */
+    if (chtmp == '\\' && flags & ESC_FLAGS) {
+        if (!io_ch(arg, "\\\\", 2))
+            return -1;
+        return 2;
+    }
+    if (!io_ch(arg, &chtmp, 1))
+        return -1;
+    return 1;
 }
 
-#define BUF_TYPE_WIDTH_MASK	0x7
-#define BUF_TYPE_CONVUTF8	0x8
+#define BUF_TYPE_WIDTH_MASK     0x7
+#define BUF_TYPE_CONVUTF8       0x8
 
-/* This function sends each character in a buffer to
- * do_esc_char(). It interprets the content formats
- * and converts to or from UTF8 as appropriate.
+/*
+ * This function sends each character in a buffer to do_esc_char(). It
+ * interprets the content formats and converts to or from UTF8 as
+ * appropriate.
  */
 
 static int do_buf(unsigned char *buf, int buflen,
-			int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
+                  int type, unsigned char flags, char *quotes, char_io *io_ch,
+                  void *arg)
 {
-	int i, outlen, len;
-	unsigned char orflags, *p, *q;
-	unsigned long c;
-	p = buf;
-	q = buf + buflen;
-	outlen = 0;
-	while(p != q) {
-		if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
-		else orflags = 0;
-		switch(type & BUF_TYPE_WIDTH_MASK) {
-			case 4:
-			c = ((unsigned long)*p++) << 24;
-			c |= ((unsigned long)*p++) << 16;
-			c |= ((unsigned long)*p++) << 8;
-			c |= *p++;
-			break;
+    int i, outlen, len;
+    unsigned char orflags, *p, *q;
+    unsigned long c;
+    p = buf;
+    q = buf + buflen;
+    outlen = 0;
+    while (p != q) {
+        if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_FIRST_ESC_2253;
+        else
+            orflags = 0;
+        switch (type & BUF_TYPE_WIDTH_MASK) {
+        case 4:
+            c = ((unsigned long)*p++) << 24;
+            c |= ((unsigned long)*p++) << 16;
+            c |= ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
 
-			case 2:
-			c = ((unsigned long)*p++) << 8;
-			c |= *p++;
-			break;
+        case 2:
+            c = ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
 
-			case 1:
-			c = *p++;
-			break;
-			
-			case 0:
-			i = UTF8_getc(p, buflen, &c);
-			if(i < 0) return -1;	/* Invalid UTF8String */
-			p += i;
-			break;
-			default:
-			return -1;	/* invalid width */
-		}
-		if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
-		if(type & BUF_TYPE_CONVUTF8) {
-			unsigned char utfbuf[6];
-			int utflen;
-			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
-			for(i = 0; i < utflen; i++) {
-				/* We don't need to worry about setting orflags correctly
-				 * because if utflen==1 its value will be correct anyway 
-				 * otherwise each character will be > 0x7f and so the 
-				 * character will never be escaped on first and last.
-				 */
-				len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
-				if(len < 0) return -1;
-				outlen += len;
-			}
-		} else {
-			len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
-			if(len < 0) return -1;
-			outlen += len;
-		}
-	}
-	return outlen;
+        case 1:
+            c = *p++;
+            break;
+
+        case 0:
+            i = UTF8_getc(p, buflen, &c);
+            if (i < 0)
+                return -1;      /* Invalid UTF8String */
+            p += i;
+            break;
+        default:
+            return -1;          /* invalid width */
+        }
+        if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_LAST_ESC_2253;
+        if (type & BUF_TYPE_CONVUTF8) {
+            unsigned char utfbuf[6];
+            int utflen;
+            utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+            for (i = 0; i < utflen; i++) {
+                /*
+                 * We don't need to worry about setting orflags correctly
+                 * because if utflen==1 its value will be correct anyway
+                 * otherwise each character will be > 0x7f and so the
+                 * character will never be escaped on first and last.
+                 */
+                len =
+                    do_esc_char(utfbuf[i], (unsigned char)(flags | orflags),
+                                quotes, io_ch, arg);
+                if (len < 0)
+                    return -1;
+                outlen += len;
+            }
+        } else {
+            len =
+                do_esc_char(c, (unsigned char)(flags | orflags), quotes,
+                            io_ch, arg);
+            if (len < 0)
+                return -1;
+            outlen += len;
+        }
+    }
+    return outlen;
 }
 
 /* This function hex dumps a buffer of characters */
 
-static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+                       int buflen)
 {
-	static const char hexdig[] = "0123456789ABCDEF";
-	unsigned char *p, *q;
-	char hextmp[2];
-	if(arg) {
-		p = buf;
-		q = buf + buflen;
-		while(p != q) {
-			hextmp[0] = hexdig[*p >> 4];
-			hextmp[1] = hexdig[*p & 0xf];
-			if(!io_ch(arg, hextmp, 2)) return -1;
-			p++;
-		}
-	}
-	return buflen << 1;
+    static const char hexdig[] = "0123456789ABCDEF";
+    unsigned char *p, *q;
+    char hextmp[2];
+    if (arg) {
+        p = buf;
+        q = buf + buflen;
+        while (p != q) {
+            hextmp[0] = hexdig[*p >> 4];
+            hextmp[1] = hexdig[*p & 0xf];
+            if (!io_ch(arg, hextmp, 2))
+                return -1;
+            p++;
+        }
+    }
+    return buflen << 1;
 }
 
-/* "dump" a string. This is done when the type is unknown,
- * or the flags request it. We can either dump the content
- * octets or the entire DER encoding. This uses the RFC2253
- * #01234 format.
+/*
+ * "dump" a string. This is done when the type is unknown, or the flags
+ * request it. We can either dump the content octets or the entire DER
+ * encoding. This uses the RFC2253 #01234 format.
  */
 
-static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
+                   ASN1_STRING *str)
 {
-	/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
-	 * the DER encoding to readily obtained
-	 */
-	ASN1_TYPE t;
-	unsigned char *der_buf, *p;
-	int outlen, der_len;
+    /*
+     * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
+     * readily obtained
+     */
+    ASN1_TYPE t;
+    unsigned char *der_buf, *p;
+    int outlen, der_len;
 
-	if(!io_ch(arg, "#", 1)) return -1;
-	/* If we don't dump DER encoding just dump content octets */
-	if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
-		outlen = do_hex_dump(io_ch, arg, str->data, str->length);
-		if(outlen < 0) return -1;
-		return outlen + 1;
-	}
-	t.type = str->type;
-	t.value.ptr = (char *)str;
-	der_len = i2d_ASN1_TYPE(&t, NULL);
-	der_buf = OPENSSL_malloc(der_len);
-	if(!der_buf) return -1;
-	p = der_buf;
-	i2d_ASN1_TYPE(&t, &p);
-	outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
-	OPENSSL_free(der_buf);
-	if(outlen < 0) return -1;
-	return outlen + 1;
+    if (!io_ch(arg, "#", 1))
+        return -1;
+    /* If we don't dump DER encoding just dump content octets */
+    if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+        outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+        if (outlen < 0)
+            return -1;
+        return outlen + 1;
+    }
+    t.type = str->type;
+    t.value.ptr = (char *)str;
+    der_len = i2d_ASN1_TYPE(&t, NULL);
+    der_buf = OPENSSL_malloc(der_len);
+    if (!der_buf)
+        return -1;
+    p = der_buf;
+    i2d_ASN1_TYPE(&t, &p);
+    outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+    OPENSSL_free(der_buf);
+    if (outlen < 0)
+        return -1;
+    return outlen + 1;
 }
 
-/* Lookup table to convert tags to character widths,
- * 0 = UTF8 encoded, -1 is used for non string types
- * otherwise it is the number of bytes per character
+/*
+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
+ * used for non string types otherwise it is the number of bytes per
+ * character
  */
 
 static const signed char tag2nbyte[] = {
-	-1, -1, -1, -1, -1,	/* 0-4 */
-	-1, -1, -1, -1, -1,	/* 5-9 */
-	-1, -1, 0, -1,		/* 10-13 */
-	-1, -1, -1, -1,		/* 15-17 */
-	-1, 1, 1,		/* 18-20 */
-	-1, 1, 1, 1,		/* 21-24 */
-	-1, 1, -1,		/* 25-27 */
-	4, -1, 2		/* 28-30 */
+    -1, -1, -1, -1, -1,         /* 0-4 */
+    -1, -1, -1, -1, -1,         /* 5-9 */
+    -1, -1, 0, -1,              /* 10-13 */
+    -1, -1, -1, -1,             /* 15-17 */
+    -1, 1, 1,                   /* 18-20 */
+    -1, 1, 1, 1,                /* 21-24 */
+    -1, 1, -1,                  /* 25-27 */
+    4, -1, 2                    /* 28-30 */
 };
 
-/* This is the main function, print out an
- * ASN1_STRING taking note of various escape
- * and display options. Returns number of
- * characters written or -1 if an error
- * occurred.
+/*
+ * This is the main function, print out an ASN1_STRING taking note of various
+ * escape and display options. Returns number of characters written or -1 if
+ * an error occurred.
  */
 
-static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+                       ASN1_STRING *str)
 {
-	int outlen, len;
-	int type;
-	char quotes;
-	unsigned char flags;
-	quotes = 0;
-	/* Keep a copy of escape flags */
-	flags = (unsigned char)(lflags & ESC_FLAGS);
+    int outlen, len;
+    int type;
+    char quotes;
+    unsigned char flags;
+    quotes = 0;
+    /* Keep a copy of escape flags */
+    flags = (unsigned char)(lflags & ESC_FLAGS);
 
-	type = str->type;
+    type = str->type;
 
-	outlen = 0;
+    outlen = 0;
 
+    if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+        const char *tagname;
+        tagname = ASN1_tag2str(type);
+        outlen += strlen(tagname);
+        if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+            return -1;
+        outlen++;
+    }
 
-	if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
-		const char *tagname;
-		tagname = ASN1_tag2str(type);
-		outlen += strlen(tagname);
-		if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; 
-		outlen++;
-	}
+    /* Decide what to do with type, either dump content or display it */
 
-	/* Decide what to do with type, either dump content or display it */
+    /* Dump everything */
+    if (lflags & ASN1_STRFLGS_DUMP_ALL)
+        type = -1;
+    /* Ignore the string type */
+    else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+        type = 1;
+    else {
+        /* Else determine width based on type */
+        if ((type > 0) && (type < 31))
+            type = tag2nbyte[type];
+        else
+            type = -1;
+        if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+            type = 1;
+    }
 
-	/* Dump everything */
-	if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
-	/* Ignore the string type */
-	else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
-	else {
-		/* Else determine width based on type */
-		if((type > 0) && (type < 31)) type = tag2nbyte[type];
-		else type = -1;
-		if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
-	}
+    if (type == -1) {
+        len = do_dump(lflags, io_ch, arg, str);
+        if (len < 0)
+            return -1;
+        outlen += len;
+        return outlen;
+    }
 
-	if(type == -1) {
-		len = do_dump(lflags, io_ch, arg, str);
-		if(len < 0) return -1;
-		outlen += len;
-		return outlen;
-	}
+    if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+        /*
+         * Note: if string is UTF8 and we want to convert to UTF8 then we
+         * just interpret it as 1 byte per character to avoid converting
+         * twice.
+         */
+        if (!type)
+            type = 1;
+        else
+            type |= BUF_TYPE_CONVUTF8;
+    }
 
-	if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
-		/* Note: if string is UTF8 and we want
-		 * to convert to UTF8 then we just interpret
-		 * it as 1 byte per character to avoid converting
-		 * twice.
-		 */
-		if(!type) type = 1;
-		else type |= BUF_TYPE_CONVUTF8;
-	}
-
-	len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
-	if(len < 0) return -1;
-	outlen += len;
-	if(quotes) outlen += 2;
-	if(!arg) return outlen;
-	if(quotes && !io_ch(arg, "\"", 1)) return -1;
-	if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
-		return -1;
-	if(quotes && !io_ch(arg, "\"", 1)) return -1;
-	return outlen;
+    len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+    if (len < 0)
+        return -1;
+    outlen += len;
+    if (quotes)
+        outlen += 2;
+    if (!arg)
+        return outlen;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+        return -1;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    return outlen;
 }
 
 /* Used for line indenting: print 'indent' spaces */
 
 static int do_indent(char_io *io_ch, void *arg, int indent)
 {
-	int i;
-	for(i = 0; i < indent; i++)
-			if(!io_ch(arg, " ", 1)) return 0;
-	return 1;
+    int i;
+    for (i = 0; i < indent; i++)
+        if (!io_ch(arg, " ", 1))
+            return 0;
+    return 1;
 }
 
-#define FN_WIDTH_LN	25
-#define FN_WIDTH_SN	10
+#define FN_WIDTH_LN     25
+#define FN_WIDTH_SN     10
 
 static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
-				int indent, unsigned long flags)
+                      int indent, unsigned long flags)
 {
-	int i, prev = -1, orflags, cnt;
-	int fn_opt, fn_nid;
-	ASN1_OBJECT *fn;
-	ASN1_STRING *val;
-	X509_NAME_ENTRY *ent;
-	char objtmp[80];
-	const char *objbuf;
-	int outlen, len;
-	const char *sep_dn, *sep_mv, *sep_eq;
-	int sep_dn_len, sep_mv_len, sep_eq_len;
-	if(indent < 0) indent = 0;
-	outlen = indent;
-	if(!do_indent(io_ch, arg, indent)) return -1;
-	switch (flags & XN_FLAG_SEP_MASK)
-	{
-		case XN_FLAG_SEP_MULTILINE:
-		sep_dn = "\n";
-		sep_dn_len = 1;
-		sep_mv = " + ";
-		sep_mv_len = 3;
-		break;
+    int i, prev = -1, orflags, cnt;
+    int fn_opt, fn_nid;
+    ASN1_OBJECT *fn;
+    ASN1_STRING *val;
+    X509_NAME_ENTRY *ent;
+    char objtmp[80];
+    const char *objbuf;
+    int outlen, len;
+    const char *sep_dn, *sep_mv, *sep_eq;
+    int sep_dn_len, sep_mv_len, sep_eq_len;
+    if (indent < 0)
+        indent = 0;
+    outlen = indent;
+    if (!do_indent(io_ch, arg, indent))
+        return -1;
+    switch (flags & XN_FLAG_SEP_MASK) {
+    case XN_FLAG_SEP_MULTILINE:
+        sep_dn = "\n";
+        sep_dn_len = 1;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        break;
 
-		case XN_FLAG_SEP_COMMA_PLUS:
-		sep_dn = ",";
-		sep_dn_len = 1;
-		sep_mv = "+";
-		sep_mv_len = 1;
-		indent = 0;
-		break;
+    case XN_FLAG_SEP_COMMA_PLUS:
+        sep_dn = ",";
+        sep_dn_len = 1;
+        sep_mv = "+";
+        sep_mv_len = 1;
+        indent = 0;
+        break;
 
-		case XN_FLAG_SEP_CPLUS_SPC:
-		sep_dn = ", ";
-		sep_dn_len = 2;
-		sep_mv = " + ";
-		sep_mv_len = 3;
-		indent = 0;
-		break;
+    case XN_FLAG_SEP_CPLUS_SPC:
+        sep_dn = ", ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
 
-		case XN_FLAG_SEP_SPLUS_SPC:
-		sep_dn = "; ";
-		sep_dn_len = 2;
-		sep_mv = " + ";
-		sep_mv_len = 3;
-		indent = 0;
-		break;
+    case XN_FLAG_SEP_SPLUS_SPC:
+        sep_dn = "; ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
 
-		default:
-		return -1;
-	}
+    default:
+        return -1;
+    }
 
-	if(flags & XN_FLAG_SPC_EQ) {
-		sep_eq = " = ";
-		sep_eq_len = 3;
-	} else {
-		sep_eq = "=";
-		sep_eq_len = 1;
-	}
+    if (flags & XN_FLAG_SPC_EQ) {
+        sep_eq = " = ";
+        sep_eq_len = 3;
+    } else {
+        sep_eq = "=";
+        sep_eq_len = 1;
+    }
 
-	fn_opt = flags & XN_FLAG_FN_MASK;
+    fn_opt = flags & XN_FLAG_FN_MASK;
 
-	cnt = X509_NAME_entry_count(n);	
-	for(i = 0; i < cnt; i++) {
-		if(flags & XN_FLAG_DN_REV)
-				ent = X509_NAME_get_entry(n, cnt - i - 1);
-		else ent = X509_NAME_get_entry(n, i);
-		if(prev != -1) {
-			if(prev == ent->set) {
-				if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
-				outlen += sep_mv_len;
-			} else {
-				if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
-				outlen += sep_dn_len;
-				if(!do_indent(io_ch, arg, indent)) return -1;
-				outlen += indent;
-			}
-		}
-		prev = ent->set;
-		fn = X509_NAME_ENTRY_get_object(ent);
-		val = X509_NAME_ENTRY_get_data(ent);
-		fn_nid = OBJ_obj2nid(fn);
-		if(fn_opt != XN_FLAG_FN_NONE) {
-			int objlen, fld_len;
-			if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
-				OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
-				fld_len = 0; /* XXX: what should this be? */
-				objbuf = objtmp;
-			} else {
-				if(fn_opt == XN_FLAG_FN_SN) {
-					fld_len = FN_WIDTH_SN;
-					objbuf = OBJ_nid2sn(fn_nid);
-				} else if(fn_opt == XN_FLAG_FN_LN) {
-					fld_len = FN_WIDTH_LN;
-					objbuf = OBJ_nid2ln(fn_nid);
-				} else {
-					fld_len = 0; /* XXX: what should this be? */
-					objbuf = "";
-				}
-			}
-			objlen = strlen(objbuf);
-			if(!io_ch(arg, objbuf, objlen)) return -1;
-			if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
-				if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
-				outlen += fld_len - objlen;
-			}
-			if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
-			outlen += objlen + sep_eq_len;
-		}
-		/* If the field name is unknown then fix up the DER dump
-		 * flag. We might want to limit this further so it will
- 		 * DER dump on anything other than a few 'standard' fields.
-		 */
-		if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) 
-					orflags = ASN1_STRFLGS_DUMP_ALL;
-		else orflags = 0;
-     
-		len = do_print_ex(io_ch, arg, flags | orflags, val);
-		if(len < 0) return -1;
-		outlen += len;
-	}
-	return outlen;
+    cnt = X509_NAME_entry_count(n);
+    for (i = 0; i < cnt; i++) {
+        if (flags & XN_FLAG_DN_REV)
+            ent = X509_NAME_get_entry(n, cnt - i - 1);
+        else
+            ent = X509_NAME_get_entry(n, i);
+        if (prev != -1) {
+            if (prev == ent->set) {
+                if (!io_ch(arg, sep_mv, sep_mv_len))
+                    return -1;
+                outlen += sep_mv_len;
+            } else {
+                if (!io_ch(arg, sep_dn, sep_dn_len))
+                    return -1;
+                outlen += sep_dn_len;
+                if (!do_indent(io_ch, arg, indent))
+                    return -1;
+                outlen += indent;
+            }
+        }
+        prev = ent->set;
+        fn = X509_NAME_ENTRY_get_object(ent);
+        val = X509_NAME_ENTRY_get_data(ent);
+        fn_nid = OBJ_obj2nid(fn);
+        if (fn_opt != XN_FLAG_FN_NONE) {
+            int objlen, fld_len;
+            if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
+                OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+                fld_len = 0;    /* XXX: what should this be? */
+                objbuf = objtmp;
+            } else {
+                if (fn_opt == XN_FLAG_FN_SN) {
+                    fld_len = FN_WIDTH_SN;
+                    objbuf = OBJ_nid2sn(fn_nid);
+                } else if (fn_opt == XN_FLAG_FN_LN) {
+                    fld_len = FN_WIDTH_LN;
+                    objbuf = OBJ_nid2ln(fn_nid);
+                } else {
+                    fld_len = 0; /* XXX: what should this be? */
+                    objbuf = "";
+                }
+            }
+            objlen = strlen(objbuf);
+            if (!io_ch(arg, objbuf, objlen))
+                return -1;
+            if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+                if (!do_indent(io_ch, arg, fld_len - objlen))
+                    return -1;
+                outlen += fld_len - objlen;
+            }
+            if (!io_ch(arg, sep_eq, sep_eq_len))
+                return -1;
+            outlen += objlen + sep_eq_len;
+        }
+        /*
+         * If the field name is unknown then fix up the DER dump flag. We
+         * might want to limit this further so it will DER dump on anything
+         * other than a few 'standard' fields.
+         */
+        if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+            orflags = ASN1_STRFLGS_DUMP_ALL;
+        else
+            orflags = 0;
+
+        len = do_print_ex(io_ch, arg, flags | orflags, val);
+        if (len < 0)
+            return -1;
+        outlen += len;
+    }
+    return outlen;
 }
 
 /* Wrappers round the main functions */
 
-int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+                       unsigned long flags)
 {
-	if(flags == XN_FLAG_COMPAT)
-		return X509_NAME_print(out, nm, indent);
-	return do_name_ex(send_bio_chars, out, nm, indent, flags);
+    if (flags == XN_FLAG_COMPAT)
+        return X509_NAME_print(out, nm, indent);
+    return do_name_ex(send_bio_chars, out, nm, indent, flags);
 }
 
 #ifndef OPENSSL_NO_FP_API
-int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+                          unsigned long flags)
 {
-	if(flags == XN_FLAG_COMPAT)
-		{
-		BIO *btmp;
-		int ret;
-		btmp = BIO_new_fp(fp, BIO_NOCLOSE);
-		if(!btmp) return -1;
-		ret = X509_NAME_print(btmp, nm, indent);
-		BIO_free(btmp);
-		return ret;
-		}
-	return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+    if (flags == XN_FLAG_COMPAT) {
+        BIO *btmp;
+        int ret;
+        btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+        if (!btmp)
+            return -1;
+        ret = X509_NAME_print(btmp, nm, indent);
+        BIO_free(btmp);
+        return ret;
+    }
+    return do_name_ex(send_fp_chars, fp, nm, indent, flags);
 }
 #endif
 
 int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
 {
-	return do_print_ex(send_bio_chars, out, flags, str);
+    return do_print_ex(send_bio_chars, out, flags, str);
 }
 
 #ifndef OPENSSL_NO_FP_API
 int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
 {
-	return do_print_ex(send_fp_chars, fp, flags, str);
+    return do_print_ex(send_fp_chars, fp, flags, str);
 }
 #endif
 
-/* Utility function: convert any string type to UTF8, returns number of bytes
+/*
+ * Utility function: convert any string type to UTF8, returns number of bytes
  * in output string or a negative error code
  */
 
 int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
 {
-	ASN1_STRING stmp, *str = &stmp;
-	int mbflag, type, ret;
-	if(!in) return -1;
-	type = in->type;
-	if((type < 0) || (type > 30)) return -1;
-	mbflag = tag2nbyte[type];
-	if(mbflag == -1) return -1;
-	mbflag |= MBSTRING_FLAG;
-	stmp.data = NULL;
-	stmp.length = 0;
-	stmp.flags = 0;
-	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
-	if(ret < 0) return ret;
-	*out = stmp.data;
-	return stmp.length;
+    ASN1_STRING stmp, *str = &stmp;
+    int mbflag, type, ret;
+    if (!in)
+        return -1;
+    type = in->type;
+    if ((type < 0) || (type > 30))
+        return -1;
+    mbflag = tag2nbyte[type];
+    if (mbflag == -1)
+        return -1;
+    mbflag |= MBSTRING_FLAG;
+    stmp.data = NULL;
+    stmp.length = 0;
+    stmp.flags = 0;
+    ret =
+        ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+                           B_ASN1_UTF8STRING);
+    if (ret < 0)
+        return ret;
+    *out = stmp.data;
+    return stmp.length;
 }
diff --git a/src/crypto/x509/a_verify.c b/src/crypto/x509/a_verify.c
index 572a139..5a9adb6 100644
--- a/src/crypto/x509/a_verify.c
+++ b/src/crypto/x509/a_verify.c
@@ -68,66 +68,60 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
-#include "../evp/internal.h"
-
+#include "internal.h"
 
 int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
-		ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
-	{
-	EVP_MD_CTX ctx;
-	uint8_t *buf_in = NULL;
-	int ret = 0, inl;
+                     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+    EVP_MD_CTX ctx;
+    uint8_t *buf_in = NULL;
+    int ret = 0, inl;
 
-	if (!pkey)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
-		return 0;
-		}
+    if (!pkey) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
 
-	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT);
-		return 0;
-		}
+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT);
+        return 0;
+    }
 
-	EVP_MD_CTX_init(&ctx);
+    EVP_MD_CTX_init(&ctx);
 
-	if (!EVP_DigestVerifyInitFromAlgorithm(&ctx, a, pkey))
-		{
-		goto err;
-		}
+    if (!x509_digest_verify_init(&ctx, a, pkey)) {
+        goto err;
+    }
 
-	inl = ASN1_item_i2d(asn, &buf_in, it);
-	
-	if (buf_in == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    inl = ASN1_item_i2d(asn, &buf_in, it);
 
-	if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
-		{
-		OPENSSL_cleanse(buf_in,(unsigned int)inl);
-		OPENSSL_free(buf_in);
-		OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
-		goto err;
-		}
+    if (buf_in == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	OPENSSL_cleanse(buf_in,(unsigned int)inl);
-	OPENSSL_free(buf_in);
+    if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
+        OPENSSL_cleanse(buf_in, (unsigned int)inl);
+        OPENSSL_free(buf_in);
+        OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+        goto err;
+    }
 
-	if (EVP_DigestVerifyFinal(&ctx,signature->data,
-			(size_t)signature->length) <= 0)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
-		goto err;
-		}
-	/* we don't need to zero the 'ctx' because we just checked
-	 * public information */
-	/* memset(&ctx,0,sizeof(ctx)); */
-	ret = 1;
-err:
-	EVP_MD_CTX_cleanup(&ctx);
-	return ret;
-	}
+    OPENSSL_cleanse(buf_in, (unsigned int)inl);
+    OPENSSL_free(buf_in);
 
+    if (EVP_DigestVerifyFinal(&ctx, signature->data,
+                              (size_t)signature->length) <= 0) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+        goto err;
+    }
+    /*
+     * we don't need to zero the 'ctx' because we just checked public
+     * information
+     */
+    /* memset(&ctx,0,sizeof(ctx)); */
+    ret = 1;
+ err:
+    EVP_MD_CTX_cleanup(&ctx);
+    return ret;
+}
diff --git a/src/crypto/evp/algorithm.c b/src/crypto/x509/algorithm.c
similarity index 67%
rename from src/crypto/evp/algorithm.c
rename to src/crypto/x509/algorithm.c
index 63bc77a..78ae882 100644
--- a/src/crypto/evp/algorithm.c
+++ b/src/crypto/x509/algorithm.c
@@ -54,100 +54,84 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
-#include <openssl/evp.h>
-
-#include <assert.h>
+#include <openssl/x509.h>
 
 #include <openssl/asn1.h>
+#include <openssl/digest.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 #include <openssl/obj.h>
-#include <openssl/x509.h>
 
 #include "internal.h"
 
 
-int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
-  const EVP_MD *digest;
-  EVP_PKEY *pkey;
-  int sign_nid, paramtype;
-
-  digest = EVP_MD_CTX_md(ctx);
-  pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
-  if (!digest || !pkey) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED);
+int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
+  const EVP_MD *digest = EVP_MD_CTX_md(ctx);
+  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+  if (digest == NULL || pkey == NULL) {
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
     return 0;
   }
 
-  if (pkey->ameth->digest_sign_algorithm) {
-    switch (pkey->ameth->digest_sign_algorithm(ctx, algor)) {
-      case EVP_DIGEST_SIGN_ALGORITHM_ERROR:
-        return 0;
-      case EVP_DIGEST_SIGN_ALGORITHM_SUCCESS:
-        return 1;
-      case EVP_DIGEST_SIGN_ALGORITHM_DEFAULT:
-        /* Use default behavior. */
-        break;
-      default:
-        assert(0);
+  if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
+    int pad_mode;
+    if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) {
+      return 0;
+    }
+    /* RSA-PSS has special signature algorithm logic. */
+    if (pad_mode == RSA_PKCS1_PSS_PADDING) {
+      return x509_rsa_ctx_to_pss(ctx, algor);
     }
   }
 
   /* Default behavior: look up the OID for the algorithm/hash pair and encode
    * that. */
+  int sign_nid;
   if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
-                              pkey->ameth->pkey_id)) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+                              EVP_PKEY_id(pkey))) {
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
     return 0;
   }
 
-  if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) {
-    paramtype = V_ASN1_NULL;
-  } else {
-    paramtype = V_ASN1_UNDEF;
-  }
-
+  /* RSA signature algorithms include an explicit NULL parameter. Others omit
+   * it. */
+  int paramtype =
+      (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF;
   X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL);
   return 1;
 }
 
-int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
-                                      X509_ALGOR *algor,
-                                      EVP_PKEY *pkey) {
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+                            EVP_PKEY *pkey) {
+  /* Convert the signature OID into digest and public key OIDs. */
+  int sigalg_nid = OBJ_obj2nid(sigalg->algorithm);
   int digest_nid, pkey_nid;
-  const EVP_PKEY_ASN1_METHOD *ameth;
-  const EVP_MD *digest;
-
-  /* Convert signature OID into digest and public key OIDs */
-  if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &digest_nid,
-                           &pkey_nid)) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+  if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) {
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
     return 0;
   }
 
-  /* Check public key OID matches public key type */
-  ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
-  if (ameth == NULL || ameth->pkey_id != pkey->ameth->pkey_id) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+  /* Check the public key OID matches the public key type. */
+  if (pkey_nid != EVP_PKEY_id(pkey)) {
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
     return 0;
   }
 
   /* NID_undef signals that there are custom parameters to set. */
   if (digest_nid == NID_undef) {
-    if (!pkey->ameth || !pkey->ameth->digest_verify_init_from_algorithm) {
-      OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+    if (sigalg_nid != NID_rsassaPss) {
+      OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
       return 0;
     }
-
-    return pkey->ameth->digest_verify_init_from_algorithm(ctx, algor, pkey);
+    return x509_rsa_pss_to_ctx(ctx, sigalg, pkey);
   }
 
   /* Otherwise, initialize with the digest from the OID. */
-  digest = EVP_get_digestbynid(digest_nid);
+  const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
   if (digest == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
     return 0;
   }
 
   return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey);
 }
-
diff --git a/src/crypto/x509/asn1_gen.c b/src/crypto/x509/asn1_gen.c
index 850a816..03a0ab9 100644
--- a/src/crypto/x509/asn1_gen.c
+++ b/src/crypto/x509/asn1_gen.c
@@ -66,808 +66,753 @@
 
 #include "../internal.h"
 
+/*
+ * Although this file is in crypto/x509 for layering purposes, it emits
+ * errors from the ASN.1 module for OpenSSL compatibility.
+ */
 
-/* Although this file is in crypto/x509 for layering purposes, it emits errors
- * from the ASN.1 module for OpenSSL compatibility. */
+#define ASN1_GEN_FLAG           0x10000
+#define ASN1_GEN_FLAG_IMP       (ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP       (ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG       (ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP   (ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP   (ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP   (ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP   (ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT    (ASN1_GEN_FLAG|8)
 
-#define ASN1_GEN_FLAG		0x10000
-#define ASN1_GEN_FLAG_IMP	(ASN1_GEN_FLAG|1)
-#define ASN1_GEN_FLAG_EXP	(ASN1_GEN_FLAG|2)
-#define ASN1_GEN_FLAG_TAG	(ASN1_GEN_FLAG|3)
-#define ASN1_GEN_FLAG_BITWRAP	(ASN1_GEN_FLAG|4)
-#define ASN1_GEN_FLAG_OCTWRAP	(ASN1_GEN_FLAG|5)
-#define ASN1_GEN_FLAG_SEQWRAP	(ASN1_GEN_FLAG|6)
-#define ASN1_GEN_FLAG_SETWRAP	(ASN1_GEN_FLAG|7)
-#define ASN1_GEN_FLAG_FORMAT	(ASN1_GEN_FLAG|8)
+#define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
 
-#define ASN1_GEN_STR(str,val)	{str, sizeof(str) - 1, val}
-
-#define ASN1_FLAG_EXP_MAX	20
+#define ASN1_FLAG_EXP_MAX       20
 
 /* Input formats */
 
 /* ASCII: default */
-#define ASN1_GEN_FORMAT_ASCII	1
+#define ASN1_GEN_FORMAT_ASCII   1
 /* UTF8 */
-#define ASN1_GEN_FORMAT_UTF8	2
+#define ASN1_GEN_FORMAT_UTF8    2
 /* Hex */
-#define ASN1_GEN_FORMAT_HEX	3
+#define ASN1_GEN_FORMAT_HEX     3
 /* List of bits */
-#define ASN1_GEN_FORMAT_BITLIST	4
+#define ASN1_GEN_FORMAT_BITLIST 4
 
+struct tag_name_st {
+    const char *strnam;
+    int len;
+    int tag;
+};
 
-struct tag_name_st
-	{
-	const char *strnam;
-	int len;
-	int tag;
-	};
+typedef struct {
+    int exp_tag;
+    int exp_class;
+    int exp_constructed;
+    int exp_pad;
+    long exp_len;
+} tag_exp_type;
 
-typedef struct
-	{
-	int exp_tag;
-	int exp_class;
-	int exp_constructed;
-	int exp_pad;
-	long exp_len;
-	} tag_exp_type;
-
-typedef struct
-	{
-	int imp_tag;
-	int imp_class;
-	int utype;
-	int format;
-	const char *str;
-	tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
-	int exp_count;
-	} tag_exp_arg;
+typedef struct {
+    int imp_tag;
+    int imp_class;
+    int utype;
+    int format;
+    const char *str;
+    tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+    int exp_count;
+} tag_exp_arg;
 
 static int bitstr_cb(const char *elem, int len, void *bitstr);
 static int asn1_cb(const char *elem, int len, void *bitstr);
-static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
-static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag,
+                         int *pclass);
 static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
 static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
 static int asn1_str2tag(const char *tagstr, int len);
 
 ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
-	{
-	X509V3_CTX cnf;
+{
+    X509V3_CTX cnf;
 
-	if (!nconf)
-		return ASN1_generate_v3(str, NULL);
+    if (!nconf)
+        return ASN1_generate_v3(str, NULL);
 
-	X509V3_set_nconf(&cnf, nconf);
-	return ASN1_generate_v3(str, &cnf);
-	}
+    X509V3_set_nconf(&cnf, nconf);
+    return ASN1_generate_v3(str, &cnf);
+}
 
 ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
-                            OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-	{
-	ASN1_TYPE *ret;
-	tag_exp_arg asn1_tags;
-	tag_exp_type *etmp;
+{
+    ASN1_TYPE *ret;
+    tag_exp_arg asn1_tags;
+    tag_exp_type *etmp;
 
-	int i, len;
+    int i, len;
 
-	unsigned char *orig_der = NULL, *new_der = NULL;
-	const unsigned char *cpy_start;
-	unsigned char *p;
-	const unsigned char *cp;
-	int cpy_len;
-	long hdr_len;
-	int hdr_constructed = 0, hdr_tag, hdr_class;
-	int r;
+    unsigned char *orig_der = NULL, *new_der = NULL;
+    const unsigned char *cpy_start;
+    unsigned char *p;
+    const unsigned char *cp;
+    int cpy_len;
+    long hdr_len = 0;
+    int hdr_constructed = 0, hdr_tag, hdr_class;
+    int r;
 
-	asn1_tags.imp_tag = -1;
-	asn1_tags.imp_class = -1;
-	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
-	asn1_tags.exp_count = 0;
-	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
-		return NULL;
+    asn1_tags.imp_tag = -1;
+    asn1_tags.imp_class = -1;
+    asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+    asn1_tags.exp_count = 0;
+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+        return NULL;
 
-	if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
-		{
-		if (!cnf)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
-			return NULL;
-			}
-		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
-		}
-	else
-		ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
+        || (asn1_tags.utype == V_ASN1_SET)) {
+        if (!cnf) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+            return NULL;
+        }
+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+    } else
+        ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
 
-	if (!ret)
-		return NULL;
+    if (!ret)
+        return NULL;
 
-	/* If no tagging return base type */
-	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
-		return ret;
+    /* If no tagging return base type */
+    if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+        return ret;
 
-	/* Generate the encoding */
-	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
-	ASN1_TYPE_free(ret);
-	ret = NULL;
-	/* Set point to start copying for modified encoding */
-	cpy_start = orig_der;
+    /* Generate the encoding */
+    cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+    ASN1_TYPE_free(ret);
+    ret = NULL;
+    /* Set point to start copying for modified encoding */
+    cpy_start = orig_der;
 
-	/* Do we need IMPLICIT tagging? */
-	if (asn1_tags.imp_tag != -1)
-		{
-		/* If IMPLICIT we will replace the underlying tag */
-		/* Skip existing tag+len */
-		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
-		if (r & 0x80)
-			goto err;
-		/* Update copy length */
-		cpy_len -= cpy_start - orig_der;
-		/* For IMPLICIT tagging the length should match the
-		 * original length and constructed flag should be
-		 * consistent.
-		 */
-		if (r & 0x1)
-			{
-			/* Indefinite length constructed */
-			hdr_constructed = 2;
-			hdr_len = 0;
-			}
-		else
-			/* Just retain constructed flag */
-			hdr_constructed = r & V_ASN1_CONSTRUCTED;
-		/* Work out new length with IMPLICIT tag: ignore constructed
-		 * because it will mess up if indefinite length
-		 */
-		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
-		}
-	else
-		len = cpy_len;
+    /* Do we need IMPLICIT tagging? */
+    if (asn1_tags.imp_tag != -1) {
+        /* If IMPLICIT we will replace the underlying tag */
+        /* Skip existing tag+len */
+        r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
+                            cpy_len);
+        if (r & 0x80)
+            goto err;
+        /* Update copy length */
+        cpy_len -= cpy_start - orig_der;
+        /*
+         * For IMPLICIT tagging the length should match the original length
+         * and constructed flag should be consistent.
+         */
+        if (r & 0x1) {
+            /* Indefinite length constructed */
+            hdr_constructed = 2;
+            hdr_len = 0;
+        } else
+            /* Just retain constructed flag */
+            hdr_constructed = r & V_ASN1_CONSTRUCTED;
+        /*
+         * Work out new length with IMPLICIT tag: ignore constructed because
+         * it will mess up if indefinite length
+         */
+        len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+    } else
+        len = cpy_len;
 
-	/* Work out length in any EXPLICIT, starting from end */
+    /* Work out length in any EXPLICIT, starting from end */
 
-	for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
-		{
-		/* Content length: number of content octets + any padding */
-		len += etmp->exp_pad;
-		etmp->exp_len = len;
-		/* Total object length: length including new header */
-		len = ASN1_object_size(0, len, etmp->exp_tag);
-		}
+    for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+         i < asn1_tags.exp_count; i++, etmp--) {
+        /* Content length: number of content octets + any padding */
+        len += etmp->exp_pad;
+        etmp->exp_len = len;
+        /* Total object length: length including new header */
+        len = ASN1_object_size(0, len, etmp->exp_tag);
+    }
 
-	/* Allocate buffer for new encoding */
+    /* Allocate buffer for new encoding */
 
-	new_der = OPENSSL_malloc(len);
-	if (!new_der)
-		goto err;
+    new_der = OPENSSL_malloc(len);
+    if (!new_der)
+        goto err;
 
-	/* Generate tagged encoding */
+    /* Generate tagged encoding */
 
-	p = new_der;
+    p = new_der;
 
-	/* Output explicit tags first */
+    /* Output explicit tags first */
 
-	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
-		{
-		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
-					etmp->exp_tag, etmp->exp_class);
-		if (etmp->exp_pad)
-			*p++ = 0;
-		}
+    for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+         i++, etmp++) {
+        ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+                        etmp->exp_tag, etmp->exp_class);
+        if (etmp->exp_pad)
+            *p++ = 0;
+    }
 
-	/* If IMPLICIT, output tag */
+    /* If IMPLICIT, output tag */
 
-	if (asn1_tags.imp_tag != -1)
-		{
-		if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 
-		    && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
-		     || asn1_tags.imp_tag == V_ASN1_SET) )
-			hdr_constructed = V_ASN1_CONSTRUCTED;
-		ASN1_put_object(&p, hdr_constructed, hdr_len,
-					asn1_tags.imp_tag, asn1_tags.imp_class);
-		}
+    if (asn1_tags.imp_tag != -1) {
+        if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
+            && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+                || asn1_tags.imp_tag == V_ASN1_SET))
+            hdr_constructed = V_ASN1_CONSTRUCTED;
+        ASN1_put_object(&p, hdr_constructed, hdr_len,
+                        asn1_tags.imp_tag, asn1_tags.imp_class);
+    }
 
-	/* Copy across original encoding */
-	memcpy(p, cpy_start, cpy_len);
+    /* Copy across original encoding */
+    memcpy(p, cpy_start, cpy_len);
 
-	cp = new_der;
+    cp = new_der;
 
-	/* Obtain new ASN1_TYPE structure */
-	ret = d2i_ASN1_TYPE(NULL, &cp, len);
+    /* Obtain new ASN1_TYPE structure */
+    ret = d2i_ASN1_TYPE(NULL, &cp, len);
 
-	err:
-	if (orig_der)
-		OPENSSL_free(orig_der);
-	if (new_der)
-		OPENSSL_free(new_der);
+ err:
+    if (orig_der)
+        OPENSSL_free(orig_der);
+    if (new_der)
+        OPENSSL_free(new_der);
 
-	return ret;
+    return ret;
 
-	}
+}
 
 static int asn1_cb(const char *elem, int len, void *bitstr)
-	{
-	tag_exp_arg *arg = bitstr;
-	int i;
-	int utype;
-	int vlen = 0;
-	const char *p, *vstart = NULL;
+{
+    tag_exp_arg *arg = bitstr;
+    int i;
+    int utype;
+    int vlen = 0;
+    const char *p, *vstart = NULL;
 
-	int tmp_tag, tmp_class;
+    int tmp_tag, tmp_class;
 
-	if (elem == NULL)
-		return 0;
+    if (elem == NULL)
+        return 0;
 
-	for(i = 0, p = elem; i < len; p++, i++)
-		{
-		/* Look for the ':' in name value pairs */
-		if (*p == ':')
-			{
-			vstart = p + 1;
-			vlen = len - (vstart - elem);
-			len = p - elem;
-			break;
-			}
-		}
+    for (i = 0, p = elem; i < len; p++, i++) {
+        /* Look for the ':' in name value pairs */
+        if (*p == ':') {
+            vstart = p + 1;
+            vlen = len - (vstart - elem);
+            len = p - elem;
+            break;
+        }
+    }
 
-	utype = asn1_str2tag(elem, len);
+    utype = asn1_str2tag(elem, len);
 
-	if (utype == -1)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
-		ERR_add_error_data(2, "tag=", elem);
-		return -1;
-		}
+    if (utype == -1) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
+        ERR_add_error_data(2, "tag=", elem);
+        return -1;
+    }
 
-	/* If this is not a modifier mark end of string and exit */
-	if (!(utype & ASN1_GEN_FLAG))
-		{
-		arg->utype = utype;
-		arg->str = vstart;
-		/* If no value and not end of string, error */
-		if (!vstart && elem[len])
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
-			return -1;
-			}
-		return 0;
-		}
+    /* If this is not a modifier mark end of string and exit */
+    if (!(utype & ASN1_GEN_FLAG)) {
+        arg->utype = utype;
+        arg->str = vstart;
+        /* If no value and not end of string, error */
+        if (!vstart && elem[len]) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
+            return -1;
+        }
+        return 0;
+    }
 
-	switch(utype)
-		{
+    switch (utype) {
 
-		case ASN1_GEN_FLAG_IMP:
-		/* Check for illegal multiple IMPLICIT tagging */
-		if (arg->imp_tag != -1)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
-			return -1;
-			}
-		if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
-			return -1;
-		break;
+    case ASN1_GEN_FLAG_IMP:
+        /* Check for illegal multiple IMPLICIT tagging */
+        if (arg->imp_tag != -1) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
+            return -1;
+        }
+        if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_EXP:
+    case ASN1_GEN_FLAG_EXP:
 
-		if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
-			return -1;
-		if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
-			return -1;
-		break;
+        if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+            return -1;
+        if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_SEQWRAP:
-		if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
-			return -1;
-		break;
+    case ASN1_GEN_FLAG_SEQWRAP:
+        if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_SETWRAP:
-		if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
-			return -1;
-		break;
+    case ASN1_GEN_FLAG_SETWRAP:
+        if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_BITWRAP:
-		if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
-			return -1;
-		break;
+    case ASN1_GEN_FLAG_BITWRAP:
+        if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_OCTWRAP:
-		if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
-			return -1;
-		break;
+    case ASN1_GEN_FLAG_OCTWRAP:
+        if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+            return -1;
+        break;
 
-		case ASN1_GEN_FLAG_FORMAT:
-		if (!vstart)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
-			return -1;
-			}
-		if (!strncmp(vstart, "ASCII", 5))
-			arg->format = ASN1_GEN_FORMAT_ASCII;
-		else if (!strncmp(vstart, "UTF8", 4))
-			arg->format = ASN1_GEN_FORMAT_UTF8;
-		else if (!strncmp(vstart, "HEX", 3))
-			arg->format = ASN1_GEN_FORMAT_HEX;
-		else if (!strncmp(vstart, "BITLIST", 7))
-			arg->format = ASN1_GEN_FORMAT_BITLIST;
-		else
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
-			return -1;
-			}
-		break;
+    case ASN1_GEN_FLAG_FORMAT:
+        if (!vstart) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        if (!strncmp(vstart, "ASCII", 5))
+            arg->format = ASN1_GEN_FORMAT_ASCII;
+        else if (!strncmp(vstart, "UTF8", 4))
+            arg->format = ASN1_GEN_FORMAT_UTF8;
+        else if (!strncmp(vstart, "HEX", 3))
+            arg->format = ASN1_GEN_FORMAT_HEX;
+        else if (!strncmp(vstart, "BITLIST", 7))
+            arg->format = ASN1_GEN_FORMAT_BITLIST;
+        else {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        break;
 
-		}
+    }
 
-	return 1;
+    return 1;
 
-	}
+}
 
 static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
-	{
-	char erch[2];
-	long tag_num;
-	char *eptr;
-	if (!vstart)
-		return 0;
-	tag_num = strtoul(vstart, &eptr, 10);
-	/* Check we haven't gone past max length: should be impossible */
-	if (eptr && *eptr && (eptr > vstart + vlen))
-		return 0;
-	if (tag_num < 0)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
-		return 0;
-		}
-	*ptag = tag_num;
-	/* If we have non numeric characters, parse them */
-	if (eptr)
-		vlen -= eptr - vstart;
-	else 
-		vlen = 0;
-	if (vlen)
-		{
-		switch (*eptr)
-			{
+{
+    char erch[2];
+    long tag_num;
+    char *eptr;
+    if (!vstart)
+        return 0;
+    tag_num = strtoul(vstart, &eptr, 10);
+    /* Check we haven't gone past max length: should be impossible */
+    if (eptr && *eptr && (eptr > vstart + vlen))
+        return 0;
+    if (tag_num < 0) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    *ptag = tag_num;
+    /* If we have non numeric characters, parse them */
+    if (eptr)
+        vlen -= eptr - vstart;
+    else
+        vlen = 0;
+    if (vlen) {
+        switch (*eptr) {
 
-			case 'U':
-			*pclass = V_ASN1_UNIVERSAL;
-			break;
+        case 'U':
+            *pclass = V_ASN1_UNIVERSAL;
+            break;
 
-			case 'A':
-			*pclass = V_ASN1_APPLICATION;
-			break;
+        case 'A':
+            *pclass = V_ASN1_APPLICATION;
+            break;
 
-			case 'P':
-			*pclass = V_ASN1_PRIVATE;
-			break;
+        case 'P':
+            *pclass = V_ASN1_PRIVATE;
+            break;
 
-			case 'C':
-			*pclass = V_ASN1_CONTEXT_SPECIFIC;
-			break;
+        case 'C':
+            *pclass = V_ASN1_CONTEXT_SPECIFIC;
+            break;
 
-			default:
-			erch[0] = *eptr;
-			erch[1] = 0;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
-			ERR_add_error_data(2, "Char=", erch);
-			return 0;
-			break;
+        default:
+            erch[0] = *eptr;
+            erch[1] = 0;
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
+            ERR_add_error_data(2, "Char=", erch);
+            return 0;
+            break;
 
-			}
-		}
-	else
-		*pclass = V_ASN1_CONTEXT_SPECIFIC;
+        }
+    } else
+        *pclass = V_ASN1_CONTEXT_SPECIFIC;
 
-	return 1;
+    return 1;
 
-	}
+}
 
 /* Handle multiple types: SET and SEQUENCE */
 
 static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
-	{
-	ASN1_TYPE *ret = NULL;
-	STACK_OF(ASN1_TYPE) *sk = NULL;
-	STACK_OF(CONF_VALUE) *sect = NULL;
-	unsigned char *der = NULL;
-	int derlen;
-	size_t i;
-	sk = sk_ASN1_TYPE_new_null();
-	if (!sk)
-		goto bad;
-	if (section)
-		{
-		if (!cnf)
-			goto bad;
-		sect = X509V3_get_section(cnf, (char *)section);
-		if (!sect)
-			goto bad;
-		for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
-			{
-			ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
-			if (!typ)
-				goto bad;
-			if (!sk_ASN1_TYPE_push(sk, typ))
-				goto bad;
-			}
-		}
+{
+    ASN1_TYPE *ret = NULL;
+    STACK_OF(ASN1_TYPE) *sk = NULL;
+    STACK_OF(CONF_VALUE) *sect = NULL;
+    unsigned char *der = NULL;
+    int derlen;
+    size_t i;
+    sk = sk_ASN1_TYPE_new_null();
+    if (!sk)
+        goto bad;
+    if (section) {
+        if (!cnf)
+            goto bad;
+        sect = X509V3_get_section(cnf, (char *)section);
+        if (!sect)
+            goto bad;
+        for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+            ASN1_TYPE *typ =
+                ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+            if (!typ)
+                goto bad;
+            if (!sk_ASN1_TYPE_push(sk, typ))
+                goto bad;
+        }
+    }
 
-	/* Now we has a STACK of the components, convert to the correct form */
+    /*
+     * Now we has a STACK of the components, convert to the correct form
+     */
 
-	if (utype == V_ASN1_SET)
-		derlen = i2d_ASN1_SET_ANY(sk, &der);
-	else
-		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+    if (utype == V_ASN1_SET)
+        derlen = i2d_ASN1_SET_ANY(sk, &der);
+    else
+        derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
 
-	if (derlen < 0)
-		goto bad;
+    if (derlen < 0)
+        goto bad;
 
-	if (!(ret = ASN1_TYPE_new()))
-		goto bad;
+    if (!(ret = ASN1_TYPE_new()))
+        goto bad;
 
-	if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
-		goto bad;
+    if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+        goto bad;
 
-	ret->type = utype;
+    ret->type = utype;
 
-	ret->value.asn1_string->data = der;
-	ret->value.asn1_string->length = derlen;
+    ret->value.asn1_string->data = der;
+    ret->value.asn1_string->length = derlen;
 
-	der = NULL;
+    der = NULL;
 
-	bad:
+ bad:
 
-	if (der)
-		OPENSSL_free(der);
+    if (der)
+        OPENSSL_free(der);
 
-	if (sk)
-		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
-	if (sect)
-		X509V3_section_free(cnf, sect);
+    if (sk)
+        sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+    if (sect)
+        X509V3_section_free(cnf, sect);
 
-	return ret;
-	}
+    return ret;
+}
 
-static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
-	{
-	tag_exp_type *exp_tmp;
-	/* Can only have IMPLICIT if permitted */
-	if ((arg->imp_tag != -1) && !imp_ok)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
-		return 0;
-		}
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok)
+{
+    tag_exp_type *exp_tmp;
+    /* Can only have IMPLICIT if permitted */
+    if ((arg->imp_tag != -1) && !imp_ok) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+        return 0;
+    }
 
-	if (arg->exp_count == ASN1_FLAG_EXP_MAX)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
-		return 0;
-		}
+    if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
+        return 0;
+    }
 
-	exp_tmp = &arg->exp_list[arg->exp_count++];
+    exp_tmp = &arg->exp_list[arg->exp_count++];
 
-	/* If IMPLICIT set tag to implicit value then
-	 * reset implicit tag since it has been used.
-	 */
-	if (arg->imp_tag != -1)
-		{
-		exp_tmp->exp_tag = arg->imp_tag;
-		exp_tmp->exp_class = arg->imp_class;
-		arg->imp_tag = -1;
-		arg->imp_class = -1;
-		}
-	else
-		{
-		exp_tmp->exp_tag = exp_tag;
-		exp_tmp->exp_class = exp_class;
-		}
-	exp_tmp->exp_constructed = exp_constructed;
-	exp_tmp->exp_pad = exp_pad;
+    /*
+     * If IMPLICIT set tag to implicit value then reset implicit tag since it
+     * has been used.
+     */
+    if (arg->imp_tag != -1) {
+        exp_tmp->exp_tag = arg->imp_tag;
+        exp_tmp->exp_class = arg->imp_class;
+        arg->imp_tag = -1;
+        arg->imp_class = -1;
+    } else {
+        exp_tmp->exp_tag = exp_tag;
+        exp_tmp->exp_class = exp_class;
+    }
+    exp_tmp->exp_constructed = exp_constructed;
+    exp_tmp->exp_pad = exp_pad;
 
-	return 1;
-	}
-
+    return 1;
+}
 
 static int asn1_str2tag(const char *tagstr, int len)
-	{
-	unsigned int i;
-	static const struct tag_name_st *tntmp, tnst [] = {
-		ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
-		ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
-		ASN1_GEN_STR("NULL", V_ASN1_NULL),
-		ASN1_GEN_STR("INT", V_ASN1_INTEGER),
-		ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
-		ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
-		ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
-		ASN1_GEN_STR("OID", V_ASN1_OBJECT),
-		ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
-		ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
-		ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
-		ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
-		ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
-		ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
-		ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
-		ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
-		ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
-		ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
-		ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
-		ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
-		ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
-		ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
-		ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
-		ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
-		ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
-		ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
-		ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
-		ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
-		ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
-		ASN1_GEN_STR("T61", V_ASN1_T61STRING),
-		ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
-		ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
-		ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
-		ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
-		ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
-		ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+{
+    unsigned int i;
+    static const struct tag_name_st *tntmp, tnst[] = {
+        ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("NULL", V_ASN1_NULL),
+        ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+        ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+        ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+        ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+        ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+        ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+        ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
 
-		/* Special cases */
-		ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
-		ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
-		ASN1_GEN_STR("SET", V_ASN1_SET),
-		/* type modifiers */
-		/* Explicit tag */
-		ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
-		ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
-		/* Implicit tag */
-		ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
-		ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
-		/* OCTET STRING wrapper */
-		ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
-		/* SEQUENCE wrapper */
-		ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
-		/* SET wrapper */
-		ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
-		/* BIT STRING wrapper */
-		ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
-		ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
-		ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
-	};
+        /* Special cases */
+        ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SET", V_ASN1_SET),
+        /* type modifiers */
+        /* Explicit tag */
+        ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+        ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+        /* Implicit tag */
+        ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+        ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+        /* OCTET STRING wrapper */
+        ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+        /* SEQUENCE wrapper */
+        ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+        /* SET wrapper */
+        ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+        /* BIT STRING wrapper */
+        ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+        ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+        ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+    };
 
-	if (len == -1)
-		len = strlen(tagstr);
-	
-	tntmp = tnst;	
-	for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
-		{
-		if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
-			return tntmp->tag;
-		}
-	
-	return -1;
-	}
+    if (len == -1)
+        len = strlen(tagstr);
+
+    tntmp = tnst;
+    for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) {
+        if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+            return tntmp->tag;
+    }
+
+    return -1;
+}
 
 static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
-	{
-	ASN1_TYPE *atmp = NULL;
+{
+    ASN1_TYPE *atmp = NULL;
 
-	CONF_VALUE vtmp;
+    CONF_VALUE vtmp;
 
-	unsigned char *rdata;
-	long rdlen;
+    unsigned char *rdata;
+    long rdlen;
 
-	int no_unused = 1;
+    int no_unused = 1;
 
-	if (!(atmp = ASN1_TYPE_new()))
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return NULL;
-		}
+    if (!(atmp = ASN1_TYPE_new())) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
 
-	if (!str)
-		str = "";
+    if (!str)
+        str = "";
 
-	switch(utype)
-		{
+    switch (utype) {
 
-		case V_ASN1_NULL:
-		if (str && *str)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
-			goto bad_form;
-			}
-		break;
-		
-		case V_ASN1_BOOLEAN:
-		if (format != ASN1_GEN_FORMAT_ASCII)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
-			goto bad_form;
-			}
-		vtmp.name = NULL;
-		vtmp.section = NULL;
-		vtmp.value = (char *)str;
-		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
-			goto bad_str;
-			}
-		break;
+    case V_ASN1_NULL:
+        if (str && *str) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
+            goto bad_form;
+        }
+        break;
 
-		case V_ASN1_INTEGER:
-		case V_ASN1_ENUMERATED:
-		if (format != ASN1_GEN_FORMAT_ASCII)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
-			goto bad_form;
-			}
-		if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
-			goto bad_str;
-			}
-		break;
+    case V_ASN1_BOOLEAN:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        vtmp.name = NULL;
+        vtmp.section = NULL;
+        vtmp.value = (char *)str;
+        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
+            goto bad_str;
+        }
+        break;
 
-		case V_ASN1_OBJECT:
-		if (format != ASN1_GEN_FORMAT_ASCII)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
-			goto bad_form;
-			}
-		if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
-			goto bad_str;
-			}
-		break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
+            goto bad_str;
+        }
+        break;
 
-		case V_ASN1_UTCTIME:
-		case V_ASN1_GENERALIZEDTIME:
-		if (format != ASN1_GEN_FORMAT_ASCII)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
-			goto bad_form;
-			}
-		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto bad_str;
-			}
-		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto bad_str;
-			}
-		atmp->value.asn1_string->type = utype;
-		if (!ASN1_TIME_check(atmp->value.asn1_string))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
-			goto bad_str;
-			}
+    case V_ASN1_OBJECT:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
+            goto bad_str;
+        }
+        break;
 
-		break;
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        atmp->value.asn1_string->type = utype;
+        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
+            goto bad_str;
+        }
 
-		case V_ASN1_BMPSTRING:
-		case V_ASN1_PRINTABLESTRING:
-		case V_ASN1_IA5STRING:
-		case V_ASN1_T61STRING:
-		case V_ASN1_UTF8STRING:
-		case V_ASN1_VISIBLESTRING:
-		case V_ASN1_UNIVERSALSTRING:
-		case V_ASN1_GENERALSTRING:
-		case V_ASN1_NUMERICSTRING:
+        break;
 
-		if (format == ASN1_GEN_FORMAT_ASCII)
-			format = MBSTRING_ASC;
-		else if (format == ASN1_GEN_FORMAT_UTF8)
-			format = MBSTRING_UTF8;
-		else
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
-			goto bad_form;
-			}
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_NUMERICSTRING:
 
+        if (format == ASN1_GEN_FORMAT_ASCII)
+            format = MBSTRING_ASC;
+        else if (format == ASN1_GEN_FORMAT_UTF8)
+            format = MBSTRING_UTF8;
+        else {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
+            goto bad_form;
+        }
 
-		if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-						-1, format, ASN1_tag2bit(utype)) <= 0)
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto bad_str;
-			}
-		
+        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+                               -1, format, ASN1_tag2bit(utype)) <= 0) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
 
-		break;
+        break;
 
-		case V_ASN1_BIT_STRING:
+    case V_ASN1_BIT_STRING:
 
-		case V_ASN1_OCTET_STRING:
+    case V_ASN1_OCTET_STRING:
 
-		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
-			{
-			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-			goto bad_form;
-			}
+        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+            OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+            goto bad_form;
+        }
 
-		if (format == ASN1_GEN_FORMAT_HEX)
-			{
+        if (format == ASN1_GEN_FORMAT_HEX) {
 
-			if (!(rdata = string_to_hex((char *)str, &rdlen)))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
-				goto bad_str;
-				}
+            if (!(rdata = string_to_hex((char *)str, &rdlen))) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
+                goto bad_str;
+            }
 
-			atmp->value.asn1_string->data = rdata;
-			atmp->value.asn1_string->length = rdlen;
-			atmp->value.asn1_string->type = utype;
+            atmp->value.asn1_string->data = rdata;
+            atmp->value.asn1_string->length = rdlen;
+            atmp->value.asn1_string->type = utype;
 
-			}
-		else if (format == ASN1_GEN_FORMAT_ASCII)
-			ASN1_STRING_set(atmp->value.asn1_string, str, -1);
-		else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
-			{
-			if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
-				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
-				goto bad_str;
-				}
-			no_unused = 0;
-			
-			}
-		else 
-			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
-			goto bad_form;
-			}
+        } else if (format == ASN1_GEN_FORMAT_ASCII)
+            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+        else if ((format == ASN1_GEN_FORMAT_BITLIST)
+                 && (utype == V_ASN1_BIT_STRING)) {
+            if (!CONF_parse_list
+                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
+                OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
+                goto bad_str;
+            }
+            no_unused = 0;
 
-		if ((utype == V_ASN1_BIT_STRING) && no_unused)
-			{
-			atmp->value.asn1_string->flags
-				&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
-        		atmp->value.asn1_string->flags
-				|= ASN1_STRING_FLAG_BITS_LEFT;
-			}
+        } else {
+            OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+            goto bad_form;
+        }
 
+        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+            atmp->value.asn1_string->flags
+                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        }
 
-		break;
+        break;
 
-		default:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
-		goto bad_str;
-		break;
-		}
+    default:
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
+        goto bad_str;
+        break;
+    }
 
+    atmp->type = utype;
+    return atmp;
 
-	atmp->type = utype;
-	return atmp;
+ bad_str:
+    ERR_add_error_data(2, "string=", str);
+ bad_form:
 
+    ASN1_TYPE_free(atmp);
+    return NULL;
 
-	bad_str:
-	ERR_add_error_data(2, "string=", str);
-	bad_form:
-
-	ASN1_TYPE_free(atmp);
-	return NULL;
-
-	}
+}
 
 static int bitstr_cb(const char *elem, int len, void *bitstr)
-	{
-	long bitnum;
-	char *eptr;
-	if (!elem)
-		return 0;
-	bitnum = strtoul(elem, &eptr, 10);
-	if (eptr && *eptr && (eptr != elem + len))
-		return 0;
-	if (bitnum < 0)
-		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
-		return 0;
-		}
-	if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
-		{
-		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	return 1;
-	}
-
+{
+    long bitnum;
+    char *eptr;
+    if (!elem)
+        return 0;
+    bitnum = strtoul(elem, &eptr, 10);
+    if (eptr && *eptr && (eptr != elem + len))
+        return 0;
+    if (bitnum < 0) {
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index ae50ae1..4f0a49e 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -68,424 +68,386 @@
 
 #include "../internal.h"
 
+typedef struct lookup_dir_hashes_st {
+    unsigned long hash;
+    int suffix;
+} BY_DIR_HASH;
 
-typedef struct lookup_dir_hashes_st
-	{
-	unsigned long hash;
-	int suffix;
-	} BY_DIR_HASH;
+typedef struct lookup_dir_entry_st {
+    char *dir;
+    int dir_type;
+    STACK_OF(BY_DIR_HASH) *hashes;
+} BY_DIR_ENTRY;
 
-typedef struct lookup_dir_entry_st
-	{
-	char *dir;
-	int dir_type;
-	STACK_OF(BY_DIR_HASH) *hashes;
-	} BY_DIR_ENTRY;
-
-typedef struct lookup_dir_st
-	{
-	BUF_MEM *buffer;
-	STACK_OF(BY_DIR_ENTRY) *dirs;
-	} BY_DIR;
+typedef struct lookup_dir_st {
+    BUF_MEM *buffer;
+    STACK_OF(BY_DIR_ENTRY) *dirs;
+} BY_DIR;
 
 DECLARE_STACK_OF(BY_DIR_HASH)
 DECLARE_STACK_OF(BY_DIR_ENTRY)
 
 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
-	char **ret);
+                    char **ret);
 static int new_dir(X509_LOOKUP *lu);
 static void free_dir(X509_LOOKUP *lu);
-static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
-static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
-	X509_OBJECT *ret);
-static X509_LOOKUP_METHOD x509_dir_lookup=
-	{
-	"Load certs from files in a directory",
-	new_dir,		/* new */
-	free_dir,		/* free */
-	NULL, 			/* init */
-	NULL,			/* shutdown */
-	dir_ctrl,		/* ctrl */
-	get_cert_by_subject,	/* get_by_subject */
-	NULL,			/* get_by_issuer_serial */
-	NULL,			/* get_by_fingerprint */
-	NULL,			/* get_by_alias */
-	};
+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
+static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
+                               X509_OBJECT *ret);
+static X509_LOOKUP_METHOD x509_dir_lookup = {
+    "Load certs from files in a directory",
+    new_dir,                    /* new */
+    free_dir,                   /* free */
+    NULL,                       /* init */
+    NULL,                       /* shutdown */
+    dir_ctrl,                   /* ctrl */
+    get_cert_by_subject,        /* get_by_subject */
+    NULL,                       /* get_by_issuer_serial */
+    NULL,                       /* get_by_fingerprint */
+    NULL,                       /* get_by_alias */
+};
 
 X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
-	{
-	return(&x509_dir_lookup);
-	}
+{
+    return (&x509_dir_lookup);
+}
 
 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
-	     char **retp)
-	{
-	int ret=0;
-	BY_DIR *ld;
-	char *dir = NULL;
+                    char **retp)
+{
+    int ret = 0;
+    BY_DIR *ld;
+    char *dir = NULL;
 
-	ld=(BY_DIR *)ctx->method_data;
+    ld = (BY_DIR *)ctx->method_data;
 
-	switch (cmd)
-		{
-	case X509_L_ADD_DIR:
-		if (argl == X509_FILETYPE_DEFAULT)
-			{
-			dir=(char *)getenv(X509_get_default_cert_dir_env());
-			if (dir)
-				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
-			else
-				ret=add_cert_dir(ld,X509_get_default_cert_dir(),
-					X509_FILETYPE_PEM);
-			if (!ret)
-				{
-				OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
-				}
-			}
-		else
-			ret=add_cert_dir(ld,argp,(int)argl);
-		break;
-		}
-	return(ret);
-	}
+    switch (cmd) {
+    case X509_L_ADD_DIR:
+        if (argl == X509_FILETYPE_DEFAULT) {
+            dir = (char *)getenv(X509_get_default_cert_dir_env());
+            if (dir)
+                ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
+            else
+                ret = add_cert_dir(ld, X509_get_default_cert_dir(),
+                                   X509_FILETYPE_PEM);
+            if (!ret) {
+                OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
+            }
+        } else
+            ret = add_cert_dir(ld, argp, (int)argl);
+        break;
+    }
+    return (ret);
+}
 
 static int new_dir(X509_LOOKUP *lu)
-	{
-	BY_DIR *a;
+{
+    BY_DIR *a;
 
-	if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
-		return(0);
-	if ((a->buffer=BUF_MEM_new()) == NULL)
-		{
-		OPENSSL_free(a);
-		return(0);
-		}
-	a->dirs=NULL;
-	lu->method_data=(char *)a;
-	return(1);
-	}
+    if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
+        return (0);
+    if ((a->buffer = BUF_MEM_new()) == NULL) {
+        OPENSSL_free(a);
+        return (0);
+    }
+    a->dirs = NULL;
+    lu->method_data = (char *)a;
+    return (1);
+}
 
 static void by_dir_hash_free(BY_DIR_HASH *hash)
-	{
-	OPENSSL_free(hash);
-	}
+{
+    OPENSSL_free(hash);
+}
 
-static int by_dir_hash_cmp(const BY_DIR_HASH **a,
-			const BY_DIR_HASH **b)
-	{
-	if ((*a)->hash > (*b)->hash)
-		return 1;
-	if ((*a)->hash < (*b)->hash)
-		return -1;
-	return 0;
-	}
+static int by_dir_hash_cmp(const BY_DIR_HASH **a, const BY_DIR_HASH **b)
+{
+    if ((*a)->hash > (*b)->hash)
+        return 1;
+    if ((*a)->hash < (*b)->hash)
+        return -1;
+    return 0;
+}
 
 static void by_dir_entry_free(BY_DIR_ENTRY *ent)
-	{
-	if (ent->dir)
-		OPENSSL_free(ent->dir);
-	if (ent->hashes)
-		sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
-	OPENSSL_free(ent);
-	}
+{
+    if (ent->dir)
+        OPENSSL_free(ent->dir);
+    if (ent->hashes)
+        sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+    OPENSSL_free(ent);
+}
 
 static void free_dir(X509_LOOKUP *lu)
-	{
-	BY_DIR *a;
+{
+    BY_DIR *a;
 
-	a=(BY_DIR *)lu->method_data;
-	if (a->dirs != NULL)
-		sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
-	if (a->buffer != NULL)
-		BUF_MEM_free(a->buffer);
-	OPENSSL_free(a);
-	}
+    a = (BY_DIR *)lu->method_data;
+    if (a->dirs != NULL)
+        sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+    if (a->buffer != NULL)
+        BUF_MEM_free(a->buffer);
+    OPENSSL_free(a);
+}
 
 static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
-	{
-	size_t j,len;
-	const char *s,*ss,*p;
+{
+    size_t j, len;
+    const char *s, *ss, *p;
 
-	if (dir == NULL || !*dir)
-	    {
-	    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
-	    return 0;
-	    }
+    if (dir == NULL || !*dir) {
+        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
+        return 0;
+    }
 
-	s=dir;
-	p=s;
-	do
-		{
-		if ((*p == ':') || (*p == '\0'))
-			{
-			BY_DIR_ENTRY *ent;
-			ss=s;
-			s=p+1;
-			len=p-ss;
-			if (len == 0) continue;
-			for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
-				{
-				ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
-				if (strlen(ent->dir) == len &&
-				    strncmp(ent->dir,ss,len) == 0)
-					break;
-				}
-			if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
-				continue;
-			if (ctx->dirs == NULL)
-				{
-				ctx->dirs = sk_BY_DIR_ENTRY_new_null();
-				if (!ctx->dirs)
-					{
-					OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-					return 0;
-					}
-				}
-			ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
-			if (!ent)
-				return 0;
-			ent->dir_type = type;
-			ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
-			ent->dir = OPENSSL_malloc(len+1);
-			if (!ent->dir || !ent->hashes)
-				{
-				by_dir_entry_free(ent);
-				return 0;
-				}
-			strncpy(ent->dir,ss,len);
-			ent->dir[len] = '\0';
-			if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
-				{
-				by_dir_entry_free(ent);
-				return 0;
-				}
-			}
-		} while (*p++ != '\0');
-	return 1;
-	}
+    s = dir;
+    p = s;
+    do {
+        if ((*p == ':') || (*p == '\0')) {
+            BY_DIR_ENTRY *ent;
+            ss = s;
+            s = p + 1;
+            len = p - ss;
+            if (len == 0)
+                continue;
+            for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
+                ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
+                if (strlen(ent->dir) == len &&
+                    strncmp(ent->dir, ss, len) == 0)
+                    break;
+            }
+            if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
+                continue;
+            if (ctx->dirs == NULL) {
+                ctx->dirs = sk_BY_DIR_ENTRY_new_null();
+                if (!ctx->dirs) {
+                    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+                    return 0;
+                }
+            }
+            ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
+            if (!ent)
+                return 0;
+            ent->dir_type = type;
+            ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
+            ent->dir = OPENSSL_malloc(len + 1);
+            if (!ent->dir || !ent->hashes) {
+                by_dir_entry_free(ent);
+                return 0;
+            }
+            strncpy(ent->dir, ss, len);
+            ent->dir[len] = '\0';
+            if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
+                by_dir_entry_free(ent);
+                return 0;
+            }
+        }
+    } while (*p++ != '\0');
+    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;
+/*
+ * 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)
-	{
-	BY_DIR *ctx;
-	union	{
-		struct	{
-			X509 st_x509;
-			X509_CINF st_x509_cinf;
-			} x509;
-		struct	{
-			X509_CRL st_crl;
-			X509_CRL_INFO st_crl_info;
-			} crl;
-		} data;
-	int ok=0;
-	size_t i;
-	int j,k;
-	unsigned long h;
-	unsigned long hash_array[2];
-	int hash_index;
-	BUF_MEM *b=NULL;
-	X509_OBJECT stmp,*tmp;
-	const char *postfix="";
+                               X509_OBJECT *ret)
+{
+    BY_DIR *ctx;
+    union {
+        struct {
+            X509 st_x509;
+            X509_CINF st_x509_cinf;
+        } x509;
+        struct {
+            X509_CRL st_crl;
+            X509_CRL_INFO st_crl_info;
+        } crl;
+    } data;
+    int ok = 0;
+    size_t i;
+    int j, k;
+    unsigned long h;
+    unsigned long hash_array[2];
+    int hash_index;
+    BUF_MEM *b = NULL;
+    X509_OBJECT stmp, *tmp;
+    const char *postfix = "";
 
-	if (name == NULL) return(0);
+    if (name == NULL)
+        return (0);
 
-	stmp.type=type;
-	if (type == X509_LU_X509)
-		{
-		data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
-		data.x509.st_x509_cinf.subject=name;
-		stmp.data.x509= &data.x509.st_x509;
-		postfix="";
-		}
-	else if (type == X509_LU_CRL)
-		{
-		data.crl.st_crl.crl= &data.crl.st_crl_info;
-		data.crl.st_crl_info.issuer=name;
-		stmp.data.crl= &data.crl.st_crl;
-		postfix="r";
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
-		goto finish;
-		}
+    stmp.type = type;
+    if (type == X509_LU_X509) {
+        data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
+        data.x509.st_x509_cinf.subject = name;
+        stmp.data.x509 = &data.x509.st_x509;
+        postfix = "";
+    } else if (type == X509_LU_CRL) {
+        data.crl.st_crl.crl = &data.crl.st_crl_info;
+        data.crl.st_crl_info.issuer = name;
+        stmp.data.crl = &data.crl.st_crl;
+        postfix = "r";
+    } else {
+        OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
+        goto finish;
+    }
 
-	if ((b=BUF_MEM_new()) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
-		goto finish;
-		}
-	
-	ctx=(BY_DIR *)xl->method_data;
+    if ((b = BUF_MEM_new()) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+        goto finish;
+    }
 
-	hash_array[0]=X509_NAME_hash(name);
-	hash_array[1]=X509_NAME_hash_old(name);
-	for (hash_index=0; hash_index < 2; ++hash_index)
-		{
-		h=hash_array[hash_index];
-		for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
-			{
-			BY_DIR_ENTRY *ent;
-			size_t idx;
-			BY_DIR_HASH htmp, *hent;
-			ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
-			j=strlen(ent->dir)+1+8+6+1+1;
-			if (!BUF_MEM_grow(b,j))
-				{
-				OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-				goto finish;
-				}
-			if (type == X509_LU_CRL && ent->hashes)
-				{
-				htmp.hash = h;
-				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);
-					k = hent->suffix;
-					}
-				else
-					{
-					hent = NULL;
-					k=0;
-					}
-				CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
-				}
-			else
-				{
-				k = 0;
-				hent = NULL;
-				}
-			for (;;)
-				{
-				char c = '/';
+    ctx = (BY_DIR *)xl->method_data;
+
+    hash_array[0] = X509_NAME_hash(name);
+    hash_array[1] = X509_NAME_hash_old(name);
+    for (hash_index = 0; hash_index < 2; ++hash_index) {
+        h = hash_array[hash_index];
+        for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
+            BY_DIR_ENTRY *ent;
+            size_t idx;
+            BY_DIR_HASH htmp, *hent;
+            ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
+            j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
+            if (!BUF_MEM_grow(b, j)) {
+                OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+                goto finish;
+            }
+            if (type == X509_LU_CRL && ent->hashes) {
+                htmp.hash = h;
+                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);
+                    k = hent->suffix;
+                } else {
+                    hent = NULL;
+                    k = 0;
+                }
+                CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+            } else {
+                k = 0;
+                hent = NULL;
+            }
+            for (;;) {
+                char c = '/';
 #ifdef OPENSSL_SYS_VMS
-				c = ent->dir[strlen(ent->dir)-1];
-				if (c != ':' && c != '>' && c != ']')
-					{
-					/* If no separator is present, we assume the
-					   directory specifier is a logical name, and
-					   add a colon.  We really should use better
-					   VMS routines for merging things like this,
-					   but this will do for now...
-					   -- Richard Levitte */
-					c = ':';
-					}
-				else
-					{
-					c = '\0';
-					}
+                c = ent->dir[strlen(ent->dir) - 1];
+                if (c != ':' && c != '>' && c != ']') {
+                    /*
+                     * If no separator is present, we assume the directory
+                     * specifier is a logical name, and add a colon.  We
+                     * really should use better VMS routines for merging
+                     * things like this, but this will do for now... --
+                     * Richard Levitte
+                     */
+                    c = ':';
+                } else {
+                    c = '\0';
+                }
 #endif
-				if (c == '\0')
-					{
-					/* This is special.  When c == '\0', no
-					   directory separator should be added. */
-					BIO_snprintf(b->data,b->max,
-						"%s%08lx.%s%d",ent->dir,h,
-						postfix,k);
-					}
-				else
-					{
-					BIO_snprintf(b->data,b->max,
-						"%s%c%08lx.%s%d",ent->dir,c,h,
-						postfix,k);
-					}
+                if (c == '\0') {
+                    /*
+                     * This is special.  When c == '\0', no directory
+                     * separator should be added.
+                     */
+                    BIO_snprintf(b->data, b->max,
+                                 "%s%08lx.%s%d", ent->dir, h, postfix, k);
+                } else {
+                    BIO_snprintf(b->data, b->max,
+                                 "%s%c%08lx.%s%d", ent->dir, c, h,
+                                 postfix, k);
+                }
 #ifndef OPENSSL_NO_POSIX_IO
-#ifdef _WIN32
-#define stat _stat
+# ifdef _WIN32
+#  define stat _stat
+# endif
+                {
+                    struct stat st;
+                    if (stat(b->data, &st) < 0)
+                        break;
+                }
 #endif
-				{
-				struct stat st;
-				if (stat(b->data,&st) < 0)
-					break;
-				}
-#endif
-				/* found one. */
-				if (type == X509_LU_X509)
-					{
-					if ((X509_load_cert_file(xl,b->data,
-						ent->dir_type)) == 0)
-						break;
-					}
-				else if (type == X509_LU_CRL)
-					{
-					if ((X509_load_crl_file(xl,b->data,
-						ent->dir_type)) == 0)
-						break;
-					}
-				/* else case will caught higher up */
-				k++;
-				}
+                /* found one. */
+                if (type == X509_LU_X509) {
+                    if ((X509_load_cert_file(xl, b->data,
+                                             ent->dir_type)) == 0)
+                        break;
+                } else if (type == X509_LU_CRL) {
+                    if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
+                        break;
+                }
+                /* else case will caught higher up */
+                k++;
+            }
 
-			/* we have added it to the cache so now pull
-			 * it out again */
-			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_MUTEX_unlock(&xl->store_ctx->objs_lock);
+            /*
+             * we have added it to the cache so now pull it out again
+             */
+            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_MUTEX_unlock(&xl->store_ctx->objs_lock);
 
+            /*
+             * If a CRL, update the last file suffix added for this
+             */
 
-			/* If a CRL, update the last file suffix added for this */
+            if (type == X509_LU_CRL) {
+                CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
+                /*
+                 * Look for entry again in case another thread added an entry
+                 * first.
+                 */
+                if (!hent) {
+                    htmp.hash = h;
+                    if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
+                        hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+                }
+                if (!hent) {
+                    hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+                    if (hent == NULL) {
+                        CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+                        ok = 0;
+                        goto finish;
+                    }
+                    hent->hash = h;
+                    hent->suffix = k;
+                    if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
+                        CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+                        OPENSSL_free(hent);
+                        ok = 0;
+                        goto finish;
+                    }
+                } else if (hent->suffix < k)
+                    hent->suffix = k;
 
-			if (type == X509_LU_CRL)
-				{
-				CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
-				/* Look for entry again in case another thread added
-				 * an entry first.
-				 */
-				if (!hent)
-					{
-					htmp.hash = h;
-					if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
-						hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
-					}
-				if (!hent)
-					{
-					hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
-					if (hent == NULL)
-						{
-						CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
-						ok = 0;
-						goto finish;
-						}
-					hent->hash = h;
-					hent->suffix = k;
-					if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
-						{
-						CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
-						OPENSSL_free(hent);
-						ok = 0;
-						goto finish;
-						}
-					}
-				else if (hent->suffix < k)
-					hent->suffix = k;
+                CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+            }
 
-				CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
-				}
-
-			if (tmp != NULL)
-				{
-				ok=1;
-				ret->type=tmp->type;
-				memcpy(&ret->data,&tmp->data,sizeof(ret->data));
-				/* If we were going to up the reference count,
-				 * we would need to do it on a perl 'type'
-				 * basis */
-		/*		CRYPTO_add(&tmp->data.x509->references,1,
-					CRYPTO_LOCK_X509);*/
-				goto finish;
-				}
-			}
-		}
-finish:
-	if (b != NULL) BUF_MEM_free(b);
-	return(ok);
-	}
+            if (tmp != NULL) {
+                ok = 1;
+                ret->type = tmp->type;
+                memcpy(&ret->data, &tmp->data, sizeof(ret->data));
+                /*
+                 * If we were going to up the reference count, we would need
+                 * to do it on a perl 'type' basis
+                 */
+                /*
+                 * CRYPTO_add(&tmp->data.x509->references,1,
+                 * CRYPTO_LOCK_X509);
+                 */
+                goto finish;
+            }
+        }
+    }
+ finish:
+    if (b != NULL)
+        BUF_MEM_free(b);
+    return (ok);
+}
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index 3460b57..ebeb72e 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -63,233 +63,213 @@
 #include <openssl/pem.h>
 #include <openssl/thread.h>
 
-
 #ifndef OPENSSL_NO_STDIO
 
 static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
-	long argl, char **ret);
-static X509_LOOKUP_METHOD x509_file_lookup=
-	{
-	"Load file into cache",
-	NULL,		/* new */
-	NULL,		/* free */
-	NULL, 		/* init */
-	NULL,		/* shutdown */
-	by_file_ctrl,	/* ctrl */
-	NULL,		/* get_by_subject */
-	NULL,		/* get_by_issuer_serial */
-	NULL,		/* get_by_fingerprint */
-	NULL,		/* get_by_alias */
-	};
+                        long argl, char **ret);
+static X509_LOOKUP_METHOD x509_file_lookup = {
+    "Load file into cache",
+    NULL,                       /* new */
+    NULL,                       /* free */
+    NULL,                       /* init */
+    NULL,                       /* shutdown */
+    by_file_ctrl,               /* ctrl */
+    NULL,                       /* get_by_subject */
+    NULL,                       /* get_by_issuer_serial */
+    NULL,                       /* get_by_fingerprint */
+    NULL,                       /* get_by_alias */
+};
 
 X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
-	{
-	return(&x509_file_lookup);
-	}
+{
+    return (&x509_file_lookup);
+}
 
-static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
-	     char **ret)
-	{
-	int ok=0;
-	char *file;
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
+                        long argl, char **ret)
+{
+    int ok = 0;
+    char *file;
 
-	switch (cmd)
-		{
-	case X509_L_FILE_LOAD:
-		if (argl == X509_FILETYPE_DEFAULT)
-			{
-			file = (char *)getenv(X509_get_default_cert_file_env());
-			if (file)
-				ok = (X509_load_cert_crl_file(ctx,file,
-					      X509_FILETYPE_PEM) != 0);
+    switch (cmd) {
+    case X509_L_FILE_LOAD:
+        if (argl == X509_FILETYPE_DEFAULT) {
+            file = (char *)getenv(X509_get_default_cert_file_env());
+            if (file)
+                ok = (X509_load_cert_crl_file(ctx, file,
+                                              X509_FILETYPE_PEM) != 0);
 
-			else
-				ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(),
-					      X509_FILETYPE_PEM) != 0);
+            else
+                ok = (X509_load_cert_crl_file
+                      (ctx, X509_get_default_cert_file(),
+                       X509_FILETYPE_PEM) != 0);
 
-			if (!ok)
-				{
-				OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
-				}
-			}
-		else
-			{
-			if(argl == X509_FILETYPE_PEM)
-				ok = (X509_load_cert_crl_file(ctx,argp,
-					X509_FILETYPE_PEM) != 0);
-			else
-				ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0);
-			}
-		break;
-		}
-	return(ok);
-	}
+            if (!ok) {
+                OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
+            }
+        } else {
+            if (argl == X509_FILETYPE_PEM)
+                ok = (X509_load_cert_crl_file(ctx, argp,
+                                              X509_FILETYPE_PEM) != 0);
+            else
+                ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0);
+        }
+        break;
+    }
+    return (ok);
+}
 
 int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
-	{
-	int ret=0;
-	BIO *in=NULL;
-	int i,count=0;
-	X509 *x=NULL;
+{
+    int ret = 0;
+    BIO *in = NULL;
+    int i, count = 0;
+    X509 *x = NULL;
 
-	if (file == NULL) return(1);
-	in=BIO_new(BIO_s_file());
+    if (file == NULL)
+        return (1);
+    in = BIO_new(BIO_s_file());
 
-	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
-		goto err;
-		}
+    if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
+        goto err;
+    }
 
-	if (type == X509_FILETYPE_PEM)
-		{
-		for (;;)
-			{
-			x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL);
-			if (x == NULL)
-				{
-				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
-					PEM_R_NO_START_LINE) && (count > 0))
-					{
-					ERR_clear_error();
-					break;
-					}
-				else
-					{
-					OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
-					goto err;
-					}
-				}
-			i=X509_STORE_add_cert(ctx->store_ctx,x);
-			if (!i) goto err;
-			count++;
-			X509_free(x);
-			x=NULL;
-			}
-		ret=count;
-		}
-	else if (type == X509_FILETYPE_ASN1)
-		{
-		x=d2i_X509_bio(in,NULL);
-		if (x == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
-			goto err;
-			}
-		i=X509_STORE_add_cert(ctx->store_ctx,x);
-		if (!i) goto err;
-		ret=i;
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
-		goto err;
-		}
-err:
-	if (x != NULL) X509_free(x);
-	if (in != NULL) BIO_free(in);
-	return(ret);
-	}
+    if (type == X509_FILETYPE_PEM) {
+        for (;;) {
+            x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
+            if (x == NULL) {
+                if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+                     PEM_R_NO_START_LINE) && (count > 0)) {
+                    ERR_clear_error();
+                    break;
+                } else {
+                    OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
+                    goto err;
+                }
+            }
+            i = X509_STORE_add_cert(ctx->store_ctx, x);
+            if (!i)
+                goto err;
+            count++;
+            X509_free(x);
+            x = NULL;
+        }
+        ret = count;
+    } else if (type == X509_FILETYPE_ASN1) {
+        x = d2i_X509_bio(in, NULL);
+        if (x == NULL) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        i = X509_STORE_add_cert(ctx->store_ctx, x);
+        if (!i)
+            goto err;
+        ret = i;
+    } else {
+        OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
+        goto err;
+    }
+ err:
+    if (x != NULL)
+        X509_free(x);
+    if (in != NULL)
+        BIO_free(in);
+    return (ret);
+}
 
 int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
-	{
-	int ret=0;
-	BIO *in=NULL;
-	int i,count=0;
-	X509_CRL *x=NULL;
+{
+    int ret = 0;
+    BIO *in = NULL;
+    int i, count = 0;
+    X509_CRL *x = NULL;
 
-	if (file == NULL) return(1);
-	in=BIO_new(BIO_s_file());
+    if (file == NULL)
+        return (1);
+    in = BIO_new(BIO_s_file());
 
-	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
-		goto err;
-		}
+    if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
+        goto err;
+    }
 
-	if (type == X509_FILETYPE_PEM)
-		{
-		for (;;)
-			{
-			x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
-			if (x == NULL)
-				{
-				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
-					PEM_R_NO_START_LINE) && (count > 0))
-					{
-					ERR_clear_error();
-					break;
-					}
-				else
-					{
-					OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
-					goto err;
-					}
-				}
-			i=X509_STORE_add_crl(ctx->store_ctx,x);
-			if (!i) goto err;
-			count++;
-			X509_CRL_free(x);
-			x=NULL;
-			}
-		ret=count;
-		}
-	else if (type == X509_FILETYPE_ASN1)
-		{
-		x=d2i_X509_CRL_bio(in,NULL);
-		if (x == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
-			goto err;
-			}
-		i=X509_STORE_add_crl(ctx->store_ctx,x);
-		if (!i) goto err;
-		ret=i;
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
-		goto err;
-		}
-err:
-	if (x != NULL) X509_CRL_free(x);
-	if (in != NULL) BIO_free(in);
-	return(ret);
-	}
+    if (type == X509_FILETYPE_PEM) {
+        for (;;) {
+            x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+            if (x == NULL) {
+                if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+                     PEM_R_NO_START_LINE) && (count > 0)) {
+                    ERR_clear_error();
+                    break;
+                } else {
+                    OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
+                    goto err;
+                }
+            }
+            i = X509_STORE_add_crl(ctx->store_ctx, x);
+            if (!i)
+                goto err;
+            count++;
+            X509_CRL_free(x);
+            x = NULL;
+        }
+        ret = count;
+    } else if (type == X509_FILETYPE_ASN1) {
+        x = d2i_X509_CRL_bio(in, NULL);
+        if (x == NULL) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        i = X509_STORE_add_crl(ctx->store_ctx, x);
+        if (!i)
+            goto err;
+        ret = i;
+    } else {
+        OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
+        goto err;
+    }
+ err:
+    if (x != NULL)
+        X509_CRL_free(x);
+    if (in != NULL)
+        BIO_free(in);
+    return (ret);
+}
 
 int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
 {
-	STACK_OF(X509_INFO) *inf;
-	X509_INFO *itmp;
-	BIO *in;
-	size_t i;
-	int count = 0;
-	if(type != X509_FILETYPE_PEM)
-		return X509_load_cert_file(ctx, file, type);
-	in = BIO_new_file(file, "r");
-	if(!in) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
-		return 0;
-	}
-	inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
-	BIO_free(in);
-	if(!inf) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
-		return 0;
-	}
-	for(i = 0; i < sk_X509_INFO_num(inf); i++) {
-		itmp = sk_X509_INFO_value(inf, i);
-		if(itmp->x509) {
-			X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
-			count++;
-		}
-		if(itmp->crl) {
-			X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
-			count++;
-		}
-	}
-	sk_X509_INFO_pop_free(inf, X509_INFO_free);
-	return count;
+    STACK_OF(X509_INFO) *inf;
+    X509_INFO *itmp;
+    BIO *in;
+    size_t i;
+    int count = 0;
+    if (type != X509_FILETYPE_PEM)
+        return X509_load_cert_file(ctx, file, type);
+    in = BIO_new_file(file, "r");
+    if (!in) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
+        return 0;
+    }
+    inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+    BIO_free(in);
+    if (!inf) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
+        return 0;
+    }
+    for (i = 0; i < sk_X509_INFO_num(inf); i++) {
+        itmp = sk_X509_INFO_value(inf, i);
+        if (itmp->x509) {
+            X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
+            count++;
+        }
+        if (itmp->crl) {
+            X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
+            count++;
+        }
+    }
+    sk_X509_INFO_pop_free(inf, X509_INFO_free);
+    return count;
 }
 
-#endif /* OPENSSL_NO_STDIO */
+#endif                          /* OPENSSL_NO_STDIO */
diff --git a/src/crypto/x509/charmap.h b/src/crypto/x509/charmap.h
index b55e638..3305ad1 100644
--- a/src/crypto/x509/charmap.h
+++ b/src/crypto/x509/charmap.h
@@ -1,15 +1,15 @@
-/* Auto generated with chartype.pl script.
- * Mask of various character properties
+/*
+ * Auto generated with chartype.pl script. Mask of various character
+ * properties
  */
 
 static const unsigned char char_type[] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
 };
-
diff --git a/src/crypto/x509/i2d_pr.c b/src/crypto/x509/i2d_pr.c
index e7f4269..c3fb8a8 100644
--- a/src/crypto/x509/i2d_pr.c
+++ b/src/crypto/x509/i2d_pr.c
@@ -55,30 +55,29 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
-#include <openssl/x509.h>
-
 #include <openssl/asn1.h>
+#include <openssl/ec_key.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
-
-#include "../evp/internal.h"
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
 
 
-int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
-	{
-	if (a->ameth && a->ameth->old_priv_encode)
-		{
-		return a->ameth->old_priv_encode(a, pp);
-		}
-	if (a->ameth && a->ameth->priv_encode) {
-		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8((EVP_PKEY*)a);
-		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
-		PKCS8_PRIV_KEY_INFO_free(p8);
-		return ret;
-	}
-	/* Although this file is in crypto/x509 for layering reasons, it emits
-	 * an error code from ASN1 for OpenSSL compatibility. */
-	OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
-	return -1;
-	}
-
+int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp)
+{
+    switch (EVP_PKEY_id(a)) {
+    case EVP_PKEY_RSA:
+        return i2d_RSAPrivateKey(a->pkey.rsa, pp);
+    case EVP_PKEY_EC:
+        return i2d_ECPrivateKey(a->pkey.ec, pp);
+    case EVP_PKEY_DSA:
+        return i2d_DSAPrivateKey(a->pkey.dsa, pp);
+    default:
+        /*
+         * Although this file is in crypto/x509 for layering reasons, it emits
+         * an error code from ASN1 for OpenSSL compatibility.
+         */
+        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+        return -1;
+    }
+}
diff --git a/src/crypto/x509/internal.h b/src/crypto/x509/internal.h
new file mode 100644
index 0000000..4957c1e
--- /dev/null
+++ b/src/crypto/x509/internal.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_X509_INTERNAL_H
+#define OPENSSL_HEADER_X509_INTERNAL_H
+
+#include <openssl/base.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* RSA-PSS functions. */
+
+/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on
+ * signature algorithm parameters in |sigalg| (which must have type
+ * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on
+ * error. */
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey);
+
+/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for
+ * |ctx|, which must have been configured for an RSA-PSS signing operation. It
+ * returns one on success and zero on error. */
+int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor);
+
+/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS
+ * parameters in |sigalg| to |bp|. It returns one on success and zero on
+ * error. */
+int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
+                              ASN1_PCTX *pctx);
+
+
+/* Signature algorithm functions. */
+
+/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an
+ * AlgorithmIdentifer and saves the result in |algor|. It returns one on
+ * success, or zero on error. */
+int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor);
+
+/* x509_digest_verify_init sets up |ctx| for a signature verification operation
+ * with public key |pkey| and parameters from |algor|. The |ctx| argument must
+ * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or
+ * zero on error. */
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+                            EVP_PKEY *pkey);
+
+
+#if defined(__cplusplus)
+}  /* extern C */
+#endif
+
+#endif  /* OPENSSL_HEADER_X509_INTERNAL_H */
diff --git a/src/crypto/x509/pkcs7_test.c b/src/crypto/x509/pkcs7_test.c
index 38beb3e..2dfeb5e 100644
--- a/src/crypto/x509/pkcs7_test.c
+++ b/src/crypto/x509/pkcs7_test.c
@@ -22,6 +22,8 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
+#include "../test/test_util.h"
+
 
 /* kPKCS7NSS contains the certificate chain of mail.google.com, as saved by NSS
  * using the Chrome UI. */
@@ -504,7 +506,7 @@
     X509 *b = sk_X509_value(certs2, i);
 
     if (X509_cmp(a, b) != 0) {
-      fprintf(stderr, "Certificate %u differs.\n", (unsigned) i);
+      fprintf(stderr, "Certificate %" OPENSSL_PR_SIZE_T " differs.\n", i);
       return 0;
     }
   }
@@ -568,7 +570,7 @@
     X509_CRL *b = sk_X509_CRL_value(crls2, i);
 
     if (X509_CRL_cmp(a, b) != 0) {
-      fprintf(stderr, "CRL %u differs.\n", (unsigned) i);
+      fprintf(stderr, "CRL %" OPENSSL_PR_SIZE_T " differs.\n", i);
       return 0;
     }
   }
@@ -596,7 +598,7 @@
 }
 
 static int test_pem_certs(const char *pem) {
-  BIO *bio = BIO_new_mem_buf((char *) pem, strlen(pem));
+  BIO *bio = BIO_new_mem_buf(pem, strlen(pem));
   STACK_OF(X509) *certs = sk_X509_new_null();
 
   if (!PKCS7_get_PEM_certificates(certs, bio)) {
@@ -606,8 +608,9 @@
 
   if (sk_X509_num(certs) != 1) {
     fprintf(stderr,
-            "Bad number of certificates from PKCS7_get_PEM_certificates: %u\n",
-            (unsigned)sk_X509_num(certs));
+            "Bad number of certificates from PKCS7_get_PEM_certificates: "
+            "%" OPENSSL_PR_SIZE_T "\n",
+            sk_X509_num(certs));
     return 0;
   }
 
@@ -618,7 +621,7 @@
 }
 
 static int test_pem_crls(const char *pem) {
-  BIO *bio = BIO_new_mem_buf((char *) pem, strlen(pem));
+  BIO *bio = BIO_new_mem_buf(pem, strlen(pem));
   STACK_OF(X509_CRL) *crls = sk_X509_CRL_new_null();
 
   if (!PKCS7_get_PEM_CRLs(crls, bio)) {
@@ -628,8 +631,9 @@
 
   if (sk_X509_CRL_num(crls) != 1) {
     fprintf(stderr,
-            "Bad number of CRLs from PKCS7_get_PEM_CRLs: %u\n",
-            (unsigned)sk_X509_CRL_num(crls));
+            "Bad number of CRLs from PKCS7_get_PEM_CRLs: %" OPENSSL_PR_SIZE_T
+            "\n",
+            sk_X509_CRL_num(crls));
     return 0;
   }
 
@@ -653,4 +657,3 @@
   printf("PASS\n");
   return 0;
 }
-
diff --git a/src/crypto/x509/rsa_pss.c b/src/crypto/x509/rsa_pss.c
new file mode 100644
index 0000000..1ae01a3
--- /dev/null
+++ b/src/crypto/x509/rsa_pss.c
@@ -0,0 +1,385 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/x509.h>
+
+#include <assert.h>
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/obj.h>
+
+#include "internal.h"
+
+
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+  ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+  ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+  ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+  ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3),
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS);
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
+
+
+/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
+static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
+  if (alg == NULL || alg->parameter == NULL ||
+      OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
+      alg->parameter->type != V_ASN1_SEQUENCE) {
+    return NULL;
+  }
+
+  const uint8_t *p = alg->parameter->value.sequence->data;
+  int plen = alg->parameter->value.sequence->length;
+  return d2i_X509_ALGOR(NULL, &p, plen);
+}
+
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+                                      X509_ALGOR **pmaskHash) {
+  *pmaskHash = NULL;
+
+  if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) {
+    return NULL;
+  }
+
+  const uint8_t *p = alg->parameter->value.sequence->data;
+  int plen = alg->parameter->value.sequence->length;
+  RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+  if (pss == NULL) {
+    return NULL;
+  }
+
+  *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+  return pss;
+}
+
+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
+static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) {
+  if (EVP_MD_type(md) == NID_sha1) {
+    return 1;
+  }
+  *palg = X509_ALGOR_new();
+  if (*palg == NULL) {
+    return 0;
+  }
+  X509_ALGOR_set_md(*palg, md);
+  return 1;
+}
+
+/* Allocate and set MGF1 algorithm ID from EVP_MD */
+static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
+  X509_ALGOR *algtmp = NULL;
+  ASN1_STRING *stmp = NULL;
+  *palg = NULL;
+
+  if (EVP_MD_type(mgf1md) == NID_sha1) {
+    return 1;
+  }
+  /* need to embed algorithm ID inside another */
+  if (!rsa_md_to_algor(&algtmp, mgf1md) ||
+      !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) {
+    goto err;
+  }
+  *palg = X509_ALGOR_new();
+  if (!*palg) {
+    goto err;
+  }
+  X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+  stmp = NULL;
+
+err:
+  ASN1_STRING_free(stmp);
+  X509_ALGOR_free(algtmp);
+  if (*palg) {
+    return 1;
+  }
+
+  return 0;
+}
+
+/* convert algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
+  const EVP_MD *md;
+  if (!alg) {
+    return EVP_sha1();
+  }
+  md = EVP_get_digestbyobj(alg->algorithm);
+  if (md == NULL) {
+    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+  }
+  return md;
+}
+
+/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
+  const EVP_MD *md;
+  if (!alg) {
+    return EVP_sha1();
+  }
+  /* Check mask and lookup mask hash algorithm */
+  if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
+      maskHash == NULL) {
+    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+    return NULL;
+  }
+  md = EVP_get_digestbyobj(maskHash->algorithm);
+  if (md == NULL) {
+    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+    return NULL;
+  }
+  return md;
+}
+
+int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
+  const EVP_MD *sigmd, *mgf1md;
+  int saltlen;
+  if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) ||
+      !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) ||
+      !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) {
+    return 0;
+  }
+
+  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+  if (saltlen == -1) {
+    saltlen = EVP_MD_size(sigmd);
+  } else if (saltlen == -2) {
+    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
+      saltlen--;
+    }
+  } else {
+    return 0;
+  }
+
+  int ret = 0;
+  ASN1_STRING *os = NULL;
+  RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();
+  if (!pss) {
+    goto err;
+  }
+
+  if (saltlen != 20) {
+    pss->saltLength = ASN1_INTEGER_new();
+    if (!pss->saltLength ||
+        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
+      goto err;
+    }
+  }
+
+  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
+      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
+    goto err;
+  }
+
+  /* Finally create string with pss parameter encoding. */
+  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
+    goto err;
+  }
+
+  X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
+  os = NULL;
+  ret = 1;
+
+err:
+  RSA_PSS_PARAMS_free(pss);
+  ASN1_STRING_free(os);
+  return ret;
+}
+
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
+  assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
+
+  /* Decode PSS parameters */
+  int ret = 0;
+  X509_ALGOR *maskHash;
+  RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
+  if (pss == NULL) {
+    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+    goto err;
+  }
+
+  const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
+  const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm);
+  if (mgf1md == NULL || md == NULL) {
+    goto err;
+  }
+
+  int saltlen = 20;
+  if (pss->saltLength != NULL) {
+    saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+    /* Could perform more salt length sanity checks but the main
+     * RSA routines will trap other invalid values anyway. */
+    if (saltlen < 0) {
+      OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+      goto err;
+    }
+  }
+
+  /* low-level routines support only trailer field 0xbc (value 1)
+   * and PKCS#1 says we should reject any other value anyway. */
+  if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) {
+    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+    goto err;
+  }
+
+  EVP_PKEY_CTX *pkctx;
+  if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
+      !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
+      !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
+      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
+    goto err;
+  }
+
+  ret = 1;
+
+err:
+  RSA_PSS_PARAMS_free(pss);
+  X509_ALGOR_free(maskHash);
+  return ret;
+}
+
+int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
+                              ASN1_PCTX *pctx) {
+  assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
+
+  int rv = 0;
+  X509_ALGOR *maskHash;
+  RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
+  if (!pss) {
+    if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
+      goto err;
+    }
+    rv = 1;
+    goto err;
+  }
+
+  if (BIO_puts(bp, "\n") <= 0 ||
+      !BIO_indent(bp, indent, 128) ||
+      BIO_puts(bp, "Hash Algorithm: ") <= 0) {
+    goto err;
+  }
+
+  if (pss->hashAlgorithm) {
+    if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
+      goto err;
+    }
+  } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
+    goto err;
+  }
+
+  if (BIO_puts(bp, "\n") <= 0 ||
+      !BIO_indent(bp, indent, 128) ||
+      BIO_puts(bp, "Mask Algorithm: ") <= 0) {
+    goto err;
+  }
+
+  if (pss->maskGenAlgorithm) {
+    if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
+        BIO_puts(bp, " with ") <= 0) {
+      goto err;
+    }
+
+    if (maskHash) {
+      if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
+        goto err;
+      }
+    } else if (BIO_puts(bp, "INVALID") <= 0) {
+      goto err;
+    }
+  } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
+    goto err;
+  }
+  BIO_puts(bp, "\n");
+
+  if (!BIO_indent(bp, indent, 128) ||
+      BIO_puts(bp, "Salt Length: 0x") <= 0) {
+    goto err;
+  }
+
+  if (pss->saltLength) {
+    if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
+      goto err;
+    }
+  } else if (BIO_puts(bp, "14 (default)") <= 0) {
+    goto err;
+  }
+  BIO_puts(bp, "\n");
+
+  if (!BIO_indent(bp, indent, 128) ||
+      BIO_puts(bp, "Trailer Field: 0x") <= 0) {
+    goto err;
+  }
+
+  if (pss->trailerField) {
+    if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
+      goto err;
+    }
+  } else if (BIO_puts(bp, "BC (default)") <= 0) {
+    goto err;
+  }
+  BIO_puts(bp, "\n");
+
+  rv = 1;
+
+err:
+  RSA_PSS_PARAMS_free(pss);
+  X509_ALGOR_free(maskHash);
+  return rv;
+}
diff --git a/src/crypto/x509/t_crl.c b/src/crypto/x509/t_crl.c
index a2d8bc7..6c347cb 100644
--- a/src/crypto/x509/t_crl.c
+++ b/src/crypto/x509/t_crl.c
@@ -61,69 +61,68 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-
 #ifndef OPENSSL_NO_FP_API
 int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
-        {
-        BIO *b;
-        int ret;
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=X509_CRL_print(b, x);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = X509_CRL_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
 #endif
 
 int X509_CRL_print(BIO *out, X509_CRL *x)
 {
-	STACK_OF(X509_REVOKED) *rev;
-	X509_REVOKED *r;
-	long l;
-	size_t i;
-	char *p;
+    STACK_OF(X509_REVOKED) *rev;
+    X509_REVOKED *r;
+    long l;
+    size_t i;
+    char *p;
 
-	BIO_printf(out, "Certificate Revocation List (CRL):\n");
-	l = X509_CRL_get_version(x);
-	BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
-	X509_signature_print(out, x->sig_alg, NULL);
-	p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
-	BIO_printf(out,"%8sIssuer: %s\n","",p);
-	OPENSSL_free(p);
-	BIO_printf(out,"%8sLast Update: ","");
-	ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
-	BIO_printf(out,"\n%8sNext Update: ","");
-	if (X509_CRL_get_nextUpdate(x))
-		 ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
-	else BIO_printf(out,"NONE");
-	BIO_printf(out,"\n");
+    BIO_printf(out, "Certificate Revocation List (CRL):\n");
+    l = X509_CRL_get_version(x);
+    BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
+    X509_signature_print(out, x->sig_alg, NULL);
+    p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+    BIO_printf(out, "%8sIssuer: %s\n", "", p);
+    OPENSSL_free(p);
+    BIO_printf(out, "%8sLast Update: ", "");
+    ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
+    BIO_printf(out, "\n%8sNext Update: ", "");
+    if (X509_CRL_get_nextUpdate(x))
+        ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
+    else
+        BIO_printf(out, "NONE");
+    BIO_printf(out, "\n");
 
-	X509V3_extensions_print(out, "CRL extensions",
-						x->crl->extensions, 0, 8);
+    X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8);
 
-	rev = X509_CRL_get_REVOKED(x);
+    rev = X509_CRL_get_REVOKED(x);
 
-	if(sk_X509_REVOKED_num(rev) > 0)
-	    BIO_printf(out, "Revoked Certificates:\n");
-	else BIO_printf(out, "No Revoked Certificates.\n");
+    if (sk_X509_REVOKED_num(rev) > 0)
+        BIO_printf(out, "Revoked Certificates:\n");
+    else
+        BIO_printf(out, "No Revoked Certificates.\n");
 
-	for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
-		r = sk_X509_REVOKED_value(rev, i);
-		BIO_printf(out,"    Serial Number: ");
-		i2a_ASN1_INTEGER(out,r->serialNumber);
-		BIO_printf(out,"\n        Revocation Date: ");
-		ASN1_TIME_print(out,r->revocationDate);
-		BIO_printf(out,"\n");
-		X509V3_extensions_print(out, "CRL entry extensions",
-						r->extensions, 0, 8);
-	}
-	X509_signature_print(out, x->sig_alg, x->signature);
+    for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+        r = sk_X509_REVOKED_value(rev, i);
+        BIO_printf(out, "    Serial Number: ");
+        i2a_ASN1_INTEGER(out, r->serialNumber);
+        BIO_printf(out, "\n        Revocation Date: ");
+        ASN1_TIME_print(out, r->revocationDate);
+        BIO_printf(out, "\n");
+        X509V3_extensions_print(out, "CRL entry extensions",
+                                r->extensions, 0, 8);
+    }
+    X509_signature_print(out, x->sig_alg, x->signature);
 
-	return 1;
+    return 1;
 
 }
diff --git a/src/crypto/x509/t_x509.c b/src/crypto/x509/t_x509.c
index 7785ebf..1fba9b4 100644
--- a/src/crypto/x509/t_x509.c
+++ b/src/crypto/x509/t_x509.c
@@ -64,437 +64,443 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-#include "../evp/internal.h"
+#include "internal.h"
+
 
 #ifndef OPENSSL_NO_FP_API
-int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
-        {
-        BIO *b;
-        int ret;
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+                     unsigned long cflag)
+{
+    BIO *b;
+    int ret;
 
-        if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
-                return(0);
-		}
-        BIO_set_fp(b,fp,BIO_NOCLOSE);
-        ret=X509_print_ex(b, x, nmflag, cflag);
-        BIO_free(b);
-        return(ret);
-        }
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = X509_print_ex(b, x, nmflag, cflag);
+    BIO_free(b);
+    return (ret);
+}
 
 int X509_print_fp(FILE *fp, X509 *x)
-	{
-	return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
-	}
+{
+    return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
 #endif
 
 int X509_print(BIO *bp, X509 *x)
 {
-	return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+    return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
 }
 
-int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
-	{
-	long l;
-	int ret=0,i;
-	char *m=NULL,mlch = ' ';
-	int nmindent = 0;
-	X509_CINF *ci;
-	ASN1_INTEGER *bs;
-	EVP_PKEY *pkey=NULL;
-	const char *neg;
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+                  unsigned long cflag)
+{
+    long l;
+    int ret = 0, i;
+    char *m = NULL, mlch = ' ';
+    int nmindent = 0;
+    X509_CINF *ci;
+    ASN1_INTEGER *bs;
+    EVP_PKEY *pkey = NULL;
+    const char *neg;
 
-	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
-			mlch = '\n';
-			nmindent = 12;
-	}
+    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+        mlch = '\n';
+        nmindent = 12;
+    }
 
-	if(nmflags == X509_FLAG_COMPAT)
-		nmindent = 16;
+    if (nmflags == X509_FLAG_COMPAT)
+        nmindent = 16;
 
-	ci=x->cert_info;
-	if(!(cflag & X509_FLAG_NO_HEADER))
-		{
-		if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
-		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_VERSION))
-		{
-		l=X509_get_version(x);
-		if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_SERIAL))
-		{
+    ci = x->cert_info;
+    if (!(cflag & X509_FLAG_NO_HEADER)) {
+        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+            goto err;
+        if (BIO_write(bp, "    Data:\n", 10) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_VERSION)) {
+        l = X509_get_version(x);
+        if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_SERIAL)) {
 
-		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;
+        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
+            goto err;
 
-		bs=X509_get_serialNumber(x);
-		if (bs->length <= (int)sizeof(long))
-			{
-			l=ASN1_INTEGER_get(bs);
-			if (bs->type == V_ASN1_NEG_INTEGER)
-				{
-				l= -l;
-				neg="-";
-				}
-			else
-				neg="";
-			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
-				goto err;
-			}
-		else
-			{
-			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
-			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
+        bs = X509_get_serialNumber(x);
+        if (bs->length < (int)sizeof(long)
+            || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) {
+            l = ASN1_INTEGER_get(bs);
+            if (bs->type == V_ASN1_NEG_INTEGER) {
+                l = -l;
+                neg = "-";
+            } else
+                neg = "";
+            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
+                goto err;
+        } else {
+            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+                goto err;
 
-			for (i=0; i<bs->length; i++)
-				{
-				if (BIO_printf(bp,"%02x%c",bs->data[i],
-					((i+1 == bs->length)?'\n':':')) <= 0)
-					goto err;
-				}
-			}
+            for (i = 0; i < bs->length; i++) {
+                if (BIO_printf(bp, "%02x%c", bs->data[i],
+                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+                    goto err;
+            }
+        }
 
-		}
+    }
 
-	if(!(cflag & X509_FLAG_NO_SIGNAME))
-		{
-		if (X509_signature_print(bp, ci->signature, NULL) <= 0)
-			goto err;
-		}
+    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+        if (X509_signature_print(bp, ci->signature, NULL) <= 0)
+            goto err;
+    }
 
-	if(!(cflag & X509_FLAG_NO_ISSUER))
-		{
-		if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
-		if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
-		if (BIO_write(bp,"\n",1) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_VALIDITY))
-		{
-		if (BIO_write(bp,"        Validity\n",17) <= 0) goto err;
-		if (BIO_write(bp,"            Not Before: ",24) <= 0) goto err;
-		if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
-		if (BIO_write(bp,"\n            Not After : ",25) <= 0) goto err;
-		if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
-		if (BIO_write(bp,"\n",1) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_SUBJECT))
-		{
-		if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
-		if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
-		if (BIO_write(bp,"\n",1) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_PUBKEY))
-		{
-		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
-			goto err;
-		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
-			goto err;
-		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
-			goto err;
-		if (BIO_puts(bp, "\n") <= 0)
-			goto err;
+    if (!(cflag & X509_FLAG_NO_ISSUER)) {
+        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
+            goto err;
+        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+            < 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+        if (BIO_write(bp, "        Validity\n", 17) <= 0)
+            goto err;
+        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
+            goto err;
+        if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
+            goto err;
+        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
+            goto err;
+        if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
+            goto err;
+        if (X509_NAME_print_ex
+            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
+            goto err;
+        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+            goto err;
+        if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+            goto err;
+        if (BIO_puts(bp, "\n") <= 0)
+            goto err;
 
-		pkey=X509_get_pubkey(x);
-		if (pkey == NULL)
-			{
-			BIO_printf(bp,"%12sUnable to load Public Key\n","");
-			BIO_print_errors(bp);
-			}
-		else
-			{
-			EVP_PKEY_print_public(bp, pkey, 16, NULL);
-			EVP_PKEY_free(pkey);
-			}
-		}
+        pkey = X509_get_pubkey(x);
+        if (pkey == NULL) {
+            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+            BIO_print_errors(bp);
+        } else {
+            EVP_PKEY_print_public(bp, pkey, 16, NULL);
+            EVP_PKEY_free(pkey);
+        }
+    }
 
-	if(!(cflag & X509_FLAG_NO_IDS))
-		{
-		if (ci->issuerUID)
-			{
-			if (BIO_printf(bp,"%8sIssuer Unique ID: ","") <= 0) 
-				goto err;
-			if (!X509_signature_dump(bp, ci->issuerUID, 12))
-				goto err;
-			}
-		if (ci->subjectUID)
-			{
-			if (BIO_printf(bp,"%8sSubject Unique ID: ","") <= 0) 
-				goto err;
-			if (!X509_signature_dump(bp, ci->subjectUID, 12))
-				goto err;
-			}
-		}
+    if (!(cflag & X509_FLAG_NO_IDS)) {
+        if (ci->issuerUID) {
+            if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, ci->issuerUID, 12))
+                goto err;
+        }
+        if (ci->subjectUID) {
+            if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, ci->subjectUID, 12))
+                goto err;
+        }
+    }
 
-	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
-		X509V3_extensions_print(bp, "X509v3 extensions",
-					ci->extensions, cflag, 8);
+    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+        X509V3_extensions_print(bp, "X509v3 extensions",
+                                ci->extensions, cflag, 8);
 
-	if(!(cflag & X509_FLAG_NO_SIGDUMP))
-		{
-		if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
-		}
-	if(!(cflag & X509_FLAG_NO_AUX))
-		{
-		if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
-		}
-	ret=1;
-err:
-	if (m != NULL) OPENSSL_free(m);
-	return(ret);
-	}
+    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+        if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_AUX)) {
+        if (!X509_CERT_AUX_print(bp, x->aux, 0))
+            goto err;
+    }
+    ret = 1;
+ err:
+    if (m != NULL)
+        OPENSSL_free(m);
+    return (ret);
+}
 
-int X509_ocspid_print (BIO *bp, X509 *x)
-	{
-	unsigned char *der=NULL ;
-	unsigned char *dertmp;
-	int derlen;
-	int i;
-	unsigned char SHA1md[SHA_DIGEST_LENGTH];
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+    unsigned char *der = NULL;
+    unsigned char *dertmp;
+    int derlen;
+    int i;
+    unsigned char SHA1md[SHA_DIGEST_LENGTH];
 
-	/* display the hash of the subject as it would appear
-	   in OCSP requests */
-	if (BIO_printf(bp,"        Subject OCSP hash: ") <= 0)
-		goto err;
-	derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
-	if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
-		goto err;
-	i2d_X509_NAME(x->cert_info->subject, &dertmp);
+    /*
+     * display the hash of the subject as it would appear in OCSP requests
+     */
+    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
+        goto err;
+    derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
+    if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
+        goto err;
+    i2d_X509_NAME(x->cert_info->subject, &dertmp);
 
-	if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
-		goto err;
-	for (i=0; i < SHA_DIGEST_LENGTH; i++)
-		{
-		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
-		}
-	OPENSSL_free (der);
-	der=NULL;
+    if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+        goto err;
+    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+            goto err;
+    }
+    OPENSSL_free(der);
+    der = NULL;
 
-	/* display the hash of the public key as it would appear
-	   in OCSP requests */
-	if (BIO_printf(bp,"\n        Public key OCSP hash: ") <= 0)
-		goto err;
+    /*
+     * display the hash of the public key as it would appear in OCSP requests
+     */
+    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
+        goto err;
 
-	if (!EVP_Digest(x->cert_info->key->public_key->data,
-			x->cert_info->key->public_key->length,
-			SHA1md, NULL, EVP_sha1(), NULL))
-		goto err;
-	for (i=0; i < SHA_DIGEST_LENGTH; i++)
-		{
-		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
-			goto err;
-		}
-	BIO_printf(bp,"\n");
+    if (!EVP_Digest(x->cert_info->key->public_key->data,
+                    x->cert_info->key->public_key->length,
+                    SHA1md, NULL, EVP_sha1(), NULL))
+        goto err;
+    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+            goto err;
+    }
+    BIO_printf(bp, "\n");
 
-	return (1);
-err:
-	if (der != NULL) OPENSSL_free(der);
-	return(0);
-	}
+    return (1);
+ err:
+    if (der != NULL)
+        OPENSSL_free(der);
+    return (0);
+}
 
 int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
 {
-	int sig_nid;
-	if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
-	if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
+    if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
+        return 0;
+    if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+        return 0;
 
-	sig_nid = OBJ_obj2nid(sigalg->algorithm);
-	if (sig_nid != NID_undef)
-		{
-		int pkey_nid, dig_nid;
-		const EVP_PKEY_ASN1_METHOD *ameth;
-		if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
-			{
-			ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
-			if (ameth && ameth->sig_print)
-				return ameth->sig_print(bp, sigalg, sig, 9, 0);
-			}
-		}
-	if (sig)
-		return X509_signature_dump(bp, sig, 9);
-	else if (BIO_puts(bp, "\n") <= 0)
-		return 0;
-	return 1;
+    /* RSA-PSS signatures have parameters to print. */
+    int sig_nid = OBJ_obj2nid(sigalg->algorithm);
+    if (sig_nid == NID_rsassaPss &&
+        !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) {
+        return 0;
+    }
+
+    if (sig)
+        return X509_signature_dump(bp, sig, 9);
+    else if (BIO_puts(bp, "\n") <= 0)
+        return 0;
+    return 1;
 }
 
 int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
-	{
-	int i,n;
-	char buf[80];
-	const char *p;
+{
+    int i, n;
+    char buf[80];
+    const char *p;
 
-	if (v == NULL) return(0);
-	n=0;
-	p=(const char *)v->data;
-	for (i=0; i<v->length; i++)
-		{
-		if ((p[i] > '~') || ((p[i] < ' ') &&
-			(p[i] != '\n') && (p[i] != '\r')))
-			buf[n]='.';
-		else
-			buf[n]=p[i];
-		n++;
-		if (n >= 80)
-			{
-			if (BIO_write(bp,buf,n) <= 0)
-				return(0);
-			n=0;
-			}
-		}
-	if (n > 0)
-		if (BIO_write(bp,buf,n) <= 0)
-			return(0);
-	return(1);
-	}
+    if (v == NULL)
+        return (0);
+    n = 0;
+    p = (const char *)v->data;
+    for (i = 0; i < v->length; i++) {
+        if ((p[i] > '~') || ((p[i] < ' ') &&
+                             (p[i] != '\n') && (p[i] != '\r')))
+            buf[n] = '.';
+        else
+            buf[n] = p[i];
+        n++;
+        if (n >= 80) {
+            if (BIO_write(bp, buf, n) <= 0)
+                return (0);
+            n = 0;
+        }
+    }
+    if (n > 0)
+        if (BIO_write(bp, buf, n) <= 0)
+            return (0);
+    return (1);
+}
 
 int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
 {
-	if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
-	if(tm->type == V_ASN1_GENERALIZEDTIME)
-				return ASN1_GENERALIZEDTIME_print(bp, tm);
-	BIO_write(bp,"Bad time value",14);
-	return(0);
+    if (tm->type == V_ASN1_UTCTIME)
+        return ASN1_UTCTIME_print(bp, tm);
+    if (tm->type == V_ASN1_GENERALIZEDTIME)
+        return ASN1_GENERALIZEDTIME_print(bp, tm);
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
 }
 
-static const char *const mon[12]=
-    {
-    "Jan","Feb","Mar","Apr","May","Jun",
-    "Jul","Aug","Sep","Oct","Nov","Dec"
-    };
+static const char *const mon[12] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
 
 int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
-	{
-	char *v;
-	int gmt=0;
-	int i;
-	int y=0,M=0,d=0,h=0,m=0,s=0;
-	char *f = NULL;
-	int f_len = 0;
+{
+    char *v;
+    int gmt = 0;
+    int i;
+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+    char *f = NULL;
+    int f_len = 0;
 
-	i=tm->length;
-	v=(char *)tm->data;
+    i = tm->length;
+    v = (char *)tm->data;
 
-	if (i < 12) goto err;
-	if (v[i-1] == 'Z') gmt=1;
-	for (i=0; i<12; i++)
-		if ((v[i] > '9') || (v[i] < '0')) goto err;
-	y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
-	M= (v[4]-'0')*10+(v[5]-'0');
-	if ((M > 12) || (M < 1)) goto err;
-	d= (v[6]-'0')*10+(v[7]-'0');
-	h= (v[8]-'0')*10+(v[9]-'0');
-	m=  (v[10]-'0')*10+(v[11]-'0');
-	if (tm->length >= 14 &&
-	    (v[12] >= '0') && (v[12] <= '9') &&
-	    (v[13] >= '0') && (v[13] <= '9'))
-		{
-		s=  (v[12]-'0')*10+(v[13]-'0');
-		/* Check for fractions of seconds. */
-		if (tm->length >= 15 && v[14] == '.')
-			{
-			int l = tm->length;
-			f = &v[14];	/* The decimal point. */
-			f_len = 1;
-			while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
-				++f_len;
-			}
-		}
+    if (i < 12)
+        goto err;
+    if (v[i - 1] == 'Z')
+        gmt = 1;
+    for (i = 0; i < 12; i++)
+        if ((v[i] > '9') || (v[i] < '0'))
+            goto err;
+    y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] -
+                                                                        '0');
+    M = (v[4] - '0') * 10 + (v[5] - '0');
+    if ((M > 12) || (M < 1))
+        goto err;
+    d = (v[6] - '0') * 10 + (v[7] - '0');
+    h = (v[8] - '0') * 10 + (v[9] - '0');
+    m = (v[10] - '0') * 10 + (v[11] - '0');
+    if (tm->length >= 14 &&
+        (v[12] >= '0') && (v[12] <= '9') &&
+        (v[13] >= '0') && (v[13] <= '9')) {
+        s = (v[12] - '0') * 10 + (v[13] - '0');
+        /* Check for fractions of seconds. */
+        if (tm->length >= 15 && v[14] == '.') {
+            int l = tm->length;
+            f = &v[14];         /* The decimal point. */
+            f_len = 1;
+            while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+                ++f_len;
+        }
+    }
 
-	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
-		mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
-		return(0);
-	else
-		return(1);
-err:
-	BIO_write(bp,"Bad time value",14);
-	return(0);
-	}
+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+                   mon[M - 1], d, h, m, s, f_len, f, y,
+                   (gmt) ? " GMT" : "") <= 0)
+        return (0);
+    else
+        return (1);
+ err:
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
+}
 
 int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
-	{
-	const char *v;
-	int gmt=0;
-	int i;
-	int y=0,M=0,d=0,h=0,m=0,s=0;
+{
+    const char *v;
+    int gmt = 0;
+    int i;
+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
 
-	i=tm->length;
-	v=(const char *)tm->data;
+    i = tm->length;
+    v = (const char *)tm->data;
 
-	if (i < 10) goto err;
-	if (v[i-1] == 'Z') gmt=1;
-	for (i=0; i<10; i++)
-		if ((v[i] > '9') || (v[i] < '0')) goto err;
-	y= (v[0]-'0')*10+(v[1]-'0');
-	if (y < 50) y+=100;
-	M= (v[2]-'0')*10+(v[3]-'0');
-	if ((M > 12) || (M < 1)) goto err;
-	d= (v[4]-'0')*10+(v[5]-'0');
-	h= (v[6]-'0')*10+(v[7]-'0');
-	m=  (v[8]-'0')*10+(v[9]-'0');
-	if (tm->length >=12 &&
-	    (v[10] >= '0') && (v[10] <= '9') &&
-	    (v[11] >= '0') && (v[11] <= '9'))
-		s=  (v[10]-'0')*10+(v[11]-'0');
+    if (i < 10)
+        goto err;
+    if (v[i - 1] == 'Z')
+        gmt = 1;
+    for (i = 0; i < 10; i++)
+        if ((v[i] > '9') || (v[i] < '0'))
+            goto err;
+    y = (v[0] - '0') * 10 + (v[1] - '0');
+    if (y < 50)
+        y += 100;
+    M = (v[2] - '0') * 10 + (v[3] - '0');
+    if ((M > 12) || (M < 1))
+        goto err;
+    d = (v[4] - '0') * 10 + (v[5] - '0');
+    h = (v[6] - '0') * 10 + (v[7] - '0');
+    m = (v[8] - '0') * 10 + (v[9] - '0');
+    if (tm->length >= 12 &&
+        (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
+        s = (v[10] - '0') * 10 + (v[11] - '0');
 
-	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
-		mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
-		return(0);
-	else
-		return(1);
-err:
-	BIO_write(bp,"Bad time value",14);
-	return(0);
-	}
+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+                   mon[M - 1], d, h, m, s, y + 1900,
+                   (gmt) ? " GMT" : "") <= 0)
+        return (0);
+    else
+        return (1);
+ err:
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
+}
 
 int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
-	{
-	char *s,*c,*b;
-	int ret=0,l,i;
+{
+    char *s, *c, *b;
+    int ret = 0, l, i;
 
-	l=80-2-obase;
+    l = 80 - 2 - obase;
 
-	b=X509_NAME_oneline(name,NULL,0);
-	if (!b)
-		return 0;
-	if (!*b)
-		{
-		OPENSSL_free(b);
-		return 1;
-		}
-	s=b+1; /* skip the first slash */
+    b = X509_NAME_oneline(name, NULL, 0);
+    if (!b)
+        return 0;
+    if (!*b) {
+        OPENSSL_free(b);
+        return 1;
+    }
+    s = b + 1;                  /* skip the first slash */
 
-	c=s;
-	for (;;)
-		{
-		if (	((*s == '/') &&
-				((s[1] >= 'A') && (s[1] <= 'Z') && (
-					(s[2] == '=') ||
-					((s[2] >= 'A') && (s[2] <= 'Z') &&
-					(s[3] == '='))
-				 ))) ||
-			(*s == '\0'))
-			{
-			i=s-c;
-			if (BIO_write(bp,c,i) != i) goto err;
-			c=s+1;	/* skip following slash */
-			if (*s != '\0')
-				{
-				if (BIO_write(bp,", ",2) != 2) goto err;
-				}
-			l--;
-			}
-		if (*s == '\0') break;
-		s++;
-		l--;
-		}
-	
-	ret=1;
-	if (0)
-		{
-err:
-		OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
-		}
-	OPENSSL_free(b);
-	return(ret);
-	}
+    c = s;
+    for (;;) {
+        if (((*s == '/') &&
+             ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
+                                                 ((s[2] >= 'A')
+                                                  && (s[2] <= 'Z')
+                                                  && (s[3] == '='))
+              ))) || (*s == '\0')) {
+            i = s - c;
+            if (BIO_write(bp, c, i) != i)
+                goto err;
+            c = s + 1;          /* skip following slash */
+            if (*s != '\0') {
+                if (BIO_write(bp, ", ", 2) != 2)
+                    goto err;
+            }
+            l--;
+        }
+        if (*s == '\0')
+            break;
+        s++;
+        l--;
+    }
+
+    ret = 1;
+    if (0) {
+ err:
+        OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+    }
+    OPENSSL_free(b);
+    return (ret);
+}
diff --git a/src/crypto/x509/t_x509a.c b/src/crypto/x509/t_x509a.c
index 7667268..5436828 100644
--- a/src/crypto/x509/t_x509a.c
+++ b/src/crypto/x509/t_x509a.c
@@ -60,50 +60,52 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 /* X509_CERT_AUX and string set routines */
 
 int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
 {
-	char oidstr[80], first;
-	size_t i;
-	int j;
-	if(!aux) return 1;
-	if(aux->trust) {
-		first = 1;
-		BIO_printf(out, "%*sTrusted Uses:\n%*s",
-						indent, "", indent + 2, "");
-		for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
-			if(!first) BIO_puts(out, ", ");
-			else first = 0;
-			OBJ_obj2txt(oidstr, sizeof oidstr,
-				sk_ASN1_OBJECT_value(aux->trust, i), 0);
-			BIO_puts(out, oidstr);
-		}
-		BIO_puts(out, "\n");
-	} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
-	if(aux->reject) {
-		first = 1;
-		BIO_printf(out, "%*sRejected Uses:\n%*s",
-						indent, "", indent + 2, "");
-		for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
-			if(!first) BIO_puts(out, ", ");
-			else first = 0;
-			OBJ_obj2txt(oidstr, sizeof oidstr,
-				sk_ASN1_OBJECT_value(aux->reject, i), 0);
-			BIO_puts(out, oidstr);
-		}
-		BIO_puts(out, "\n");
-	} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
-	if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
-							aux->alias->data);
-	if(aux->keyid) {
-		BIO_printf(out, "%*sKey Id: ", indent, "");
-		for(j = 0; j < aux->keyid->length; j++)
-			BIO_printf(out, "%s%02X",
-				j ? ":" : "",
-				aux->keyid->data[j]);
-		BIO_write(out,"\n",1);
-	}
-	return 1;
+    char oidstr[80], first;
+    size_t i;
+    int j;
+    if (!aux)
+        return 1;
+    if (aux->trust) {
+        first = 1;
+        BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+        for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+            if (!first)
+                BIO_puts(out, ", ");
+            else
+                first = 0;
+            OBJ_obj2txt(oidstr, sizeof oidstr,
+                        sk_ASN1_OBJECT_value(aux->trust, i), 0);
+            BIO_puts(out, oidstr);
+        }
+        BIO_puts(out, "\n");
+    } else
+        BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+    if (aux->reject) {
+        first = 1;
+        BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+        for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+            if (!first)
+                BIO_puts(out, ", ");
+            else
+                first = 0;
+            OBJ_obj2txt(oidstr, sizeof oidstr,
+                        sk_ASN1_OBJECT_value(aux->reject, i), 0);
+            BIO_puts(out, oidstr);
+        }
+        BIO_puts(out, "\n");
+    } else
+        BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+    if (aux->alias)
+        BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
+    if (aux->keyid) {
+        BIO_printf(out, "%*sKey Id: ", indent, "");
+        for (j = 0; j < aux->keyid->length; j++)
+            BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]);
+        BIO_write(out, "\n", 1);
+    }
+    return 1;
 }
diff --git a/src/crypto/x509/vpm_int.h b/src/crypto/x509/vpm_int.h
index 9edbd5a..9c55def 100644
--- a/src/crypto/x509/vpm_int.h
+++ b/src/crypto/x509/vpm_int.h
@@ -1,6 +1,7 @@
 /* vpm_int.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2013.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2013.
  */
 /* ====================================================================
  * Copyright (c) 2013 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -58,13 +59,12 @@
 
 /* internal only structure to hold additional X509_VERIFY_PARAM data */
 
-struct X509_VERIFY_PARAM_ID_st
-	{
-	STACK_OF(OPENSSL_STRING) *hosts;	/* Set of acceptable names */
-	unsigned int hostflags;	/* Flags to control matching features */
-	char *peername;		/* Matching hostname in peer certificate */
-	char *email;		/* If not NULL email address to match */
-	size_t emaillen;
-	unsigned char *ip;	/* If not NULL IP address to match */
-	size_t iplen;		/* Length of IP address */
-	};
+struct X509_VERIFY_PARAM_ID_st {
+    STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
+    unsigned int hostflags;     /* Flags to control matching features */
+    char *peername;             /* Matching hostname in peer certificate */
+    char *email;                /* If not NULL email address to match */
+    size_t emaillen;
+    unsigned char *ip;          /* If not NULL IP address to match */
+    size_t iplen;               /* Length of IP address */
+};
diff --git a/src/crypto/x509/x509.c b/src/crypto/x509/x509.c
index 31f9e1e..188fd49 100644
--- a/src/crypto/x509/x509.c
+++ b/src/crypto/x509/x509.c
@@ -57,9 +57,14 @@
 #include <openssl/x509.h>
 
 #include <openssl/bio.h>
+#include <openssl/err.h>
 #include <openssl/mem.h>
 
 
+/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define
+ * it to avoid downstream churn. */
+OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM)
+
 int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
                     int ptype, void *pval, uint8_t *penc, int penclen) {
   uint8_t **ppenc = NULL;
diff --git a/src/crypto/x509/x509_att.c b/src/crypto/x509/x509_att.c
index 1491484..b83d32f 100644
--- a/src/crypto/x509/x509_att.c
+++ b/src/crypto/x509/x509_att.c
@@ -62,292 +62,314 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
-
 int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
 {
-	return sk_X509_ATTRIBUTE_num(x);
+    return sk_X509_ATTRIBUTE_num(x);
 }
 
 int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
-			  int lastpos)
+                           int lastpos)
 {
-	const ASN1_OBJECT *obj;
+    const ASN1_OBJECT *obj;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL) return(-2);
-	return(X509at_get_attr_by_OBJ(x,obj,lastpos));
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-2);
+    return (X509at_get_attr_by_OBJ(x, obj, lastpos));
 }
 
-int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj,
-			  int lastpos)
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+                           const ASN1_OBJECT *obj, int lastpos)
 {
-	int n;
-	X509_ATTRIBUTE *ex;
+    int n;
+    X509_ATTRIBUTE *ex;
 
-	if (sk == NULL) return(-1);
-	lastpos++;
-	if (lastpos < 0)
-		lastpos=0;
-	n=sk_X509_ATTRIBUTE_num(sk);
-	for ( ; lastpos < n; lastpos++)
-		{
-		ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
-		if (OBJ_cmp(ex->object,obj) == 0)
-			return(lastpos);
-		}
-	return(-1);
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_ATTRIBUTE_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
+        if (OBJ_cmp(ex->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
 }
 
 X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
 {
-	if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t) loc)
-		return NULL;
-	else
-		return sk_X509_ATTRIBUTE_value(x,loc);
+    if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc)
+        return NULL;
+    else
+        return sk_X509_ATTRIBUTE_value(x, loc);
 }
 
 X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
 {
-	X509_ATTRIBUTE *ret;
+    X509_ATTRIBUTE *ret;
 
-	if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t) loc)
-		return(NULL);
-	ret=sk_X509_ATTRIBUTE_delete(x,loc);
-	return(ret);
+    if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc)
+        return (NULL);
+    ret = sk_X509_ATTRIBUTE_delete(x, loc);
+    return (ret);
 }
 
 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
-					 X509_ATTRIBUTE *attr)
+                                           X509_ATTRIBUTE *attr)
 {
-	X509_ATTRIBUTE *new_attr=NULL;
-	STACK_OF(X509_ATTRIBUTE) *sk=NULL;
+    X509_ATTRIBUTE *new_attr = NULL;
+    STACK_OF(X509_ATTRIBUTE) *sk = NULL;
 
-	if (x == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
-		goto err2;
-		} 
+    if (x == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+        goto err2;
+    }
 
-	if (*x == NULL)
-		{
-		if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
-			goto err;
-		}
-	else
-		sk= *x;
+    if (*x == NULL) {
+        if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
+            goto err;
+    } else
+        sk = *x;
 
-	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
-		goto err2;
-	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
-		goto err;
-	if (*x == NULL)
-		*x=sk;
-	return(sk);
-err:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-err2:
-	if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
-	if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
-	return(NULL);
+    if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
+        goto err2;
+    if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
+        goto err;
+    if (*x == NULL)
+        *x = sk;
+    return (sk);
+ err:
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ err2:
+    if (new_attr != NULL)
+        X509_ATTRIBUTE_free(new_attr);
+    if (sk != NULL)
+        sk_X509_ATTRIBUTE_free(sk);
+    return (NULL);
 }
 
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
-			const ASN1_OBJECT *obj, int type,
-			const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const ASN1_OBJECT *obj,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
 {
-	X509_ATTRIBUTE *attr;
-	STACK_OF(X509_ATTRIBUTE) *ret;
-	attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
-	if(!attr) return 0;
-	ret = X509at_add1_attr(x, attr);
-	X509_ATTRIBUTE_free(attr);
-	return ret;
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
 }
 
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
-			int nid, int type,
-			const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, int nid, int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
 {
-	X509_ATTRIBUTE *attr;
-	STACK_OF(X509_ATTRIBUTE) *ret;
-	attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
-	if(!attr) return 0;
-	ret = X509at_add1_attr(x, attr);
-	X509_ATTRIBUTE_free(attr);
-	return ret;
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
 }
 
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
-			const char *attrname, int type,
-			const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const char *attrname,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
 {
-	X509_ATTRIBUTE *attr;
-	STACK_OF(X509_ATTRIBUTE) *ret;
-	attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
-	if(!attr) return 0;
-	ret = X509at_add1_attr(x, attr);
-	X509_ATTRIBUTE_free(attr);
-	return ret;
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
 }
 
 void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
-				ASN1_OBJECT *obj, int lastpos, int type)
+                              ASN1_OBJECT *obj, int lastpos, int type)
 {
-	int i;
-	X509_ATTRIBUTE *at;
-	i = X509at_get_attr_by_OBJ(x, obj, lastpos);
-	if (i == -1)
-		return NULL;
-	if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
-		return NULL;
-	at = X509at_get_attr(x, i);
-	if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
-		return NULL;
-	return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
+    int i;
+    X509_ATTRIBUTE *at;
+    i = X509at_get_attr_by_OBJ(x, obj, lastpos);
+    if (i == -1)
+        return NULL;
+    if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
+        return NULL;
+    at = X509at_get_attr(x, i);
+    if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
+        return NULL;
+    return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
 }
 
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
-	     int atrtype, const void *data, int len)
+                                             int atrtype, const void *data,
+                                             int len)
 {
-	const ASN1_OBJECT *obj;
+    const ASN1_OBJECT *obj;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
-		return(NULL);
-		}
-	return X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+        return (NULL);
+    }
+    return X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
 }
 
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
-	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
+                                             const ASN1_OBJECT *obj,
+                                             int atrtype, const void *data,
+                                             int len)
 {
-	X509_ATTRIBUTE *ret;
+    X509_ATTRIBUTE *ret;
 
-	if ((attr == NULL) || (*attr == NULL))
-		{
-		if ((ret=X509_ATTRIBUTE_new()) == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			return(NULL);
-			}
-		}
-	else
-		ret= *attr;
+    if ((attr == NULL) || (*attr == NULL)) {
+        if ((ret = X509_ATTRIBUTE_new()) == NULL) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else
+        ret = *attr;
 
-	if (!X509_ATTRIBUTE_set1_object(ret,obj))
-		goto err;
-	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
-		goto err;
+    if (!X509_ATTRIBUTE_set1_object(ret, obj))
+        goto err;
+    if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
+        goto err;
 
-	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
-	return(ret);
-err:
-	if ((attr == NULL) || (ret != *attr))
-		X509_ATTRIBUTE_free(ret);
-	return(NULL);
+    if ((attr != NULL) && (*attr == NULL))
+        *attr = ret;
+    return (ret);
+ err:
+    if ((attr == NULL) || (ret != *attr))
+        X509_ATTRIBUTE_free(ret);
+    return (NULL);
 }
 
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
-		const char *atrname, int type, const unsigned char *bytes, int len)
-	{
-	ASN1_OBJECT *obj;
-	X509_ATTRIBUTE *nattr;
+                                             const char *atrname, int type,
+                                             const unsigned char *bytes,
+                                             int len)
+{
+    ASN1_OBJECT *obj;
+    X509_ATTRIBUTE *nattr;
 
-	obj=OBJ_txt2obj(atrname, 0);
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
-		ERR_add_error_data(2, "name=", atrname);
-		return(NULL);
-		}
-	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
-	ASN1_OBJECT_free(obj);
-	return nattr;
-	}
+    obj = OBJ_txt2obj(atrname, 0);
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
+        ERR_add_error_data(2, "name=", atrname);
+        return (NULL);
+    }
+    nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
+    ASN1_OBJECT_free(obj);
+    return nattr;
+}
 
 int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
 {
-	if ((attr == NULL) || (obj == NULL))
-		return(0);
-	ASN1_OBJECT_free(attr->object);
-	attr->object=OBJ_dup(obj);
-	return attr->object != NULL;
+    if ((attr == NULL) || (obj == NULL))
+        return (0);
+    ASN1_OBJECT_free(attr->object);
+    attr->object = OBJ_dup(obj);
+    return attr->object != NULL;
 }
 
-int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+                             const void *data, int len)
 {
-	ASN1_TYPE *ttmp;
-	ASN1_STRING *stmp = NULL;
-	int atype = 0;
-	if (!attr) return 0;
-	if(attrtype & MBSTRING_FLAG) {
-		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
-						OBJ_obj2nid(attr->object));
-		if(!stmp) {
-			OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
-			return 0;
-		}
-		atype = stmp->type;
-	} else if (len != -1){
-		if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
-		if(!ASN1_STRING_set(stmp, data, len)) goto err;
-		atype = attrtype;
-	}
-	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
-	attr->single = 0;
-	/* This is a bit naughty because the attribute should really have
-	 * at least one value but some types use and zero length SET and
-	 * require this.
-	 */
-	if (attrtype == 0)
-		return 1;
-	if(!(ttmp = ASN1_TYPE_new())) goto err;
-	if ((len == -1) && !(attrtype & MBSTRING_FLAG))
-		{
-		if (!ASN1_TYPE_set1(ttmp, attrtype, data))
-			goto err;
-		}
-	else
-		ASN1_TYPE_set(ttmp, atype, stmp);
-	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
-	return 1;
-	err:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	return 0;
+    ASN1_TYPE *ttmp;
+    ASN1_STRING *stmp = NULL;
+    int atype = 0;
+    if (!attr)
+        return 0;
+    if (attrtype & MBSTRING_FLAG) {
+        stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
+                                      OBJ_obj2nid(attr->object));
+        if (!stmp) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+            return 0;
+        }
+        atype = stmp->type;
+    } else if (len != -1) {
+        if (!(stmp = ASN1_STRING_type_new(attrtype)))
+            goto err;
+        if (!ASN1_STRING_set(stmp, data, len))
+            goto err;
+        atype = attrtype;
+    }
+    if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
+        goto err;
+    attr->single = 0;
+    /*
+     * This is a bit naughty because the attribute should really have at
+     * least one value but some types use and zero length SET and require
+     * this.
+     */
+    if (attrtype == 0)
+        return 1;
+    if (!(ttmp = ASN1_TYPE_new()))
+        goto err;
+    if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
+        if (!ASN1_TYPE_set1(ttmp, attrtype, data))
+            goto err;
+    } else
+        ASN1_TYPE_set(ttmp, atype, stmp);
+    if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
+        goto err;
+    return 1;
+ err:
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    return 0;
 }
 
 int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
 {
-	if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
-	if(attr->value.single) return 1;
-	return 0;
+    if (!attr->single)
+        return sk_ASN1_TYPE_num(attr->value.set);
+    if (attr->value.single)
+        return 1;
+    return 0;
 }
 
 ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
 {
-	if (attr == NULL) return(NULL);
-	return(attr->object);
+    if (attr == NULL)
+        return (NULL);
+    return (attr->object);
 }
 
 void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
-					int atrtype, void *data)
+                               int atrtype, void *data)
 {
-	ASN1_TYPE *ttmp;
-	ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
-	if(!ttmp) return NULL;
-	if(atrtype != ASN1_TYPE_get(ttmp)){
-		OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
-		return NULL;
-	}
-	return ttmp->value.ptr;
+    ASN1_TYPE *ttmp;
+    ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
+    if (!ttmp)
+        return NULL;
+    if (atrtype != ASN1_TYPE_get(ttmp)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
+        return NULL;
+    }
+    return ttmp->value.ptr;
 }
 
 ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
 {
-	if (attr == NULL) return(NULL);
-	if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
-	if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
-	else return attr->value.single;
+    if (attr == NULL)
+        return (NULL);
+    if (idx >= X509_ATTRIBUTE_count(attr))
+        return NULL;
+    if (!attr->single)
+        return sk_ASN1_TYPE_value(attr->value.set, idx);
+    else
+        return attr->value.single;
 }
diff --git a/src/crypto/x509/x509_cmp.c b/src/crypto/x509/x509_cmp.c
index 0e35f3e..32862eb 100644
--- a/src/crypto/x509/x509_cmp.c
+++ b/src/crypto/x509/x509_cmp.c
@@ -67,424 +67,408 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-
 int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
-	{
-	int i;
-	X509_CINF *ai,*bi;
+{
+    int i;
+    X509_CINF *ai, *bi;
 
-	ai=a->cert_info;
-	bi=b->cert_info;
-	i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
-	if (i) return(i);
-	return(X509_NAME_cmp(ai->issuer,bi->issuer));
-	}
+    ai = a->cert_info;
+    bi = b->cert_info;
+    i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
+    if (i)
+        return (i);
+    return (X509_NAME_cmp(ai->issuer, bi->issuer));
+}
 
 unsigned long X509_issuer_and_serial_hash(X509 *a)
-	{
-	unsigned long ret=0;
-	EVP_MD_CTX ctx;
-	unsigned char md[16];
-	char *f;
+{
+    unsigned long ret = 0;
+    EVP_MD_CTX ctx;
+    unsigned char md[16];
+    char *f;
 
-	EVP_MD_CTX_init(&ctx);
-	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
-	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
-		goto err;
-	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
-		goto err;
-	OPENSSL_free(f);
-	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
-		(unsigned long)a->cert_info->serialNumber->length))
-		goto err;
-	if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
-		goto err;
-	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-		)&0xffffffffL;
-	err:
-	EVP_MD_CTX_cleanup(&ctx);
-	return(ret);
-	}
-	
+    EVP_MD_CTX_init(&ctx);
+    f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
+    if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+        goto err;
+    if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
+        goto err;
+    OPENSSL_free(f);
+    if (!EVP_DigestUpdate
+        (&ctx, (unsigned char *)a->cert_info->serialNumber->data,
+         (unsigned long)a->cert_info->serialNumber->length))
+        goto err;
+    if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
+        goto err;
+    ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+           ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+        ) & 0xffffffffL;
+ err:
+    EVP_MD_CTX_cleanup(&ctx);
+    return (ret);
+}
+
 int X509_issuer_name_cmp(const X509 *a, const X509 *b)
-	{
-	return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
-	}
+{
+    return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
+}
 
 int X509_subject_name_cmp(const X509 *a, const X509 *b)
-	{
-	return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
-	}
+{
+    return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
+}
 
 int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
-	{
-	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
-	}
+{
+    return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
+}
 
 int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
-	{
-	return memcmp(a->sha1_hash, b->sha1_hash, 20);
-	}
+{
+    return memcmp(a->sha1_hash, b->sha1_hash, 20);
+}
 
 X509_NAME *X509_get_issuer_name(X509 *a)
-	{
-	return(a->cert_info->issuer);
-	}
+{
+    return (a->cert_info->issuer);
+}
 
 unsigned long X509_issuer_name_hash(X509 *x)
-	{
-	return(X509_NAME_hash(x->cert_info->issuer));
-	}
+{
+    return (X509_NAME_hash(x->cert_info->issuer));
+}
 
 unsigned long X509_issuer_name_hash_old(X509 *x)
-	{
-	return(X509_NAME_hash_old(x->cert_info->issuer));
-	}
+{
+    return (X509_NAME_hash_old(x->cert_info->issuer));
+}
 
 X509_NAME *X509_get_subject_name(X509 *a)
-	{
-	return(a->cert_info->subject);
-	}
+{
+    return (a->cert_info->subject);
+}
 
 ASN1_INTEGER *X509_get_serialNumber(X509 *a)
-	{
-	return(a->cert_info->serialNumber);
-	}
+{
+    return (a->cert_info->serialNumber);
+}
 
 unsigned long X509_subject_name_hash(X509 *x)
-	{
-	return(X509_NAME_hash(x->cert_info->subject));
-	}
+{
+    return (X509_NAME_hash(x->cert_info->subject));
+}
 
 unsigned long X509_subject_name_hash_old(X509 *x)
-	{
-	return(X509_NAME_hash_old(x->cert_info->subject));
-	}
+{
+    return (X509_NAME_hash_old(x->cert_info->subject));
+}
 
-/* Compare two certificates: they must be identical for
- * this to work. NB: Although "cmp" operations are generally
- * prototyped to take "const" arguments (eg. for use in
- * STACKs), the way X509 handling is - these operations may
- * involve ensuring the hashes are up-to-date and ensuring
- * certain cert information is cached. So this is the point
- * where the "depth-first" constification tree has to halt
- * with an evil cast.
+/*
+ * Compare two certificates: they must be identical for this to work. NB:
+ * Although "cmp" operations are generally prototyped to take "const"
+ * arguments (eg. for use in STACKs), the way X509 handling is - these
+ * operations may involve ensuring the hashes are up-to-date and ensuring
+ * certain cert information is cached. So this is the point where the
+ * "depth-first" constification tree has to halt with an evil cast.
  */
 int X509_cmp(const X509 *a, const X509 *b)
 {
-	int rv;
-	/* ensure hash is valid */
-	X509_check_purpose((X509 *)a, -1, 0);
-	X509_check_purpose((X509 *)b, -1, 0);
+    int rv;
+    /* ensure hash is valid */
+    X509_check_purpose((X509 *)a, -1, 0);
+    X509_check_purpose((X509 *)b, -1, 0);
 
-	rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
-	if (rv)
-		return rv;
-	/* Check for match against stored encoding too */
-	if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
-		{
-		rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
-		if (rv)
-			return rv;
-		return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
-				a->cert_info->enc.len);
-		}
-	return rv;
+    rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
+    if (rv)
+        return rv;
+    /* Check for match against stored encoding too */
+    if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) {
+        rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
+        if (rv)
+            return rv;
+        return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
+                      a->cert_info->enc.len);
+    }
+    return rv;
 }
 
-
 int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
-	{
-	int ret;
+{
+    int ret;
 
-	/* Ensure canonical encoding is present and up to date */
+    /* Ensure canonical encoding is present and up to date */
 
-	if (!a->canon_enc || a->modified)
-		{
-		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
-		if (ret < 0)
-			return -2;
-		}
+    if (!a->canon_enc || a->modified) {
+        ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+        if (ret < 0)
+            return -2;
+    }
 
-	if (!b->canon_enc || b->modified)
-		{
-		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
-		if (ret < 0)
-			return -2;
-		}
+    if (!b->canon_enc || b->modified) {
+        ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+        if (ret < 0)
+            return -2;
+    }
 
-	ret = a->canon_enclen - b->canon_enclen;
+    ret = a->canon_enclen - b->canon_enclen;
 
-	if (ret)
-		return ret;
+    if (ret)
+        return ret;
 
-	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+    return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
 
-	}
+}
 
 unsigned long X509_NAME_hash(X509_NAME *x)
-	{
-	unsigned long ret=0;
-	unsigned char md[SHA_DIGEST_LENGTH];
+{
+    unsigned long ret = 0;
+    unsigned char md[SHA_DIGEST_LENGTH];
 
-	/* Make sure X509_NAME structure contains valid cached encoding */
-	i2d_X509_NAME(x,NULL);
-	if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
-		NULL))
-		return 0;
+    /* Make sure X509_NAME structure contains valid cached encoding */
+    i2d_X509_NAME(x, NULL);
+    if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
+                    NULL))
+        return 0;
 
-	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-		)&0xffffffffL;
-	return(ret);
-	}
+    ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+           ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+        ) & 0xffffffffL;
+    return (ret);
+}
 
-
-/* I now DER encode the name and hash it.  Since I cache the DER encoding,
- * this is reasonably efficient. */
+/*
+ * I now DER encode the name and hash it.  Since I cache the DER encoding,
+ * this is reasonably efficient.
+ */
 
 unsigned long X509_NAME_hash_old(X509_NAME *x)
-	{
-	EVP_MD_CTX md_ctx;
-	unsigned long ret=0;
-	unsigned char md[16];
+{
+    EVP_MD_CTX md_ctx;
+    unsigned long ret = 0;
+    unsigned char md[16];
 
-	/* Make sure X509_NAME structure contains valid cached encoding */
-	i2d_X509_NAME(x,NULL);
-	EVP_MD_CTX_init(&md_ctx);
-	/* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
-	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
-	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
-	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
-		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-		     )&0xffffffffL;
-	EVP_MD_CTX_cleanup(&md_ctx);
+    /* Make sure X509_NAME structure contains valid cached encoding */
+    i2d_X509_NAME(x, NULL);
+    EVP_MD_CTX_init(&md_ctx);
+    /* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
+    if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+        && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+        && EVP_DigestFinal_ex(&md_ctx, md, NULL))
+        ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+               ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+            ) & 0xffffffffL;
+    EVP_MD_CTX_cleanup(&md_ctx);
 
-	return(ret);
-	}
+    return (ret);
+}
 
 /* Search a stack of X509 for a match */
 X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
-		ASN1_INTEGER *serial)
-	{
-	size_t i;
-	X509_CINF cinf;
-	X509 x,*x509=NULL;
+                                     ASN1_INTEGER *serial)
+{
+    size_t i;
+    X509_CINF cinf;
+    X509 x, *x509 = NULL;
 
-	if(!sk) return NULL;
+    if (!sk)
+        return NULL;
 
-	x.cert_info= &cinf;
-	cinf.serialNumber=serial;
-	cinf.issuer=name;
+    x.cert_info = &cinf;
+    cinf.serialNumber = serial;
+    cinf.issuer = name;
 
-	for (i=0; i<sk_X509_num(sk); i++)
-		{
-		x509=sk_X509_value(sk,i);
-		if (X509_issuer_and_serial_cmp(x509,&x) == 0)
-			return(x509);
-		}
-	return(NULL);
-	}
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        x509 = sk_X509_value(sk, i);
+        if (X509_issuer_and_serial_cmp(x509, &x) == 0)
+            return (x509);
+    }
+    return (NULL);
+}
 
 X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
-	{
-	X509 *x509;
-	size_t i;
+{
+    X509 *x509;
+    size_t i;
 
-	for (i=0; i<sk_X509_num(sk); i++)
-		{
-		x509=sk_X509_value(sk,i);
-		if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
-			return(x509);
-		}
-	return(NULL);
-	}
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        x509 = sk_X509_value(sk, i);
+        if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
+            return (x509);
+    }
+    return (NULL);
+}
 
 EVP_PKEY *X509_get_pubkey(X509 *x)
-	{
-	if ((x == NULL) || (x->cert_info == NULL))
-		return(NULL);
-	return(X509_PUBKEY_get(x->cert_info->key));
-	}
+{
+    if ((x == NULL) || (x->cert_info == NULL))
+        return (NULL);
+    return (X509_PUBKEY_get(x->cert_info->key));
+}
 
 ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
-	{
-	if(!x) return NULL;
-	return x->cert_info->key->public_key;
-	}
-
+{
+    if (!x)
+        return NULL;
+    return x->cert_info->key->public_key;
+}
 
 int X509_check_private_key(X509 *x, EVP_PKEY *k)
-	{
-	EVP_PKEY *xk;
-	int ret;
+{
+    EVP_PKEY *xk;
+    int ret;
 
-	xk=X509_get_pubkey(x);
+    xk = X509_get_pubkey(x);
 
-	if (xk)
-		ret = EVP_PKEY_cmp(xk, k);
-	else
-		ret = -2;
+    if (xk)
+        ret = EVP_PKEY_cmp(xk, k);
+    else
+        ret = -2;
 
-	switch (ret)
-		{
-	case 1:
-		break;
-	case 0:
-		OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
-		break;
-	case -1:
-		OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
-		break;
-	case -2:
-	        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
-		}
-	if (xk)
-		EVP_PKEY_free(xk);
-	if (ret > 0)
-		return 1;
-	return 0;
-	}
+    switch (ret) {
+    case 1:
+        break;
+    case 0:
+        OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+        break;
+    case -1:
+        OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+        break;
+    case -2:
+        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+    }
+    if (xk)
+        EVP_PKEY_free(xk);
+    if (ret > 0)
+        return 1;
+    return 0;
+}
 
-/* Check a suite B algorithm is permitted: pass in a public key and
- * the NID of its signature (or 0 if no signature). The pflags is
- * a pointer to a flags field which must contain the suite B verification
- * flags.
+/*
+ * Check a suite B algorithm is permitted: pass in a public key and the NID
+ * of its signature (or 0 if no signature). The pflags is a pointer to a
+ * flags field which must contain the suite B verification flags.
  */
 
-
 static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
-	{
-	const EC_GROUP *grp = NULL;
-	int curve_nid;
-	if (pkey && pkey->type == EVP_PKEY_EC)
-		grp = EC_KEY_get0_group(pkey->pkey.ec);
-	if (!grp)
-		return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
-	curve_nid = EC_GROUP_get_curve_name(grp);
-	/* Check curve is consistent with LOS */
-	if (curve_nid == NID_secp384r1) /* P-384 */
-		{
-		/* Check signature algorithm is consistent with
-		 * curve.
-		 */
-		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
-			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
-		if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
-			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
-		/* If we encounter P-384 we cannot use P-256 later */
-		*pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
-		}
-	else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
-		{
-		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
-			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
-		if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
-			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
-		}
-	else
-		return X509_V_ERR_SUITE_B_INVALID_CURVE;
+{
+    const EC_GROUP *grp = NULL;
+    int curve_nid;
+    if (pkey && pkey->type == EVP_PKEY_EC)
+        grp = EC_KEY_get0_group(pkey->pkey.ec);
+    if (!grp)
+        return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
+    curve_nid = EC_GROUP_get_curve_name(grp);
+    /* Check curve is consistent with LOS */
+    if (curve_nid == NID_secp384r1) { /* P-384 */
+        /*
+         * Check signature algorithm is consistent with curve.
+         */
+        if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
+            return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+        if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
+            return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+        /* If we encounter P-384 we cannot use P-256 later */
+        *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
+    } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */
+        if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
+            return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+        if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
+            return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+    } else
+        return X509_V_ERR_SUITE_B_INVALID_CURVE;
 
-	return X509_V_OK;
-	}
+    return X509_V_OK;
+}
 
 int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
-							unsigned long flags)
-	{
-	int rv, sign_nid;
-	size_t i;
-	EVP_PKEY *pk = NULL;
-	unsigned long tflags;
-	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
-		return X509_V_OK;
-	tflags = flags;
-	/* If no EE certificate passed in must be first in chain */
-	if (x == NULL)
-		{
-		x = sk_X509_value(chain, 0);
-		i = 1;
-		}
-	else
-		i = 0;
+                            unsigned long flags)
+{
+    int rv, sign_nid;
+    size_t i;
+    EVP_PKEY *pk = NULL;
+    unsigned long tflags;
+    if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+        return X509_V_OK;
+    tflags = flags;
+    /* If no EE certificate passed in must be first in chain */
+    if (x == NULL) {
+        x = sk_X509_value(chain, 0);
+        i = 1;
+    } else
+        i = 0;
 
-	if (X509_get_version(x) != 2)
-		{
-		rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
-		/* Correct error depth */
-		i = 0;
-		goto end;
-		}
+    if (X509_get_version(x) != 2) {
+        rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+        /* Correct error depth */
+        i = 0;
+        goto end;
+    }
 
-	pk = X509_get_pubkey(x);
-	/* Check EE key only */
-	rv = check_suite_b(pk, -1, &tflags);
-	if (rv != X509_V_OK)
-		{
-		/* Correct error depth */
-		i = 0;
-		goto end;
-		}
-	for(; i < sk_X509_num(chain); i++)
-		{
-		sign_nid = X509_get_signature_nid(x);
-		x = sk_X509_value(chain, i);
-		if (X509_get_version(x) != 2)
-			{
-			rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
-			goto end;
-			}
-		EVP_PKEY_free(pk);
-		pk = X509_get_pubkey(x);
-		rv = check_suite_b(pk, sign_nid, &tflags);
-		if (rv != X509_V_OK)
-			goto end;
-		}
+    pk = X509_get_pubkey(x);
+    /* Check EE key only */
+    rv = check_suite_b(pk, -1, &tflags);
+    if (rv != X509_V_OK) {
+        /* Correct error depth */
+        i = 0;
+        goto end;
+    }
+    for (; i < sk_X509_num(chain); i++) {
+        sign_nid = X509_get_signature_nid(x);
+        x = sk_X509_value(chain, i);
+        if (X509_get_version(x) != 2) {
+            rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+            goto end;
+        }
+        EVP_PKEY_free(pk);
+        pk = X509_get_pubkey(x);
+        rv = check_suite_b(pk, sign_nid, &tflags);
+        if (rv != X509_V_OK)
+            goto end;
+    }
 
-	/* Final check: root CA signature */
-	rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
-	end:
-	if (pk)
-		EVP_PKEY_free(pk);
-	if (rv != X509_V_OK)
-		{
-		/* Invalid signature or LOS errors are for previous cert */
-		if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
-		    || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
-			i--;
-		/* If we have LOS error and flags changed then we are signing
-		 * P-384 with P-256. Use more meaninggul error.
-		 */
-		if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
-			rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
-		if (perror_depth)
-			*perror_depth = i;
-		}
-	return rv;
-	}
+    /* Final check: root CA signature */
+    rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
+ end:
+    if (pk)
+        EVP_PKEY_free(pk);
+    if (rv != X509_V_OK) {
+        /* Invalid signature or LOS errors are for previous cert */
+        if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
+             || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
+            i--;
+        /*
+         * If we have LOS error and flags changed then we are signing P-384
+         * with P-256. Use more meaninggul error.
+         */
+        if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
+            rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
+        if (perror_depth)
+            *perror_depth = i;
+    }
+    return rv;
+}
 
 int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
-	{
-	int sign_nid;
-	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
-		return X509_V_OK;
-	sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
-	return check_suite_b(pk, sign_nid, &flags);
-	}
+{
+    int sign_nid;
+    if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+        return X509_V_OK;
+    sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
+    return check_suite_b(pk, sign_nid, &flags);
+}
 
-/* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
- * count but it has the same effect by duping the STACK and upping the ref
- * of each X509 structure.
+/*
+ * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
+ * count but it has the same effect by duping the STACK and upping the ref of
+ * each X509 structure.
  */
 STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
-	{
-	STACK_OF(X509) *ret;
-	size_t i;
-	ret = sk_X509_dup(chain);
-	for (i = 0; i < sk_X509_num(ret); i++)
-		{
-		X509_up_ref(sk_X509_value(ret, i));
-		}
-	return ret;
-	}
+{
+    STACK_OF(X509) *ret;
+    size_t i;
+    ret = sk_X509_dup(chain);
+    for (i = 0; i < sk_X509_num(ret); i++) {
+        X509_up_ref(sk_X509_value(ret, i));
+    }
+    return ret;
+}
diff --git a/src/crypto/x509/x509_d2.c b/src/crypto/x509/x509_d2.c
index 2161d85..69ae54e 100644
--- a/src/crypto/x509/x509_d2.c
+++ b/src/crypto/x509/x509_d2.c
@@ -58,48 +58,49 @@
 #include <openssl/err.h>
 #include <openssl/x509.h>
 
-
 #ifndef OPENSSL_NO_STDIO
 int X509_STORE_set_default_paths(X509_STORE *ctx)
-	{
-	X509_LOOKUP *lookup;
+{
+    X509_LOOKUP *lookup;
 
-	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
-	if (lookup == NULL) return(0);
-	X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+    lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+    if (lookup == NULL)
+        return (0);
+    X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
 
-	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
-	if (lookup == NULL) return(0);
-	X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
-	
-	/* clear any errors */
-	ERR_clear_error();
+    lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+    if (lookup == NULL)
+        return (0);
+    X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
 
-	return(1);
-	}
+    /* clear any errors */
+    ERR_clear_error();
+
+    return (1);
+}
 
 int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
-		const char *path)
-	{
-	X509_LOOKUP *lookup;
+                              const char *path)
+{
+    X509_LOOKUP *lookup;
 
-	if (file != NULL)
-		{
-		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
-		if (lookup == NULL) return(0);
-		if (X509_LOOKUP_load_file(lookup,file,X509_FILETYPE_PEM) != 1)
-		    return(0);
-		}
-	if (path != NULL)
-		{
-		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
-		if (lookup == NULL) return(0);
-		if (X509_LOOKUP_add_dir(lookup,path,X509_FILETYPE_PEM) != 1)
-		    return(0);
-		}
-	if ((path == NULL) && (file == NULL))
-		return(0);
-	return(1);
-	}
+    if (file != NULL) {
+        lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+        if (lookup == NULL)
+            return (0);
+        if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
+            return (0);
+    }
+    if (path != NULL) {
+        lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+        if (lookup == NULL)
+            return (0);
+        if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
+            return (0);
+    }
+    if ((path == NULL) && (file == NULL))
+        return (0);
+    return (1);
+}
 
 #endif
diff --git a/src/crypto/x509/x509_def.c b/src/crypto/x509/x509_def.c
index dbae289..2bf2240 100644
--- a/src/crypto/x509/x509_def.c
+++ b/src/crypto/x509/x509_def.c
@@ -57,32 +57,42 @@
 
 #include <openssl/x509.h>
 
-
 /* TODO(fork): cleanup */
 
 #define OPENSSLDIR "/etc/ssl"
-#define X509_CERT_AREA		OPENSSLDIR
-#define X509_CERT_DIR		OPENSSLDIR "/certs"
-#define X509_CERT_FILE		OPENSSLDIR "/cert.pem"
-#define X509_PRIVATE_DIR	OPENSSLDIR "/private"
+#define X509_CERT_AREA          OPENSSLDIR
+#define X509_CERT_DIR           OPENSSLDIR "/certs"
+#define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR        OPENSSLDIR "/private"
 #define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
 #define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
 
 const char *X509_get_default_private_dir(void)
-	{ return(X509_PRIVATE_DIR); }
-	
+{
+    return (X509_PRIVATE_DIR);
+}
+
 const char *X509_get_default_cert_area(void)
-	{ return(X509_CERT_AREA); }
+{
+    return (X509_CERT_AREA);
+}
 
 const char *X509_get_default_cert_dir(void)
-	{ return(X509_CERT_DIR); }
+{
+    return (X509_CERT_DIR);
+}
 
 const char *X509_get_default_cert_file(void)
-	{ return(X509_CERT_FILE); }
+{
+    return (X509_CERT_FILE);
+}
 
 const char *X509_get_default_cert_dir_env(void)
-	{ return(X509_CERT_DIR_EVP); }
+{
+    return (X509_CERT_DIR_EVP);
+}
 
 const char *X509_get_default_cert_file_env(void)
-	{ return(X509_CERT_FILE_EVP); }
-
+{
+    return (X509_CERT_FILE_EVP);
+}
diff --git a/src/crypto/x509/x509_ext.c b/src/crypto/x509/x509_ext.c
index 2f1e0c5..a329f6f 100644
--- a/src/crypto/x509/x509_ext.c
+++ b/src/crypto/x509/x509_ext.c
@@ -62,145 +62,145 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-
 int X509_CRL_get_ext_count(X509_CRL *x)
-	{
-	return(X509v3_get_ext_count(x->crl->extensions));
-	}
+{
+    return (X509v3_get_ext_count(x->crl->extensions));
+}
 
 int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
-	{
-	return(X509v3_get_ext_by_NID(x->crl->extensions,nid,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos));
+}
 
 int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
-	{
-	return(X509v3_get_ext_by_OBJ(x->crl->extensions,obj,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos));
+}
 
 int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
-	{
-	return(X509v3_get_ext_by_critical(x->crl->extensions,crit,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
+}
 
 X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
-	{
-	return(X509v3_get_ext(x->crl->extensions,loc));
-	}
+{
+    return (X509v3_get_ext(x->crl->extensions, loc));
+}
 
 X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
-	{
-	return(X509v3_delete_ext(x->crl->extensions,loc));
-	}
+{
+    return (X509v3_delete_ext(x->crl->extensions, loc));
+}
 
 void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
 {
-	return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
+    return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
 }
 
 int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
-							unsigned long flags)
+                          unsigned long flags)
 {
-	return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
+    return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
 }
 
 int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
-	{
-	return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL);
-	}
+{
+    return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
+}
 
 int X509_get_ext_count(X509 *x)
-	{
-	return(X509v3_get_ext_count(x->cert_info->extensions));
-	}
+{
+    return (X509v3_get_ext_count(x->cert_info->extensions));
+}
 
 int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
-	{
-	return(X509v3_get_ext_by_NID(x->cert_info->extensions,nid,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos));
+}
 
 int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
-	{
-	return(X509v3_get_ext_by_OBJ(x->cert_info->extensions,obj,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos));
+}
 
 int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
-	{
-	return(X509v3_get_ext_by_critical(x->cert_info->extensions,crit,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_critical
+            (x->cert_info->extensions, crit, lastpos));
+}
 
 X509_EXTENSION *X509_get_ext(X509 *x, int loc)
-	{
-	return(X509v3_get_ext(x->cert_info->extensions,loc));
-	}
+{
+    return (X509v3_get_ext(x->cert_info->extensions, loc));
+}
 
 X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
-	{
-	return(X509v3_delete_ext(x->cert_info->extensions,loc));
-	}
+{
+    return (X509v3_delete_ext(x->cert_info->extensions, loc));
+}
 
 int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
-	{
-	return(X509v3_add_ext(&(x->cert_info->extensions),ex,loc) != NULL);
-	}
+{
+    return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
+}
 
 void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
 {
-	return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
+    return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
 }
 
 int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
-							unsigned long flags)
+                      unsigned long flags)
 {
-	return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
-							flags);
+    return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
+                           flags);
 }
 
 int X509_REVOKED_get_ext_count(X509_REVOKED *x)
-	{
-	return(X509v3_get_ext_count(x->extensions));
-	}
+{
+    return (X509v3_get_ext_count(x->extensions));
+}
 
 int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
-	{
-	return(X509v3_get_ext_by_NID(x->extensions,nid,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
+}
 
 int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
-	     int lastpos)
-	{
-	return(X509v3_get_ext_by_OBJ(x->extensions,obj,lastpos));
-	}
+                                int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
+}
 
 int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
-	{
-	return(X509v3_get_ext_by_critical(x->extensions,crit,lastpos));
-	}
+{
+    return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
+}
 
 X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
-	{
-	return(X509v3_get_ext(x->extensions,loc));
-	}
+{
+    return (X509v3_get_ext(x->extensions, loc));
+}
 
 X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
-	{
-	return(X509v3_delete_ext(x->extensions,loc));
-	}
+{
+    return (X509v3_delete_ext(x->extensions, loc));
+}
 
 int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
-	{
-	return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL);
-	}
+{
+    return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
+}
 
 void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
 {
-	return X509V3_get_d2i(x->extensions, nid, crit, idx);
+    return X509V3_get_d2i(x->extensions, nid, crit, idx);
 }
 
 int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
-							unsigned long flags)
+                              unsigned long flags)
 {
-	return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
+    return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
 }
 
 IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 5751f75..ec3f300 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -66,673 +66,640 @@
 
 #include "../internal.h"
 
-
 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
-	{
-	X509_LOOKUP *ret;
+{
+    X509_LOOKUP *ret;
 
-	ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
-	if (ret == NULL) return NULL;
+    ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
+    if (ret == NULL)
+        return NULL;
 
-	ret->init=0;
-	ret->skip=0;
-	ret->method=method;
-	ret->method_data=NULL;
-	ret->store_ctx=NULL;
-	if ((method->new_item != NULL) && !method->new_item(ret))
-		{
-		OPENSSL_free(ret);
-		return NULL;
-		}
-	return ret;
-	}
+    ret->init = 0;
+    ret->skip = 0;
+    ret->method = method;
+    ret->method_data = NULL;
+    ret->store_ctx = NULL;
+    if ((method->new_item != NULL) && !method->new_item(ret)) {
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
 
 void X509_LOOKUP_free(X509_LOOKUP *ctx)
-	{
-	if (ctx == NULL) return;
-	if (	(ctx->method != NULL) &&
-		(ctx->method->free != NULL))
-		(*ctx->method->free)(ctx);
-	OPENSSL_free(ctx);
-	}
+{
+    if (ctx == NULL)
+        return;
+    if ((ctx->method != NULL) && (ctx->method->free != NULL))
+        (*ctx->method->free) (ctx);
+    OPENSSL_free(ctx);
+}
 
 int X509_LOOKUP_init(X509_LOOKUP *ctx)
-	{
-	if (ctx->method == NULL) return 0;
-	if (ctx->method->init != NULL)
-		return ctx->method->init(ctx);
-	else
-		return 1;
-	}
+{
+    if (ctx->method == NULL)
+        return 0;
+    if (ctx->method->init != NULL)
+        return ctx->method->init(ctx);
+    else
+        return 1;
+}
 
 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
-	{
-	if (ctx->method == NULL) return 0;
-	if (ctx->method->shutdown != NULL)
-		return ctx->method->shutdown(ctx);
-	else
-		return 1;
-	}
+{
+    if (ctx->method == NULL)
+        return 0;
+    if (ctx->method->shutdown != NULL)
+        return ctx->method->shutdown(ctx);
+    else
+        return 1;
+}
 
 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
-	     char **ret)
-	{
-	if (ctx->method == NULL) return -1;
-	if (ctx->method->ctrl != NULL)
-		return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
-	else
-		return 1;
-	}
+                     char **ret)
+{
+    if (ctx->method == NULL)
+        return -1;
+    if (ctx->method->ctrl != NULL)
+        return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
+    else
+        return 1;
+}
 
 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
-	     X509_OBJECT *ret)
-	{
-	if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
-		return X509_LU_FAIL;
-	if (ctx->skip) return 0;
-	return ctx->method->get_by_subject(ctx,type,name,ret);
-	}
+                           X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
+        return X509_LU_FAIL;
+    if (ctx->skip)
+        return 0;
+    return ctx->method->get_by_subject(ctx, type, name, ret);
+}
 
 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
-	     ASN1_INTEGER *serial, X509_OBJECT *ret)
-	{
-	if ((ctx->method == NULL) ||
-		(ctx->method->get_by_issuer_serial == NULL))
-		return X509_LU_FAIL;
-	return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
-	}
+                                 ASN1_INTEGER *serial, X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
+        return X509_LU_FAIL;
+    return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
+}
 
 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
-	     unsigned char *bytes, int len, X509_OBJECT *ret)
-	{
-	if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
-		return X509_LU_FAIL;
-	return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
-	}
+                               unsigned char *bytes, int len,
+                               X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
+        return X509_LU_FAIL;
+    return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
+}
 
 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
-	     X509_OBJECT *ret)
-	{
-	if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
-		return X509_LU_FAIL;
-	return ctx->method->get_by_alias(ctx,type,str,len,ret);
-	}
+                         X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
+        return X509_LU_FAIL;
+    return ctx->method->get_by_alias(ctx, type, str, len, ret);
+}
 
-  
 static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b)
-  	{
- 	int ret;
+{
+    int ret;
 
- 	ret=((*a)->type - (*b)->type);
- 	if (ret) return ret;
- 	switch ((*a)->type)
- 		{
- 	case X509_LU_X509:
- 		ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
- 		break;
- 	case X509_LU_CRL:
- 		ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
- 		break;
-	default:
-		/* abort(); */
-		return 0;
-		}
-	return ret;
-	}
+    ret = ((*a)->type - (*b)->type);
+    if (ret)
+        return ret;
+    switch ((*a)->type) {
+    case X509_LU_X509:
+        ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
+        break;
+    case X509_LU_CRL:
+        ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
+        break;
+    default:
+        /* abort(); */
+        return 0;
+    }
+    return ret;
+}
 
 X509_STORE *X509_STORE_new(void)
-	{
-	X509_STORE *ret;
+{
+    X509_STORE *ret;
 
-	if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
-		return NULL;
-	memset(ret, 0, sizeof(*ret));
-	CRYPTO_MUTEX_init(&ret->objs_lock);
-	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
-	if (ret->objs == NULL)
-		goto err;
-	ret->cache = 1;
-	ret->get_cert_methods = sk_X509_LOOKUP_new_null();
-	if (ret->get_cert_methods == NULL)
-		goto err;
-	ret->param = X509_VERIFY_PARAM_new();
-	if (ret->param == NULL)
-		goto err;
+    if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
+        return NULL;
+    memset(ret, 0, sizeof(*ret));
+    CRYPTO_MUTEX_init(&ret->objs_lock);
+    ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+    if (ret->objs == NULL)
+        goto err;
+    ret->cache = 1;
+    ret->get_cert_methods = sk_X509_LOOKUP_new_null();
+    if (ret->get_cert_methods == NULL)
+        goto err;
+    ret->param = X509_VERIFY_PARAM_new();
+    if (ret->param == NULL)
+        goto err;
 
-	ret->references = 1;
-	return ret;
-err:
-	if (ret)
-		{
-		CRYPTO_MUTEX_cleanup(&ret->objs_lock);
-		if (ret->param)
-			X509_VERIFY_PARAM_free(ret->param);
-		if (ret->get_cert_methods)
-			sk_X509_LOOKUP_free(ret->get_cert_methods);
-		if (ret->objs)
-			sk_X509_OBJECT_free(ret->objs);
-		OPENSSL_free(ret);
-		}
-	return NULL;
-	}
+    ret->references = 1;
+    return ret;
+ err:
+    if (ret) {
+        CRYPTO_MUTEX_cleanup(&ret->objs_lock);
+        if (ret->param)
+            X509_VERIFY_PARAM_free(ret->param);
+        if (ret->get_cert_methods)
+            sk_X509_LOOKUP_free(ret->get_cert_methods);
+        if (ret->objs)
+            sk_X509_OBJECT_free(ret->objs);
+        OPENSSL_free(ret);
+    }
+    return NULL;
+}
+
+void X509_STORE_up_ref(X509_STORE *store)
+{
+    CRYPTO_refcount_inc(&store->references);
+}
 
 static void cleanup(X509_OBJECT *a)
-	{
-	if (a->type == X509_LU_X509)
-		{
-		X509_free(a->data.x509);
-		}
-	else if (a->type == X509_LU_CRL)
-		{
-		X509_CRL_free(a->data.crl);
-		}
-	else
-		{
-		/* abort(); */
-		}
+{
+    if (a == NULL) {
+        return;
+    }
+    if (a->type == X509_LU_X509) {
+        X509_free(a->data.x509);
+    } else if (a->type == X509_LU_CRL) {
+        X509_CRL_free(a->data.crl);
+    } else {
+        /* abort(); */
+    }
 
-	OPENSSL_free(a);
-	}
+    OPENSSL_free(a);
+}
 
 void X509_STORE_free(X509_STORE *vfy)
-	{
-	size_t j;
-	STACK_OF(X509_LOOKUP) *sk;
-	X509_LOOKUP *lu;
+{
+    size_t j;
+    STACK_OF(X509_LOOKUP) *sk;
+    X509_LOOKUP *lu;
 
-	if (vfy == NULL)
-	    return;
+    if (vfy == NULL)
+        return;
 
-	if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
-	  return;
-	}
+    if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
+        return;
+    }
 
-	CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
+    CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
 
-	sk=vfy->get_cert_methods;
-	for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
-		{
-		lu=sk_X509_LOOKUP_value(sk,j);
-		X509_LOOKUP_shutdown(lu);
-		X509_LOOKUP_free(lu);
-		}
-	sk_X509_LOOKUP_free(sk);
-	sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+    sk = vfy->get_cert_methods;
+    for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) {
+        lu = sk_X509_LOOKUP_value(sk, j);
+        X509_LOOKUP_shutdown(lu);
+        X509_LOOKUP_free(lu);
+    }
+    sk_X509_LOOKUP_free(sk);
+    sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
 
-	if (vfy->param)
-		X509_VERIFY_PARAM_free(vfy->param);
-	OPENSSL_free(vfy);
-	}
+    if (vfy->param)
+        X509_VERIFY_PARAM_free(vfy->param);
+    OPENSSL_free(vfy);
+}
 
 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
-	{
-	size_t i;
-	STACK_OF(X509_LOOKUP) *sk;
-	X509_LOOKUP *lu;
+{
+    size_t i;
+    STACK_OF(X509_LOOKUP) *sk;
+    X509_LOOKUP *lu;
 
-	sk=v->get_cert_methods;
-	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
-		{
-		lu=sk_X509_LOOKUP_value(sk,i);
-		if (m == lu->method)
-			{
-			return lu;
-			}
-		}
-	/* a new one */
-	lu=X509_LOOKUP_new(m);
-	if (lu == NULL)
-		return NULL;
-	else
-		{
-		lu->store_ctx=v;
-		if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
-			return lu;
-		else
-			{
-			X509_LOOKUP_free(lu);
-			return NULL;
-			}
-		}
-	}
+    sk = v->get_cert_methods;
+    for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+        lu = sk_X509_LOOKUP_value(sk, i);
+        if (m == lu->method) {
+            return lu;
+        }
+    }
+    /* a new one */
+    lu = X509_LOOKUP_new(m);
+    if (lu == NULL)
+        return NULL;
+    else {
+        lu->store_ctx = v;
+        if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
+            return lu;
+        else {
+            X509_LOOKUP_free(lu);
+            return NULL;
+        }
+    }
+}
 
 int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
-	     X509_OBJECT *ret)
-	{
-	X509_STORE *ctx=vs->ctx;
-	X509_LOOKUP *lu;
-	X509_OBJECT stmp,*tmp;
-	int i,j;
+                              X509_OBJECT *ret)
+{
+    X509_STORE *ctx = vs->ctx;
+    X509_LOOKUP *lu;
+    X509_OBJECT stmp, *tmp;
+    int i, j;
 
-	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
-	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
-	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+    CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+    tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
+    CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
-	if (tmp == NULL || type == X509_LU_CRL)
-		{
-		for (i=vs->current_method; i<(int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
-			{
-			lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
-			j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
-			if (j < 0)
-				{
-				vs->current_method=j;
-				return j;
-				}
-			else if (j)
-				{
-				tmp= &stmp;
-				break;
-				}
-			}
-		vs->current_method=0;
-		if (tmp == NULL)
-			return 0;
-		}
+    if (tmp == NULL || type == X509_LU_CRL) {
+        for (i = vs->current_method;
+             i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+            lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+            j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
+            if (j < 0) {
+                vs->current_method = j;
+                return j;
+            } else if (j) {
+                tmp = &stmp;
+                break;
+            }
+        }
+        vs->current_method = 0;
+        if (tmp == NULL)
+            return 0;
+    }
 
-/*	if (ret->data.ptr != NULL)
-		X509_OBJECT_free_contents(ret); */
+    /*
+     * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret);
+     */
 
-	ret->type=tmp->type;
-	ret->data.ptr=tmp->data.ptr;
+    ret->type = tmp->type;
+    ret->data.ptr = tmp->data.ptr;
 
-	X509_OBJECT_up_ref_count(ret);
+    X509_OBJECT_up_ref_count(ret);
 
-	return 1;
-	}
+    return 1;
+}
 
 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
-	{
-	X509_OBJECT *obj;
-	int ret=1;
+{
+    X509_OBJECT *obj;
+    int ret = 1;
 
-	if (x == NULL) return 0;
-	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	obj->type=X509_LU_X509;
-	obj->data.x509=x;
+    if (x == NULL)
+        return 0;
+    obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    obj->type = X509_LU_X509;
+    obj->data.x509 = x;
 
-	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+    CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
 
-	X509_OBJECT_up_ref_count(obj);
+    X509_OBJECT_up_ref_count(obj);
 
-	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
-		{
-		X509_OBJECT_free_contents(obj);
-		OPENSSL_free(obj);
-		OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
-		ret=0;
-		} 
-	else sk_X509_OBJECT_push(ctx->objs, obj);
+    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+        X509_OBJECT_free_contents(obj);
+        OPENSSL_free(obj);
+        OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+        ret = 0;
+    } else
+        sk_X509_OBJECT_push(ctx->objs, obj);
 
-	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+    CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
-	return ret;
-	}
+    return ret;
+}
 
 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
-	{
-	X509_OBJECT *obj;
-	int ret=1;
+{
+    X509_OBJECT *obj;
+    int ret = 1;
 
-	if (x == NULL) return 0;
-	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	obj->type=X509_LU_CRL;
-	obj->data.crl=x;
+    if (x == NULL)
+        return 0;
+    obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    obj->type = X509_LU_CRL;
+    obj->data.crl = x;
 
-	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+    CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
 
-	X509_OBJECT_up_ref_count(obj);
+    X509_OBJECT_up_ref_count(obj);
 
-	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
-		{
-		X509_OBJECT_free_contents(obj);
-		OPENSSL_free(obj);
-		OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
-		ret=0;
-		}
-	else sk_X509_OBJECT_push(ctx->objs, obj);
+    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+        X509_OBJECT_free_contents(obj);
+        OPENSSL_free(obj);
+        OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+        ret = 0;
+    } else
+        sk_X509_OBJECT_push(ctx->objs, obj);
 
-	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+    CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
-	return ret;
-	}
+    return ret;
+}
 
 void X509_OBJECT_up_ref_count(X509_OBJECT *a)
-	{
-	switch (a->type)
-		{
-	case X509_LU_X509:
-		X509_up_ref(a->data.x509);
-		break;
-	case X509_LU_CRL:
-		X509_CRL_up_ref(a->data.crl);
-		break;
-		}
-	}
+{
+    switch (a->type) {
+    case X509_LU_X509:
+        X509_up_ref(a->data.x509);
+        break;
+    case X509_LU_CRL:
+        X509_CRL_up_ref(a->data.crl);
+        break;
+    }
+}
 
 void X509_OBJECT_free_contents(X509_OBJECT *a)
-	{
-	switch (a->type)
-		{
-	case X509_LU_X509:
-		X509_free(a->data.x509);
-		break;
-	case X509_LU_CRL:
-		X509_CRL_free(a->data.crl);
-		break;
-		}
-	}
+{
+    switch (a->type) {
+    case X509_LU_X509:
+        X509_free(a->data.x509);
+        break;
+    case X509_LU_CRL:
+        X509_CRL_free(a->data.crl);
+        break;
+    }
+}
 
 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
-	     X509_NAME *name, int *pnmatch)
-	{
-	X509_OBJECT stmp;
-	X509 x509_s;
-	X509_CINF cinf_s;
-	X509_CRL crl_s;
-	X509_CRL_INFO crl_info_s;
+                               X509_NAME *name, int *pnmatch)
+{
+    X509_OBJECT stmp;
+    X509 x509_s;
+    X509_CINF cinf_s;
+    X509_CRL crl_s;
+    X509_CRL_INFO crl_info_s;
 
-	stmp.type=type;
-	switch (type)
-		{
-	case X509_LU_X509:
-		stmp.data.x509= &x509_s;
-		x509_s.cert_info= &cinf_s;
-		cinf_s.subject=name;
-		break;
-	case X509_LU_CRL:
-		stmp.data.crl= &crl_s;
-		crl_s.crl= &crl_info_s;
-		crl_info_s.issuer=name;
-		break;
-	default:
-		/* abort(); */
-		return -1;
-		}
+    stmp.type = type;
+    switch (type) {
+    case X509_LU_X509:
+        stmp.data.x509 = &x509_s;
+        x509_s.cert_info = &cinf_s;
+        cinf_s.subject = name;
+        break;
+    case X509_LU_CRL:
+        stmp.data.crl = &crl_s;
+        crl_s.crl = &crl_info_s;
+        crl_info_s.issuer = name;
+        break;
+    default:
+        /* abort(); */
+        return -1;
+    }
 
-	size_t idx;
-	if (!sk_X509_OBJECT_find(h, &idx, &stmp))
-		return -1;
+    size_t idx;
+    if (!sk_X509_OBJECT_find(h, &idx, &stmp))
+        return -1;
 
-	if (pnmatch != NULL)
-		{
-		int tidx;
-		const X509_OBJECT *tobj, *pstmp;
-		*pnmatch = 1;
-		pstmp = &stmp;
-		for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++)
-			{
-			tobj = sk_X509_OBJECT_value(h, tidx);
-			if (x509_object_cmp(&tobj, &pstmp))
-				break;
-			(*pnmatch)++;
-			}
-		}
+    if (pnmatch != NULL) {
+        int tidx;
+        const X509_OBJECT *tobj, *pstmp;
+        *pnmatch = 1;
+        pstmp = &stmp;
+        for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) {
+            tobj = sk_X509_OBJECT_value(h, tidx);
+            if (x509_object_cmp(&tobj, &pstmp))
+                break;
+            (*pnmatch)++;
+        }
+    }
 
-	return idx;
-	}
-
+    return idx;
+}
 
 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
-	     X509_NAME *name)
-	{
-	return x509_object_idx_cnt(h, type, name, NULL);
-	}
+                               X509_NAME *name)
+{
+    return x509_object_idx_cnt(h, type, name, NULL);
+}
 
-X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
-	     X509_NAME *name)
-	{
-	int idx;
-	idx = X509_OBJECT_idx_by_subject(h, type, name);
-	if (idx==-1) return NULL;
-	return sk_X509_OBJECT_value(h, idx);
-	}
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+                                             int type, X509_NAME *name)
+{
+    int idx;
+    idx = X509_OBJECT_idx_by_subject(h, type, name);
+    if (idx == -1)
+        return NULL;
+    return sk_X509_OBJECT_value(h, idx);
+}
 
-STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
-	{
-	int i, idx, cnt;
-	STACK_OF(X509) *sk;
-	X509 *x;
-	X509_OBJECT *obj;
-	sk = sk_X509_new_null();
-	if (sk == NULL)
-		return NULL;
-	CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
-	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
-	if (idx < 0)
-		{
-		/* Nothing found in cache: do lookup to possibly add new
-		 * objects to cache
-		 */
-		X509_OBJECT xobj;
-		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_MUTEX_lock_write(&ctx->ctx->objs_lock);
-		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
-		if (idx < 0)
-			{
-			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-			sk_X509_free(sk);
-			return NULL;
-			}
-		}
-	for (i = 0; i < cnt; i++, idx++)
-		{
-		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
-		x = obj->data.x509;
-		if (!sk_X509_push(sk, X509_up_ref(x)))
-			{
-			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-			X509_free(x);
-			sk_X509_pop_free(sk, X509_free);
-			return NULL;
-			}
-		}
-	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-	return sk;
+STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    int i, idx, cnt;
+    STACK_OF(X509) *sk;
+    X509 *x;
+    X509_OBJECT *obj;
+    sk = sk_X509_new_null();
+    if (sk == NULL)
+        return NULL;
+    CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
+    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+    if (idx < 0) {
+        /*
+         * Nothing found in cache: do lookup to possibly add new objects to
+         * cache
+         */
+        X509_OBJECT xobj;
+        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_MUTEX_lock_write(&ctx->ctx->objs_lock);
+        idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+        if (idx < 0) {
+            CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+            sk_X509_free(sk);
+            return NULL;
+        }
+    }
+    for (i = 0; i < cnt; i++, idx++) {
+        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        x = obj->data.x509;
+        if (!sk_X509_push(sk, X509_up_ref(x))) {
+            CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+            X509_free(x);
+            sk_X509_pop_free(sk, X509_free);
+            return NULL;
+        }
+    }
+    CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+    return sk;
 
-	}
+}
 
-STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
-	{
-	int i, idx, cnt;
-	STACK_OF(X509_CRL) *sk;
-	X509_CRL *x;
-	X509_OBJECT *obj, xobj;
-	sk = sk_X509_CRL_new_null();
-	if (sk == NULL)
-		return NULL;
+STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    int i, idx, cnt;
+    STACK_OF(X509_CRL) *sk;
+    X509_CRL *x;
+    X509_OBJECT *obj, xobj;
+    sk = sk_X509_CRL_new_null();
+    if (sk == NULL)
+        return NULL;
 
-	/* Always do lookup to possibly add new CRLs to cache. */
-	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_MUTEX_lock_write(&ctx->ctx->objs_lock);
-	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
-	if (idx < 0)
-		{
-		CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-		sk_X509_CRL_free(sk);
-		return NULL;
-		}
+    /* Always do lookup to possibly add new CRLs to cache. */
+    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_MUTEX_lock_write(&ctx->ctx->objs_lock);
+    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+    if (idx < 0) {
+        CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+        sk_X509_CRL_free(sk);
+        return NULL;
+    }
 
-	for (i = 0; i < cnt; i++, idx++)
-		{
-		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
-		x = obj->data.crl;
-		X509_CRL_up_ref(x);
-		if (!sk_X509_CRL_push(sk, x))
-			{
-			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-			X509_CRL_free(x);
-			sk_X509_CRL_pop_free(sk, X509_CRL_free);
-			return NULL;
-			}
-		}
-	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-	return sk;
-	}
+    for (i = 0; i < cnt; i++, idx++) {
+        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        x = obj->data.crl;
+        X509_CRL_up_ref(x);
+        if (!sk_X509_CRL_push(sk, x)) {
+            CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+            X509_CRL_free(x);
+            sk_X509_CRL_pop_free(sk, X509_CRL_free);
+            return NULL;
+        }
+    }
+    CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+    return sk;
+}
 
-X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
-	{
-	size_t idx, i;
-	X509_OBJECT *obj;
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+                                        X509_OBJECT *x)
+{
+    size_t idx, i;
+    X509_OBJECT *obj;
 
-	if (!sk_X509_OBJECT_find(h, &idx, x)) {
-		return NULL;
-	}
-	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
-		return sk_X509_OBJECT_value(h, idx);
-	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
-		{
-		obj = sk_X509_OBJECT_value(h, i);
-		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
-			return NULL;
-		if (x->type == X509_LU_X509)
-			{
-			if (!X509_cmp(obj->data.x509, x->data.x509))
-				return obj;
-			}
-		else if (x->type == X509_LU_CRL)
-			{
-			if (!X509_CRL_match(obj->data.crl, x->data.crl))
-				return obj;
-			}
-		else
-			return obj;
-		}
-	return NULL;
-	}
+    if (!sk_X509_OBJECT_find(h, &idx, x)) {
+        return NULL;
+    }
+    if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+        return sk_X509_OBJECT_value(h, idx);
+    for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
+        obj = sk_X509_OBJECT_value(h, i);
+        if (x509_object_cmp
+            ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
+            return NULL;
+        if (x->type == X509_LU_X509) {
+            if (!X509_cmp(obj->data.x509, x->data.x509))
+                return obj;
+        } else if (x->type == X509_LU_CRL) {
+            if (!X509_CRL_match(obj->data.crl, x->data.crl))
+                return obj;
+        } else
+            return obj;
+    }
+    return NULL;
+}
 
-
-/* Try to get issuer certificate from store. Due to limitations
- * of the API this can only retrieve a single certificate matching
- * a given subject name. However it will fill the cache with all
- * matching certificates, so we can examine the cache for all
- * matches.
- *
- * Return values are:
- *  1 lookup successful.
- *  0 certificate not found.
- * -1 some other error.
+/*
+ * Try to get issuer certificate from store. Due to limitations of the API
+ * this can only retrieve a single certificate matching a given subject name.
+ * However it will fill the cache with all matching certificates, so we can
+ * examine the cache for all matches. Return values are: 1 lookup
+ * successful.  0 certificate not found. -1 some other error.
  */
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
-	{
-	X509_NAME *xn;
-	X509_OBJECT obj, *pobj;
-	int ok, idx, ret;
-	size_t i;
-	xn=X509_get_issuer_name(x);
-	ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
-	if (ok != X509_LU_X509)
-		{
-		if (ok == X509_LU_RETRY)
-			{
-			X509_OBJECT_free_contents(&obj);
-			OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
-			return -1;
-			}
-		else if (ok != X509_LU_FAIL)
-			{
-			X509_OBJECT_free_contents(&obj);
-			/* not good :-(, break anyway */
-			return -1;
-			}
-		return 0;
-		}
-	/* If certificate matches all OK */
-	if (ctx->check_issued(ctx, x, obj.data.x509))
-		{
-		*issuer = obj.data.x509;
-		return 1;
-		}
-	X509_OBJECT_free_contents(&obj);
+{
+    X509_NAME *xn;
+    X509_OBJECT obj, *pobj;
+    int ok, idx, ret;
+    size_t i;
+    xn = X509_get_issuer_name(x);
+    ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
+    if (ok != X509_LU_X509) {
+        if (ok == X509_LU_RETRY) {
+            X509_OBJECT_free_contents(&obj);
+            OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
+            return -1;
+        } else if (ok != X509_LU_FAIL) {
+            X509_OBJECT_free_contents(&obj);
+            /* not good :-(, break anyway */
+            return -1;
+        }
+        return 0;
+    }
+    /* If certificate matches all OK */
+    if (ctx->check_issued(ctx, x, obj.data.x509)) {
+        *issuer = obj.data.x509;
+        return 1;
+    }
+    X509_OBJECT_free_contents(&obj);
 
-	/* Else find index of first cert accepted by 'check_issued' */
-	ret = 0;
-	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 */
-		{
-		/* Look through all matching certs for suitable issuer */
-		for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
-			{
-			pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
-			/* See if we've run past the matches */
-			if (pobj->type != X509_LU_X509)
-				break;
-			if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
-				break;
-			if (ctx->check_issued(ctx, x, pobj->data.x509))
-				{
-				*issuer = pobj->data.x509;
-				X509_OBJECT_up_ref_count(pobj);
-				ret = 1;
-				break;
-				}
-			}
-		}
-	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
-	return ret;
-	}
+    /* Else find index of first cert accepted by 'check_issued' */
+    ret = 0;
+    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 */
+        /* Look through all matching certs for suitable issuer */
+        for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
+            pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+            /* See if we've run past the matches */
+            if (pobj->type != X509_LU_X509)
+                break;
+            if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+                break;
+            if (ctx->check_issued(ctx, x, pobj->data.x509)) {
+                *issuer = pobj->data.x509;
+                X509_OBJECT_up_ref_count(pobj);
+                ret = 1;
+                break;
+            }
+        }
+    }
+    CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+    return ret;
+}
 
 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
-	{
-	return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
-	}
+{
+    return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
 
 int X509_STORE_set_depth(X509_STORE *ctx, int depth)
-	{
-	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
-	return 1;
-	}
+{
+    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+    return 1;
+}
 
 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
-	{
-	return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
-	}
+{
+    return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+}
 
 int X509_STORE_set_trust(X509_STORE *ctx, int trust)
-	{
-	return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
-	}
+{
+    return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+}
 
 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
-	{
-	return X509_VERIFY_PARAM_set1(ctx->param, param);
-	}
+{
+    return X509_VERIFY_PARAM_set1(ctx->param, param);
+}
 
 void X509_STORE_set_verify_cb(X509_STORE *ctx,
-				  int (*verify_cb)(int, X509_STORE_CTX *))
-	{
-	ctx->verify_cb = verify_cb;
-	}
+                              int (*verify_cb) (int, X509_STORE_CTX *))
+{
+    ctx->verify_cb = verify_cb;
+}
 
 void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
-		STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm))
-	{
-	ctx->lookup_crls = cb;
-	}
+                                   STACK_OF (X509_CRL) *
+                                   (*cb) (X509_STORE_CTX *ctx, X509_NAME *nm))
+{
+    ctx->lookup_crls = cb;
+}
 
 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
-	{
-	return ctx->ctx;
-	}
+{
+    return ctx->ctx;
+}
diff --git a/src/crypto/x509/x509_obj.c b/src/crypto/x509/x509_obj.c
index b6f0816..641e308 100644
--- a/src/crypto/x509/x509_obj.c
+++ b/src/crypto/x509/x509_obj.c
@@ -64,128 +64,117 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
-	{
-	X509_NAME_ENTRY *ne;
-	size_t i;
-	int n,lold,l,l1,l2,num,j,type;
-	const char *s;
-	char *p;
-	unsigned char *q;
-	BUF_MEM *b=NULL;
-	static const char hex[17]="0123456789ABCDEF";
-	int gs_doit[4];
-	char tmp_buf[80];
+{
+    X509_NAME_ENTRY *ne;
+    size_t i;
+    int n, lold, l, l1, l2, num, j, type;
+    const char *s;
+    char *p;
+    unsigned char *q;
+    BUF_MEM *b = NULL;
+    static const char hex[17] = "0123456789ABCDEF";
+    int gs_doit[4];
+    char tmp_buf[80];
 
-	if (buf == NULL)
-		{
-		if ((b=BUF_MEM_new()) == NULL) goto err;
-		if (!BUF_MEM_grow(b,200)) goto err;
-		b->data[0]='\0';
-		len=200;
-		}
-	if (a == NULL)
-	    {
-	    if(b)
-		{
-		buf=b->data;
-		OPENSSL_free(b);
-		}
-	    strncpy(buf,"NO X509_NAME",len);
-	    buf[len-1]='\0';
-	    return buf;
-	    }
+    if (buf == NULL) {
+        if ((b = BUF_MEM_new()) == NULL)
+            goto err;
+        if (!BUF_MEM_grow(b, 200))
+            goto err;
+        b->data[0] = '\0';
+        len = 200;
+    }
+    if (a == NULL) {
+        if (b) {
+            buf = b->data;
+            OPENSSL_free(b);
+        }
+        strncpy(buf, "NO X509_NAME", len);
+        buf[len - 1] = '\0';
+        return buf;
+    }
 
-	len--; /* space for '\0' */
-	l=0;
-	for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++)
-		{
-		ne=sk_X509_NAME_ENTRY_value(a->entries,i);
-		n=OBJ_obj2nid(ne->object);
-		if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL))
-			{
-			i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object);
-			s=tmp_buf;
-			}
-		l1=strlen(s);
+    len--;                      /* space for '\0' */
+    l = 0;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        ne = sk_X509_NAME_ENTRY_value(a->entries, i);
+        n = OBJ_obj2nid(ne->object);
+        if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
+            i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
+            s = tmp_buf;
+        }
+        l1 = strlen(s);
 
-		type=ne->value->type;
-		num=ne->value->length;
-		q=ne->value->data;
+        type = ne->value->type;
+        num = ne->value->length;
+        q = ne->value->data;
 
-		if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0))
-			{
-			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=0;
-			for (j=0; j<num; j++)
-				if (q[j] != 0) gs_doit[j&3]=1;
+        if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
+            gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
+            for (j = 0; j < num; j++)
+                if (q[j] != 0)
+                    gs_doit[j & 3] = 1;
 
-			if (gs_doit[0]|gs_doit[1]|gs_doit[2])
-				gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
-			else
-				{
-				gs_doit[0]=gs_doit[1]=gs_doit[2]=0;
-				gs_doit[3]=1;
-				}
-			}
-		else
-			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
+            if (gs_doit[0] | gs_doit[1] | gs_doit[2])
+                gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+            else {
+                gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
+                gs_doit[3] = 1;
+            }
+        } else
+            gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
 
-		for (l2=j=0; j<num; j++)
-			{
-			if (!gs_doit[j&3]) continue;
-			l2++;
-			if ((q[j] < ' ') || (q[j] > '~')) l2+=3;
-			}
+        for (l2 = j = 0; j < num; j++) {
+            if (!gs_doit[j & 3])
+                continue;
+            l2++;
+            if ((q[j] < ' ') || (q[j] > '~'))
+                l2 += 3;
+        }
 
-		lold=l;
-		l+=1+l1+1+l2;
-		if (b != NULL)
-			{
-			if (!BUF_MEM_grow(b,l+1)) goto err;
-			p= &(b->data[lold]);
-			}
-		else if (l > len)
-			{
-			break;
-			}
-		else
-			p= &(buf[lold]);
-		*(p++)='/';
-		memcpy(p,s,(unsigned int)l1); p+=l1;
-		*(p++)='=';
+        lold = l;
+        l += 1 + l1 + 1 + l2;
+        if (b != NULL) {
+            if (!BUF_MEM_grow(b, l + 1))
+                goto err;
+            p = &(b->data[lold]);
+        } else if (l > len) {
+            break;
+        } else
+            p = &(buf[lold]);
+        *(p++) = '/';
+        memcpy(p, s, (unsigned int)l1);
+        p += l1;
+        *(p++) = '=';
 
-		q=ne->value->data;
+        q = ne->value->data;
 
-		for (j=0; j<num; j++)
-			{
-			if (!gs_doit[j&3]) continue;
-			n=q[j];
-			if ((n < ' ') || (n > '~'))
-				{
-				*(p++)='\\';
-				*(p++)='x';
-				*(p++)=hex[(n>>4)&0x0f];
-				*(p++)=hex[n&0x0f];
-				}
-			else
-				*(p++)=n;
-			}
-		*p='\0';
-		}
-	if (b != NULL)
-		{
-		p=b->data;
-		OPENSSL_free(b);
-		}
-	else
-		p=buf;
-	if (i == 0)
-		*p = '\0';
-	return(p);
-err:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	if (b != NULL) BUF_MEM_free(b);
-	return(NULL);
-	}
-
+        for (j = 0; j < num; j++) {
+            if (!gs_doit[j & 3])
+                continue;
+            n = q[j];
+            if ((n < ' ') || (n > '~')) {
+                *(p++) = '\\';
+                *(p++) = 'x';
+                *(p++) = hex[(n >> 4) & 0x0f];
+                *(p++) = hex[n & 0x0f];
+            } else
+                *(p++) = n;
+        }
+        *p = '\0';
+    }
+    if (b != NULL) {
+        p = b->data;
+        OPENSSL_free(b);
+    } else
+        p = buf;
+    if (i == 0)
+        *p = '\0';
+    return (p);
+ err:
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    if (b != NULL)
+        BUF_MEM_free(b);
+    return (NULL);
+}
diff --git a/src/crypto/x509/x509_r2x.c b/src/crypto/x509/x509_r2x.c
index 85979ac..83951a2 100644
--- a/src/crypto/x509/x509_r2x.c
+++ b/src/crypto/x509/x509_r2x.c
@@ -63,51 +63,51 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
-	{
-	X509 *ret=NULL;
-	X509_CINF *xi=NULL;
-	X509_NAME *xn;
+{
+    X509 *ret = NULL;
+    X509_CINF *xi = NULL;
+    X509_NAME *xn;
 
-	if ((ret=X509_new()) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    if ((ret = X509_new()) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	/* duplicate the request */
-	xi=ret->cert_info;
+    /* duplicate the request */
+    xi = ret->cert_info;
 
-	if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0)
-		{
-		if ((xi->version=M_ASN1_INTEGER_new()) == NULL) goto err;
-		if (!ASN1_INTEGER_set(xi->version,2)) goto err;
-/*		xi->extensions=ri->attributes; <- bad, should not ever be done
-		ri->attributes=NULL; */
-		}
+    if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
+        if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(xi->version, 2))
+            goto err;
+        /*
+         * xi->extensions=ri->attributes; <- bad, should not ever be done
+         * ri->attributes=NULL;
+         */
+    }
 
-	xn=X509_REQ_get_subject_name(r);
-	if (X509_set_subject_name(ret,X509_NAME_dup(xn)) == 0)
-		goto err;
-	if (X509_set_issuer_name(ret,X509_NAME_dup(xn)) == 0)
-		goto err;
+    xn = X509_REQ_get_subject_name(r);
+    if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
+        goto err;
+    if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
+        goto err;
 
-	if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL)
-		goto err;
-	if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL)
-		goto err;
+    if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
+        goto err;
+    if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
+        NULL)
+        goto err;
 
-	X509_set_pubkey(ret,X509_REQ_get_pubkey(r));
+    X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
 
-	if (!X509_sign(ret,pkey,EVP_md5()))
-		goto err;
-	if (0)
-		{
-err:
-		X509_free(ret);
-		ret=NULL;
-		}
-	return(ret);
-	}
-
+    if (!X509_sign(ret, pkey, EVP_md5()))
+        goto err;
+    if (0) {
+ err:
+        X509_free(ret);
+        ret = NULL;
+    }
+    return (ret);
+}
diff --git a/src/crypto/x509/x509_req.c b/src/crypto/x509/x509_req.c
index 01c5113..69bc6f1 100644
--- a/src/crypto/x509/x509_req.c
+++ b/src/crypto/x509/x509_req.c
@@ -66,250 +66,257 @@
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 
-
 X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
-	{
-	X509_REQ *ret;
-	X509_REQ_INFO *ri;
-	int i;
-	EVP_PKEY *pktmp;
+{
+    X509_REQ *ret;
+    X509_REQ_INFO *ri;
+    int i;
+    EVP_PKEY *pktmp;
 
-	ret=X509_REQ_new();
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    ret = X509_REQ_new();
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	ri=ret->req_info;
+    ri = ret->req_info;
 
-	ri->version->length=1;
-	ri->version->data=(unsigned char *)OPENSSL_malloc(1);
-	if (ri->version->data == NULL) goto err;
-	ri->version->data[0]=0; /* version == 0 */
+    ri->version->length = 1;
+    ri->version->data = (unsigned char *)OPENSSL_malloc(1);
+    if (ri->version->data == NULL)
+        goto err;
+    ri->version->data[0] = 0;   /* version == 0 */
 
-	if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
-		goto err;
+    if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
+        goto err;
 
-	pktmp = X509_get_pubkey(x);
-	if (pktmp == NULL)
-		goto err;
-	i=X509_REQ_set_pubkey(ret,pktmp);
-	EVP_PKEY_free(pktmp);
-	if (!i) goto err;
+    pktmp = X509_get_pubkey(x);
+    if (pktmp == NULL)
+        goto err;
+    i = X509_REQ_set_pubkey(ret, pktmp);
+    EVP_PKEY_free(pktmp);
+    if (!i)
+        goto err;
 
-	if (pkey != NULL)
-		{
-		if (!X509_REQ_sign(ret,pkey,md))
-			goto err;
-		}
-	return(ret);
-err:
-	X509_REQ_free(ret);
-	return(NULL);
-	}
+    if (pkey != NULL) {
+        if (!X509_REQ_sign(ret, pkey, md))
+            goto err;
+    }
+    return (ret);
+ err:
+    X509_REQ_free(ret);
+    return (NULL);
+}
 
 EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
-	{
-	if ((req == NULL) || (req->req_info == NULL))
-		return(NULL);
-	return(X509_PUBKEY_get(req->req_info->pubkey));
-	}
+{
+    if ((req == NULL) || (req->req_info == NULL))
+        return (NULL);
+    return (X509_PUBKEY_get(req->req_info->pubkey));
+}
 
 int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
-	{
-	EVP_PKEY *xk=NULL;
-	int ok=0;
+{
+    EVP_PKEY *xk = NULL;
+    int ok = 0;
 
-	xk=X509_REQ_get_pubkey(x);
-	switch (EVP_PKEY_cmp(xk, k))
-		{
-	case 1:
-		ok=1;
-		break;
-	case 0:
-		OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
-		break;
-	case -1:
-		OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
-		break;
-	case -2:
-		if (k->type == EVP_PKEY_EC)
-			{
-			OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
-			break;
-			}
-		if (k->type == EVP_PKEY_DH)
-			{
-			/* No idea */
-			OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
-			break;
-			}
-	        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
-		}
+    xk = X509_REQ_get_pubkey(x);
+    switch (EVP_PKEY_cmp(xk, k)) {
+    case 1:
+        ok = 1;
+        break;
+    case 0:
+        OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+        break;
+    case -1:
+        OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+        break;
+    case -2:
+        if (k->type == EVP_PKEY_EC) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
+            break;
+        }
+        if (k->type == EVP_PKEY_DH) {
+            /* No idea */
+            OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
+            break;
+        }
+        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+    }
 
-	EVP_PKEY_free(xk);
-	return(ok);
-	}
+    EVP_PKEY_free(xk);
+    return (ok);
+}
 
-/* It seems several organisations had the same idea of including a list of
+/*
+ * It seems several organisations had the same idea of including a list of
  * extensions in a certificate request. There are at least two OIDs that are
  * used and there may be more: so the list is configurable.
  */
 
-static const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
+static const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef };
 
 static const int *ext_nids = ext_nid_list;
 
 int X509_REQ_extension_nid(int req_nid)
 {
-	int i, nid;
-	for(i = 0; ; i++) {
-		nid = ext_nids[i];
-		if(nid == NID_undef) return 0;
-		else if (req_nid == nid) return 1;
-	}
+    int i, nid;
+    for (i = 0;; i++) {
+        nid = ext_nids[i];
+        if (nid == NID_undef)
+            return 0;
+        else if (req_nid == nid)
+            return 1;
+    }
 }
 
 const int *X509_REQ_get_extension_nids(void)
 {
-	return ext_nids;
+    return ext_nids;
 }
-	
+
 void X509_REQ_set_extension_nids(const int *nids)
 {
-	ext_nids = nids;
+    ext_nids = nids;
 }
 
 STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
-	{
-	X509_ATTRIBUTE *attr;
-	ASN1_TYPE *ext = NULL;
-	int idx;
-	const int *pnid;
-	const unsigned char *p;
+{
+    X509_ATTRIBUTE *attr;
+    ASN1_TYPE *ext = NULL;
+    int idx;
+    const int *pnid;
+    const unsigned char *p;
 
-	if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
-		return(NULL);
-	for (pnid = ext_nids; *pnid != NID_undef; pnid++)
-		{
-		idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
-		if (idx == -1)
-			continue;
-		attr = X509_REQ_get_attr(req, idx);
-		if(attr->single) ext = attr->value.single;
-		else if(sk_ASN1_TYPE_num(attr->value.set))
-			ext = sk_ASN1_TYPE_value(attr->value.set, 0);
-		break;
-		}
-	if(!ext || (ext->type != V_ASN1_SEQUENCE))
-		return NULL;
-	p = ext->value.sequence->data;
-	return (STACK_OF(X509_EXTENSION) *)
-		ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
-				ASN1_ITEM_rptr(X509_EXTENSIONS));
+    if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
+        return (NULL);
+    for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
+        idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
+        if (idx == -1)
+            continue;
+        attr = X509_REQ_get_attr(req, idx);
+        if (attr->single)
+            ext = attr->value.single;
+        else if (sk_ASN1_TYPE_num(attr->value.set))
+            ext = sk_ASN1_TYPE_value(attr->value.set, 0);
+        break;
+    }
+    if (!ext || (ext->type != V_ASN1_SEQUENCE))
+        return NULL;
+    p = ext->value.sequence->data;
+    return (STACK_OF(X509_EXTENSION) *)
+        ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
+                      ASN1_ITEM_rptr(X509_EXTENSIONS));
 }
 
-/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
+/*
+ * Add a STACK_OF extensions to a certificate request: allow alternative OIDs
  * in case we want to create a non standard one.
  */
 
 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
-				int nid)
+                                int nid)
 {
-	ASN1_TYPE *at = NULL;
-	X509_ATTRIBUTE *attr = NULL;
-	if(!(at = ASN1_TYPE_new()) ||
-		!(at->value.sequence = ASN1_STRING_new())) goto err;
+    ASN1_TYPE *at = NULL;
+    X509_ATTRIBUTE *attr = NULL;
+    if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new()))
+        goto err;
 
-	at->type = V_ASN1_SEQUENCE;
-	/* Generate encoding of extensions */
-	at->value.sequence->length = 
-			ASN1_item_i2d((ASN1_VALUE *)exts,
-				&at->value.sequence->data,
-				ASN1_ITEM_rptr(X509_EXTENSIONS));
-	if(!(attr = X509_ATTRIBUTE_new())) goto err;
-	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
-	if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
-	at = NULL;
-	attr->single = 0;
-	attr->object = (ASN1_OBJECT*) OBJ_nid2obj(nid);
-	if (!req->req_info->attributes)
-		{
-		if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
-			goto err;
-		}
-	if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
-	return 1;
-	err:
-	X509_ATTRIBUTE_free(attr);
-	ASN1_TYPE_free(at);
-	return 0;
+    at->type = V_ASN1_SEQUENCE;
+    /* Generate encoding of extensions */
+    at->value.sequence->length =
+        ASN1_item_i2d((ASN1_VALUE *)exts,
+                      &at->value.sequence->data,
+                      ASN1_ITEM_rptr(X509_EXTENSIONS));
+    if (!(attr = X509_ATTRIBUTE_new()))
+        goto err;
+    if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
+        goto err;
+    if (!sk_ASN1_TYPE_push(attr->value.set, at))
+        goto err;
+    at = NULL;
+    attr->single = 0;
+    attr->object = (ASN1_OBJECT *)OBJ_nid2obj(nid);
+    if (!req->req_info->attributes) {
+        if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
+            goto err;
+    }
+    if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
+        goto err;
+    return 1;
+ err:
+    X509_ATTRIBUTE_free(attr);
+    ASN1_TYPE_free(at);
+    return 0;
 }
+
 /* This is the normal usage: use the "official" OID */
 int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
 {
-	return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
+    return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
 }
 
 /* Request attribute functions */
 
 int X509_REQ_get_attr_count(const X509_REQ *req)
 {
-	return X509at_get_attr_count(req->req_info->attributes);
+    return X509at_get_attr_count(req->req_info->attributes);
 }
 
-int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
-			  int lastpos)
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
 {
-	return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
+    return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
 }
 
 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
-			  int lastpos)
+                             int lastpos)
 {
-	return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
+    return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
 }
 
 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
 {
-	return X509at_get_attr(req->req_info->attributes, loc);
+    return X509at_get_attr(req->req_info->attributes, loc);
 }
 
 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
 {
-	return X509at_delete_attr(req->req_info->attributes, loc);
+    return X509at_delete_attr(req->req_info->attributes, loc);
 }
 
 int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
 {
-	if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
-	return 0;
+    if (X509at_add1_attr(&req->req_info->attributes, attr))
+        return 1;
+    return 0;
 }
 
 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
-			const ASN1_OBJECT *obj, int type,
-			const unsigned char *bytes, int len)
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len)
 {
-	if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
-				type, bytes, len)) return 1;
-	return 0;
+    if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
+                                type, bytes, len))
+        return 1;
+    return 0;
 }
 
 int X509_REQ_add1_attr_by_NID(X509_REQ *req,
-			int nid, int type,
-			const unsigned char *bytes, int len)
+                              int nid, int type,
+                              const unsigned char *bytes, int len)
 {
-	if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
-				type, bytes, len)) return 1;
-	return 0;
+    if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
+                                type, bytes, len))
+        return 1;
+    return 0;
 }
 
 int X509_REQ_add1_attr_by_txt(X509_REQ *req,
-			const char *attrname, int type,
-			const unsigned char *bytes, int len)
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len)
 {
-	if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
-				type, bytes, len)) return 1;
-	return 0;
+    if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
+                                type, bytes, len))
+        return 1;
+    return 0;
 }
diff --git a/src/crypto/x509/x509_set.c b/src/crypto/x509/x509_set.c
index 06658b0..42e9cf0 100644
--- a/src/crypto/x509/x509_set.c
+++ b/src/crypto/x509/x509_set.c
@@ -60,95 +60,90 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 int X509_set_version(X509 *x, long version)
-	{
-	if (x == NULL) return(0);
-	if (version == 0)
-		{
-		M_ASN1_INTEGER_free(x->cert_info->version);
-		x->cert_info->version = NULL;
-		return(1);
-		}
-	if (x->cert_info->version == NULL)
-		{
-		if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL)
-			return(0);
-		}
-	return(ASN1_INTEGER_set(x->cert_info->version,version));
-	}
+{
+    if (x == NULL)
+        return (0);
+    if (version == 0) {
+        M_ASN1_INTEGER_free(x->cert_info->version);
+        x->cert_info->version = NULL;
+        return (1);
+    }
+    if (x->cert_info->version == NULL) {
+        if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
+            return (0);
+    }
+    return (ASN1_INTEGER_set(x->cert_info->version, version));
+}
 
 int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
-	{
-	ASN1_INTEGER *in;
+{
+    ASN1_INTEGER *in;
 
-	if (x == NULL) return(0);
-	in=x->cert_info->serialNumber;
-	if (in != serial)
-		{
-		in=M_ASN1_INTEGER_dup(serial);
-		if (in != NULL)
-			{
-			M_ASN1_INTEGER_free(x->cert_info->serialNumber);
-			x->cert_info->serialNumber=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if (x == NULL)
+        return (0);
+    in = x->cert_info->serialNumber;
+    if (in != serial) {
+        in = M_ASN1_INTEGER_dup(serial);
+        if (in != NULL) {
+            M_ASN1_INTEGER_free(x->cert_info->serialNumber);
+            x->cert_info->serialNumber = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_set_issuer_name(X509 *x, X509_NAME *name)
-	{
-	if ((x == NULL) || (x->cert_info == NULL)) return(0);
-	return(X509_NAME_set(&x->cert_info->issuer,name));
-	}
+{
+    if ((x == NULL) || (x->cert_info == NULL))
+        return (0);
+    return (X509_NAME_set(&x->cert_info->issuer, name));
+}
 
 int X509_set_subject_name(X509 *x, X509_NAME *name)
-	{
-	if ((x == NULL) || (x->cert_info == NULL)) return(0);
-	return(X509_NAME_set(&x->cert_info->subject,name));
-	}
+{
+    if ((x == NULL) || (x->cert_info == NULL))
+        return (0);
+    return (X509_NAME_set(&x->cert_info->subject, name));
+}
 
 int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
-	{
-	ASN1_TIME *in;
+{
+    ASN1_TIME *in;
 
-	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
-	in=x->cert_info->validity->notBefore;
-	if (in != tm)
-		{
-		in=M_ASN1_TIME_dup(tm);
-		if (in != NULL)
-			{
-			M_ASN1_TIME_free(x->cert_info->validity->notBefore);
-			x->cert_info->validity->notBefore=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if ((x == NULL) || (x->cert_info->validity == NULL))
+        return (0);
+    in = x->cert_info->validity->notBefore;
+    if (in != tm) {
+        in = M_ASN1_TIME_dup(tm);
+        if (in != NULL) {
+            M_ASN1_TIME_free(x->cert_info->validity->notBefore);
+            x->cert_info->validity->notBefore = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
-	{
-	ASN1_TIME *in;
+{
+    ASN1_TIME *in;
 
-	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
-	in=x->cert_info->validity->notAfter;
-	if (in != tm)
-		{
-		in=M_ASN1_TIME_dup(tm);
-		if (in != NULL)
-			{
-			M_ASN1_TIME_free(x->cert_info->validity->notAfter);
-			x->cert_info->validity->notAfter=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if ((x == NULL) || (x->cert_info->validity == NULL))
+        return (0);
+    in = x->cert_info->validity->notAfter;
+    if (in != tm) {
+        in = M_ASN1_TIME_dup(tm);
+        if (in != NULL) {
+            M_ASN1_TIME_free(x->cert_info->validity->notAfter);
+            x->cert_info->validity->notAfter = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
-	{
-	if ((x == NULL) || (x->cert_info == NULL)) return(0);
-	return(X509_PUBKEY_set(&(x->cert_info->key),pkey));
-	}
-
-
-
+{
+    if ((x == NULL) || (x->cert_info == NULL))
+        return (0);
+    return (X509_PUBKEY_set(&(x->cert_info->key), pkey));
+}
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
new file mode 100644
index 0000000..650163a
--- /dev/null
+++ b/src/crypto/x509/x509_test.cc
@@ -0,0 +1,472 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <vector>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/digest.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+
+#include "../test/scoped_types.h"
+
+
+static const char kCrossSigningRootPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICcTCCAdqgAwIBAgIIagJHiPvE0MowDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwo3qFvSB9Zmlbpzn9wJp\n"
+"ikI75Rxkatez8VkLqyxbOhPYl2Haz8F5p1gDG96dCI6jcLGgu3AKT9uhEQyyUko5\n"
+"EKYasazSeA9CQrdyhPg0mkTYVETnPM1W/ebid1YtqQbq1CMWlq2aTDoSGAReGFKP\n"
+"RTdXAbuAXzpCfi/d8LqV13UCAwEAAaN6MHgwDgYDVR0PAQH/BAQDAgIEMB0GA1Ud\n"
+"JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MBkGA1Ud\n"
+"DgQSBBBHKHC7V3Z/3oLvEZx0RZRwMBsGA1UdIwQUMBKAEEcocLtXdn/egu8RnHRF\n"
+"lHAwDQYJKoZIhvcNAQELBQADgYEAnglibsy6mGtpIXivtlcz4zIEnHw/lNW+r/eC\n"
+"CY7evZTmOoOuC/x9SS3MF9vawt1HFUummWM6ZgErqVBOXIB4//ykrcCgf5ZbF5Hr\n"
+"+3EFprKhBqYiXdD8hpBkrBoXwn85LPYWNd2TceCrx0YtLIprE2R5MB2RIq8y4Jk3\n"
+"YFXvkME=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRootCAPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICVTCCAb6gAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwLjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwIBcNMTUwMTAx\n"
+"MDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMC4xGjAYBgNVBAoTEUJvcmluZ1NTTCBU\n"
+"RVNUSU5HMRAwDgYDVQQDEwdSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
+"iQKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/VImi2XeJM\n"
+"2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2m8PX+plZ\n"
+"w7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQABo3oweDAO\n"
+"BgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8G\n"
+"A1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEEA31wH7QC+4HH5UBCeMWQEwGwYDVR0j\n"
+"BBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOBgQDXylEK77Za\n"
+"kKeY6ZerrScWyZhrjIGtHFu09qVpdJEzrk87k2G7iHHR9CAvSofCgEExKtWNS9dN\n"
+"+9WiZp/U48iHLk7qaYXdEuO07No4BYtXn+lkOykE+FUxmA4wvOF1cTd2tdj3MzX2\n"
+"kfGIBAYhzGZWhY3JbhIfTEfY1PNM1pWChQ==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRootCrossSignedPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICYzCCAcygAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowLjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwgZ8wDQYJKoZI\n"
+"hvcNAQEBBQADgY0AMIGJAoGBAOkOfxEM5lrmhoNw9lEHLgJ4EfWyJJI47iZiAseU\n"
+"8T6hd2rAj9UiaLZd4kza4IURNcKSckmNgbSIl2u3/LJEW9lNBnD5DMaP6bPfo2qE\n"
+"bENZvp2y0Habw9f6mVnDuOXzUwO9SdazzKJD/q3CC7kBuFYplAMkpw0oISmprpRb\n"
+"SvmfAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEFBQcD\n"
+"AQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQQDfXAftAL7gc\n"
+"flQEJ4xZATAbBgNVHSMEFDASgBBHKHC7V3Z/3oLvEZx0RZRwMA0GCSqGSIb3DQEB\n"
+"CwUAA4GBAErTxYJ0en9HVRHAAr5OO5wuk5Iq3VMc79TMyQLCXVL8YH8Uk7KEwv+q\n"
+"9MEKZv2eR/Vfm4HlXlUuIqfgUXbwrAYC/YVVX86Wnbpy/jc73NYVCq8FEZeO+0XU\n"
+"90SWAPDdp+iL7aZdimnMtG1qlM1edmz8AKbrhN/R3IbA2CL0nCWV\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kIntermediatePEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICXjCCAcegAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMC4xGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRAwDgYDVQQDEwdSb290IENBMCAXDTE1MDEw\n"
+"MTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjA2MRowGAYDVQQKExFCb3JpbmdTU0wg\n"
+"VEVTVElORzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEB\n"
+"AQUAA4GNADCBiQKBgQC7YtI0l8ocTYJ0gKyXTtPL4iMJCNY4OcxXl48jkncVG1Hl\n"
+"blicgNUa1r9m9YFtVkxvBinb8dXiUpEGhVg4awRPDcatlsBSEBuJkiZGYbRcAmSu\n"
+"CmZYnf6u3aYQ18SU8WqVERPpE4cwVVs+6kwlzRw0+XDoZAczu8ZezVhCUc6NbQID\n"
+"AQABo3oweDAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n"
+"AQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEIwaaKi1dttdV3sfjRSy\n"
+"BqMwGwYDVR0jBBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOB\n"
+"gQCvnolNWEHuQS8PFVVyuLR+FKBeUUdrVbSfHSzTqNAqQGp0C9fk5oCzDq6ZgTfY\n"
+"ESXM4cJhb3IAnW0UM0NFsYSKQJ50JZL2L3z5ZLQhHdbs4RmODGoC40BVdnJ4/qgB\n"
+"aGSh09eQRvAVmbVCviDK2ipkWNegdyI19jFfNP5uIkGlYg==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kIntermediateSelfSignedPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICZjCCAc+gAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDYxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwgZ8wDQYJ\n"
+"KoZIhvcNAQEBBQADgY0AMIGJAoGBALti0jSXyhxNgnSArJdO08viIwkI1jg5zFeX\n"
+"jyOSdxUbUeVuWJyA1RrWv2b1gW1WTG8GKdvx1eJSkQaFWDhrBE8Nxq2WwFIQG4mS\n"
+"JkZhtFwCZK4KZlid/q7dphDXxJTxapURE+kThzBVWz7qTCXNHDT5cOhkBzO7xl7N\n"
+"WEJRzo1tAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEF\n"
+"BQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQjBpoqLV2\n"
+"211Xex+NFLIGozAbBgNVHSMEFDASgBCMGmiotXbbXVd7H40UsgajMA0GCSqGSIb3\n"
+"DQEBCwUAA4GBALcccSrAQ0/EqQBsx0ZDTUydHXXNP2DrUkpUKmAXIe8McqIVSlkT\n"
+"6H4xz7z8VRKBo9j+drjjtCw2i0CQc8aOLxRb5WJ8eVLnaW2XRlUqAzhF0CrulfVI\n"
+"E4Vs6ZLU+fra1WAuIj6qFiigRja+3YkZArG8tMA9vtlhTX/g7YBZIkqH\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kLeafPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg\n"
+"Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y\n"
+"aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3\n"
+"DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c\n"
+"oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j\n"
+"5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh\n"
+"TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG\n"
+"CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0\n"
+"4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB\n"
+"gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y\n"
+"rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU\n"
+"xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kLeafNoKeyUsagePEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICNTCCAZ6gAwIBAgIJAIFQGaLQ0G2mMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDcxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRkwFwYDVQQDExBldmlsLmV4YW1wbGUuY29tMIGfMA0G\n"
+"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOKoZe75NPz77EOaMMl4/0s3PyQw++zJvp\n"
+"ejHAxZiTPCJgMbEHLrSzNoHdopg+CLUH5bE4wTXM8w9Inv5P8OAFJt7gJuPUunmk\n"
+"j+NoU3QfzOR6BroePcz1vXX9jyVHRs087M/sLqWRHu9IR+/A+UTcBaWaFiDVUxtJ\n"
+"YOwFMwjNPQIDAQABo0gwRjAMBgNVHRMBAf8EAjAAMBkGA1UdDgQSBBBJfLEUWHq1\n"
+"27rZ1AVx2J5GMBsGA1UdIwQUMBKAEIwaaKi1dttdV3sfjRSyBqMwDQYJKoZIhvcN\n"
+"AQELBQADgYEALVKN2Y3LZJOtu6SxFIYKxbLaXhTGTdIjxipZhmbBRDFjbZjZZOTe\n"
+"6Oo+VDNPYco4rBexK7umYXJyfTqoY0E8dbiImhTcGTEj7OAB3DbBomgU1AYe+t2D\n"
+"uwBqh4Y3Eto+Zn4pMVsxGEfUpjzjZDel7bN1/oU/9KWPpDfywfUmjgk=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kForgeryPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICZzCCAdCgAwIBAgIIdTlMzQoKkeMwDQYJKoZIhvcNAQELBQAwNzEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGTAXBgNVBAMTEGV2aWwuZXhhbXBsZS5jb20w\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDoxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRwwGgYDVQQDExNmb3JnZXJ5LmV4YW1wbGUuY29tMIGf\n"
+"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADTwruBQZGb7Ay6s9HiYv5d1lwtEy\n"
+"xQdA2Sy8Rn8uA20Q4KgqwVY7wzIZ+z5Butrsmwb70gdG1XU+yRaDeE7XVoW6jSpm\n"
+"0sw35/5vJbTcL4THEFbnX0OPZnvpuZDFUkvVtq5kxpDWsVyM24G8EEq7kPih3Sa3\n"
+"OMhXVXF8kso6UQIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI\n"
+"KwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEEYJ/WHM\n"
+"8p64erPWIg4/liwwGwYDVR0jBBQwEoAQSXyxFFh6tdu62dQFcdieRjANBgkqhkiG\n"
+"9w0BAQsFAAOBgQA+zH7bHPElWRWJvjxDqRexmYLn+D3Aivs8XgXQJsM94W0EzSUf\n"
+"DSLfRgaQwcb2gg2xpDFoG+W0vc6O651uF23WGt5JaFFJJxqjII05IexfCNhuPmp4\n"
+"4UZAXPttuJXpn74IY1tuouaM06B3vXKZR+/ityKmfJvSwxacmFcK+2ziAg==\n"
+"-----END CERTIFICATE-----\n";
+
+// kExamplePSSCert is an example RSA-PSS self-signed certificate, signed with
+// the default hash functions.
+static const char kExamplePSSCert[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICYjCCAcagAwIBAgIJAI3qUyT6SIfzMBIGCSqGSIb3DQEBCjAFogMCAWowRTEL\n"
+"MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy\n"
+"bmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDEwMDkxOTA5NTVaFw0xNTEwMDkxOTA5\n"
+"NTVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK\n"
+"DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A\n"
+"MIGJAoGBAPi4bIO0vNmoV8CltFl2jFQdeesiUgR+0zfrQf2D+fCmhRU0dXFahKg8\n"
+"0u9aTtPel4rd/7vPCqqGkr64UOTNb4AzMHYTj8p73OxaymPHAyXvqIqDWHYg+hZ3\n"
+"13mSYwFIGth7Z/FSVUlO1m5KXNd6NzYM3t2PROjCpywrta9kS2EHAgMBAAGjUDBO\n"
+"MB0GA1UdDgQWBBTQQfuJQR6nrVrsNF1JEflVgXgfEzAfBgNVHSMEGDAWgBTQQfuJ\n"
+"QR6nrVrsNF1JEflVgXgfEzAMBgNVHRMEBTADAQH/MBIGCSqGSIb3DQEBCjAFogMC\n"
+"AWoDgYEASUy2RZcgNbNQZA0/7F+V1YTLEXwD16bm+iSVnzGwtexmQVEYIZG74K/w\n"
+"xbdZQdTbpNJkp1QPjPfh0zsatw6dmt5QoZ8K8No0DjR9dgf+Wvv5WJvJUIQBoAVN\n"
+"Z0IL+OQFz6+LcTHxD27JJCebrATXZA0wThGTQDm7crL+a+SujBY=\n"
+"-----END CERTIFICATE-----\n";
+
+// kBadPSSCertPEM is a self-signed RSA-PSS certificate with bad parameters.
+static const char kBadPSSCertPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIIDdjCCAjqgAwIBAgIJANcwZLyfEv7DMD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n"
+"AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3jAnMSUwIwYD\n"
+"VQQDDBxUZXN0IEludmFsaWQgUFNTIGNlcnRpZmljYXRlMB4XDTE1MTEwNDE2MDIz\n"
+"NVoXDTE1MTIwNDE2MDIzNVowJzElMCMGA1UEAwwcVGVzdCBJbnZhbGlkIFBTUyBj\n"
+"ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMTaM7WH\n"
+"qVCAGAIA+zL1KWvvASTrhlq+1ePdO7wsrWX2KiYoTYrJYTnxhLnn0wrHqApt79nL\n"
+"IBG7cfShyZqFHOY/IzlYPMVt+gPo293gw96Fds5JBsjhjkyGnOyr9OUntFqvxDbT\n"
+"IIFU7o9IdxD4edaqjRv+fegVE+B79pDk4s0ujsk6dULtCg9Rst0ucGFo19mr+b7k\n"
+"dbfn8pZ72ZNDJPueVdrUAWw9oll61UcYfk75XdrLk6JlL41GrYHc8KlfXf43gGQq\n"
+"QfrpHkg4Ih2cI6Wt2nhFGAzrlcorzLliQIUJRIhM8h4IgDfpBpaPdVQLqS2pFbXa\n"
+"5eQjqiyJwak2vJ8CAwEAAaNQME4wHQYDVR0OBBYEFCt180N4oGUt5LbzBwQ4Ia+2\n"
+"4V97MB8GA1UdIwQYMBaAFCt180N4oGUt5LbzBwQ4Ia+24V97MAwGA1UdEwQFMAMB\n"
+"Af8wMQYJKoZIhvcNAQEKMCSgDTALBglghkgBZQMEAgGhDTALBgkqhkiG9w0BAQii\n"
+"BAICAN4DggEBAAjBtm90lGxgddjc4Xu/nbXXFHVs2zVcHv/mqOZoQkGB9r/BVgLb\n"
+"xhHrFZ2pHGElbUYPfifdS9ztB73e1d4J+P29o0yBqfd4/wGAc/JA8qgn6AAEO/Xn\n"
+"plhFeTRJQtLZVl75CkHXgUGUd3h+ADvKtcBuW9dSUncaUrgNKR8u/h/2sMG38RWY\n"
+"DzBddC/66YTa3r7KkVUfW7yqRQfELiGKdcm+bjlTEMsvS+EhHup9CzbpoCx2Fx9p\n"
+"NPtFY3yEObQhmL1JyoCRWqBE75GzFPbRaiux5UpEkns+i3trkGssZzsOuVqHNTNZ\n"
+"lC9+9hPHIoc9UMmAQNo1vGIW3NWVoeGbaJ8=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRSAKey[] =
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
+"kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
+"KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
+"AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
+"i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
+"WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
+"m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
+"QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
+"aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
+"LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
+"104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
+"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
+"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
+"-----END RSA PRIVATE KEY-----\n";
+
+
+// CertFromPEM parses the given, NUL-terminated pem block and returns an
+// |X509*|.
+static ScopedX509 CertFromPEM(const char *pem) {
+  ScopedBIO bio(BIO_new_mem_buf(pem, strlen(pem)));
+  return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+}
+
+// PrivateKeyFromPEM parses the given, NUL-terminated pem block and returns an
+// |EVP_PKEY*|.
+static ScopedEVP_PKEY PrivateKeyFromPEM(const char *pem) {
+  ScopedBIO bio(BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
+  return ScopedEVP_PKEY(
+      PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+}
+
+// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509*),
+// bumping the reference counts for each certificate in question.
+static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
+  ScopedX509Stack stack(sk_X509_new_null());
+  if (!stack) {
+    return nullptr;
+  }
+  for (auto cert : certs) {
+    if (!sk_X509_push(stack.get(), cert)) {
+      return nullptr;
+    }
+    X509_up_ref(cert);
+  }
+
+  return stack.release();
+}
+
+static bool Verify(X509 *leaf, const std::vector<X509 *> &roots,
+                   const std::vector<X509 *> &intermediates,
+                   unsigned long flags = 0) {
+  ScopedX509Stack roots_stack(CertsToStack(roots));
+  ScopedX509Stack intermediates_stack(CertsToStack(intermediates));
+  if (!roots_stack ||
+      !intermediates_stack) {
+    return false;
+  }
+
+  ScopedX509_STORE_CTX ctx(X509_STORE_CTX_new());
+  if (!ctx) {
+    return false;
+  }
+  if (!X509_STORE_CTX_init(ctx.get(), nullptr /* no X509_STORE */, leaf,
+                           intermediates_stack.get())) {
+    return false;
+  }
+
+  X509_STORE_CTX_trusted_stack(ctx.get(), roots_stack.get());
+
+  X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
+  if (param == nullptr) {
+    return false;
+  }
+  X509_VERIFY_PARAM_set_time(param, 1452807555 /* Jan 14th, 2016 */);
+  X509_VERIFY_PARAM_set_depth(param, 16);
+  if (flags) {
+    X509_VERIFY_PARAM_set_flags(param, flags);
+  }
+  X509_STORE_CTX_set0_param(ctx.get(), param);
+
+  ERR_clear_error();
+  return X509_verify_cert(ctx.get()) == 1;
+}
+
+static bool TestVerify() {
+  ScopedX509 cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
+  ScopedX509 root(CertFromPEM(kRootCAPEM));
+  ScopedX509 root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
+  ScopedX509 intermediate(CertFromPEM(kIntermediatePEM));
+  ScopedX509 intermediate_self_signed(CertFromPEM(kIntermediateSelfSignedPEM));
+  ScopedX509 leaf(CertFromPEM(kLeafPEM));
+  ScopedX509 leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
+  ScopedX509 forgery(CertFromPEM(kForgeryPEM));
+
+  if (!cross_signing_root ||
+      !root ||
+      !root_cross_signed ||
+      !intermediate ||
+      !intermediate_self_signed ||
+      !leaf ||
+      !leaf_no_key_usage ||
+      !forgery) {
+    fprintf(stderr, "Failed to parse certificates\n");
+    return false;
+  }
+
+  std::vector<X509*> empty;
+  if (Verify(leaf.get(), empty, empty)) {
+    fprintf(stderr, "Leaf verified with no roots!\n");
+    return false;
+  }
+
+  if (Verify(leaf.get(), empty, {intermediate.get()})) {
+    fprintf(stderr, "Leaf verified with no roots!\n");
+    return false;
+  }
+
+  if (!Verify(leaf.get(), {root.get()}, {intermediate.get()})) {
+    ERR_print_errors_fp(stderr);
+    fprintf(stderr, "Basic chain didn't verify.\n");
+    return false;
+  }
+
+  if (!Verify(leaf.get(), {cross_signing_root.get()},
+              {intermediate.get(), root_cross_signed.get()})) {
+    ERR_print_errors_fp(stderr);
+    fprintf(stderr, "Cross-signed chain didn't verify.\n");
+    return false;
+  }
+
+  if (!Verify(leaf.get(), {cross_signing_root.get(), root.get()},
+              {intermediate.get(), root_cross_signed.get()})) {
+    ERR_print_errors_fp(stderr);
+    fprintf(stderr, "Cross-signed chain with root didn't verify.\n");
+    return false;
+  }
+
+  /* This is the “altchains” test – we remove the cross-signing CA but include
+   * the cross-sign in the intermediates. */
+  if (!Verify(leaf.get(), {root.get()},
+              {intermediate.get(), root_cross_signed.get()})) {
+    ERR_print_errors_fp(stderr);
+    fprintf(stderr, "Chain with cross-sign didn't backtrack to find root.\n");
+    return false;
+  }
+
+  if (Verify(leaf.get(), {root.get()},
+             {intermediate.get(), root_cross_signed.get()},
+             X509_V_FLAG_NO_ALT_CHAINS)) {
+    fprintf(stderr, "Altchains test still passed when disabled.\n");
+    return false;
+  }
+
+  if (Verify(forgery.get(), {intermediate_self_signed.get()},
+             {leaf_no_key_usage.get()})) {
+    fprintf(stderr, "Basic constraints weren't checked.\n");
+    return false;
+  }
+
+  /* Test that one cannot skip Basic Constraints checking with a contorted set
+   * of roots and intermediates. This is a regression test for CVE-2015-1793. */
+  if (Verify(forgery.get(),
+             {intermediate_self_signed.get(), root_cross_signed.get()},
+             {leaf_no_key_usage.get(), intermediate.get()})) {
+    fprintf(stderr, "Basic constraints weren't checked.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool TestPSS() {
+  ScopedX509 cert(CertFromPEM(kExamplePSSCert));
+  if (!cert) {
+    return false;
+  }
+
+  ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+  if (!pkey) {
+    return false;
+  }
+
+  if (!X509_verify(cert.get(), pkey.get())) {
+    fprintf(stderr, "Could not verify certificate.\n");
+    return false;
+  }
+  return true;
+}
+
+static bool TestBadPSSParameters() {
+  ScopedX509 cert(CertFromPEM(kBadPSSCertPEM));
+  if (!cert) {
+    return false;
+  }
+
+  ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+  if (!pkey) {
+    return false;
+  }
+
+  if (X509_verify(cert.get(), pkey.get())) {
+    fprintf(stderr, "Unexpectedly verified bad certificate.\n");
+    return false;
+  }
+  ERR_clear_error();
+  return true;
+}
+
+static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
+  // Make a certificate like signed with |md_ctx|'s settings.'
+  ScopedX509 cert(CertFromPEM(kLeafPEM));
+  if (!cert || !X509_sign_ctx(cert.get(), md_ctx)) {
+    return false;
+  }
+
+  // Ensure that |pkey| may still be used to verify the resulting signature. All
+  // settings in |md_ctx| must have been serialized appropriately.
+  return !!X509_verify(cert.get(), pkey);
+}
+
+static bool TestSignCtx() {
+  ScopedEVP_PKEY pkey(PrivateKeyFromPEM(kRSAKey));
+  if (!pkey) {
+    return false;
+  }
+
+  // Test PKCS#1 v1.5.
+  ScopedEVP_MD_CTX md_ctx;
+  if (!EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+      !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
+    fprintf(stderr, "RSA PKCS#1 with SHA-256 failed\n");
+    return false;
+  }
+
+  // Test RSA-PSS with custom parameters.
+  md_ctx.Reset();
+  EVP_PKEY_CTX *pkey_ctx;
+  if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
+                          pkey.get()) ||
+      !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
+      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
+      !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
+    fprintf(stderr, "RSA-PSS failed\n");
+    return false;
+  }
+
+  return true;
+}
+
+int main(int argc, char **argv) {
+  CRYPTO_library_init();
+
+  if (!TestVerify() ||
+      !TestPSS() ||
+      !TestBadPSSParameters() ||
+      !TestSignCtx()) {
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/x509/x509_trs.c b/src/crypto/x509/x509_trs.c
index 820e605..c7dfcad 100644
--- a/src/crypto/x509/x509_trs.c
+++ b/src/crypto/x509/x509_trs.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -58,9 +60,7 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static int tr_cmp(const X509_TRUST **a,
-		const X509_TRUST **b);
+static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b);
 static void trtable_free(X509_TRUST *p);
 
 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
@@ -68,237 +68,259 @@
 static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
 
 static int obj_trust(int id, X509 *x, int flags);
-static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
+static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
 
-/* WARNING: the following table should be kept in order of trust
- * and without any gaps so we can just subtract the minimum trust
- * value to get an index into the table
+/*
+ * WARNING: the following table should be kept in order of trust and without
+ * any gaps so we can just subtract the minimum trust value to get an index
+ * into the table
  */
 
 static X509_TRUST trstandard[] = {
-{X509_TRUST_COMPAT, 0, trust_compat, (char *) "compatible", 0, NULL},
-{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *) "SSL Client", NID_client_auth, NULL},
-{X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *) "SSL Server", NID_server_auth, NULL},
-{X509_TRUST_EMAIL, 0, trust_1oidany, (char *) "S/MIME email", NID_email_protect, NULL},
-{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *) "Object Signer", NID_code_sign, NULL},
-{X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *) "OCSP responder", NID_OCSP_sign, NULL},
-{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *) "OCSP request", NID_ad_OCSP, NULL},
-{X509_TRUST_TSA, 0, trust_1oidany, (char *) "TSA server", NID_time_stamp, NULL}
+    {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL},
+    {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client",
+     NID_client_auth, NULL},
+    {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server",
+     NID_server_auth, NULL},
+    {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email",
+     NID_email_protect, NULL},
+    {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer",
+     NID_code_sign, NULL},
+    {X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *)"OCSP responder",
+     NID_OCSP_sign, NULL},
+    {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request",
+     NID_ad_OCSP, NULL},
+    {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp,
+     NULL}
 };
 
-#define X509_TRUST_COUNT	(sizeof(trstandard)/sizeof(X509_TRUST))
+#define X509_TRUST_COUNT        (sizeof(trstandard)/sizeof(X509_TRUST))
 
 static STACK_OF(X509_TRUST) *trtable = NULL;
 
-static int tr_cmp(const X509_TRUST **a,
-		const X509_TRUST **b)
+static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b)
 {
-	return (*a)->trust - (*b)->trust;
+    return (*a)->trust - (*b)->trust;
 }
 
-int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
-{
-	int (*oldtrust)(int , X509 *, int);
-	oldtrust = default_trust;
-	default_trust = trust;
-	return oldtrust;
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+                                                                int) {
+    int (*oldtrust) (int, X509 *, int);
+    oldtrust = default_trust;
+    default_trust = trust;
+    return oldtrust;
 }
 
-
 int X509_check_trust(X509 *x, int id, int flags)
 {
-	X509_TRUST *pt;
-	int idx;
-	if(id == -1) return 1;
-	/* We get this as a default value */
-	if (id == 0)
-		{
-		int rv;
-		rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
-		if (rv != X509_TRUST_UNTRUSTED)
-			return rv;
-		return trust_compat(NULL, x, 0);
-		}
-	idx = X509_TRUST_get_by_id(id);
-	if(idx == -1) return default_trust(id, x, flags);
-	pt = X509_TRUST_get0(idx);
-	return pt->check_trust(pt, x, flags);
+    X509_TRUST *pt;
+    int idx;
+    if (id == -1)
+        return 1;
+    /* We get this as a default value */
+    if (id == 0) {
+        int rv;
+        rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
+        if (rv != X509_TRUST_UNTRUSTED)
+            return rv;
+        return trust_compat(NULL, x, 0);
+    }
+    idx = X509_TRUST_get_by_id(id);
+    if (idx == -1)
+        return default_trust(id, x, flags);
+    pt = X509_TRUST_get0(idx);
+    return pt->check_trust(pt, x, flags);
 }
 
 int X509_TRUST_get_count(void)
 {
-	if(!trtable) return X509_TRUST_COUNT;
-	return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
+    if (!trtable)
+        return X509_TRUST_COUNT;
+    return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
 }
 
-X509_TRUST * X509_TRUST_get0(int idx)
+X509_TRUST *X509_TRUST_get0(int idx)
 {
-	if(idx < 0) return NULL;
-	if(idx < (int)X509_TRUST_COUNT) return trstandard + idx;
-	return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
+    if (idx < 0)
+        return NULL;
+    if (idx < (int)X509_TRUST_COUNT)
+        return trstandard + idx;
+    return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
 }
 
 int X509_TRUST_get_by_id(int id)
 {
-	X509_TRUST tmp;
-	size_t idx;
+    X509_TRUST tmp;
+    size_t idx;
 
-	if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
-				 return id - X509_TRUST_MIN;
-	tmp.trust = id;
-	if(!trtable) return -1;
-	if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
-		return -1;
-	}
-	return idx + X509_TRUST_COUNT;
+    if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
+        return id - X509_TRUST_MIN;
+    tmp.trust = id;
+    if (!trtable)
+        return -1;
+    if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
+        return -1;
+    }
+    return idx + X509_TRUST_COUNT;
 }
 
 int X509_TRUST_set(int *t, int trust)
 {
-	if(X509_TRUST_get_by_id(trust) == -1) {
-		OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
-		return 0;
-	}
-	*t = trust;
-	return 1;
+    if (X509_TRUST_get_by_id(trust) == -1) {
+        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
+        return 0;
+    }
+    *t = trust;
+    return 1;
 }
 
-int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
-					char *name, int arg1, void *arg2)
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+                   char *name, int arg1, void *arg2)
 {
-	int idx;
-	X509_TRUST *trtmp;
-	char *name_dup;
+    int idx;
+    X509_TRUST *trtmp;
+    char *name_dup;
 
-	/* This is set according to what we change: application can't set it */
-	flags &= ~X509_TRUST_DYNAMIC;
-	/* This will always be set for application modified trust entries */
-	flags |= X509_TRUST_DYNAMIC_NAME;
-	/* Get existing entry if any */
-	idx = X509_TRUST_get_by_id(id);
-	/* Need a new entry */
-	if(idx == -1) {
-		if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			return 0;
-		}
-		trtmp->flags = X509_TRUST_DYNAMIC;
-	} else trtmp = X509_TRUST_get0(idx);
+    /*
+     * This is set according to what we change: application can't set it
+     */
+    flags &= ~X509_TRUST_DYNAMIC;
+    /* This will always be set for application modified trust entries */
+    flags |= X509_TRUST_DYNAMIC_NAME;
+    /* Get existing entry if any */
+    idx = X509_TRUST_get_by_id(id);
+    /* Need a new entry */
+    if (idx == -1) {
+        if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        trtmp->flags = X509_TRUST_DYNAMIC;
+    } else
+        trtmp = X509_TRUST_get0(idx);
 
-	/* Duplicate the supplied name. */
-	name_dup = BUF_strdup(name);
-	if (name_dup == NULL) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		if (idx == -1)
-			OPENSSL_free(trtmp);
-		return 0;
-	}
+    /* Duplicate the supplied name. */
+    name_dup = BUF_strdup(name);
+    if (name_dup == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        if (idx == -1)
+            OPENSSL_free(trtmp);
+        return 0;
+    }
 
-	/* OPENSSL_free existing name if dynamic */
-	if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
-	trtmp->name = name_dup;
-	/* Keep the dynamic flag of existing entry */
-	trtmp->flags &= X509_TRUST_DYNAMIC;
-	/* Set all other flags */
-	trtmp->flags |= flags;
+    /* OPENSSL_free existing name if dynamic */
+    if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
+        OPENSSL_free(trtmp->name);
+    trtmp->name = name_dup;
+    /* Keep the dynamic flag of existing entry */
+    trtmp->flags &= X509_TRUST_DYNAMIC;
+    /* Set all other flags */
+    trtmp->flags |= flags;
 
-	trtmp->trust = id;
-	trtmp->check_trust = ck;
-	trtmp->arg1 = arg1;
-	trtmp->arg2 = arg2;
+    trtmp->trust = id;
+    trtmp->check_trust = ck;
+    trtmp->arg1 = arg1;
+    trtmp->arg2 = arg2;
 
-	/* If its a new entry manage the dynamic table */
-	if(idx == -1) {
-		if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			trtable_free(trtmp);
-			return 0;
-		}
-		if (!sk_X509_TRUST_push(trtable, trtmp)) {
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			trtable_free(trtmp);
-			return 0;
-		}
-	}
-	return 1;
+    /* If its a new entry manage the dynamic table */
+    if (idx == -1) {
+        if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+            trtable_free(trtmp);
+            return 0;
+        }
+        if (!sk_X509_TRUST_push(trtable, trtmp)) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+            trtable_free(trtmp);
+            return 0;
+        }
+    }
+    return 1;
 }
 
 static void trtable_free(X509_TRUST *p)
-	{
-	if(!p) return;
-	if (p->flags & X509_TRUST_DYNAMIC) 
-		{
-		if (p->flags & X509_TRUST_DYNAMIC_NAME)
-			OPENSSL_free(p->name);
-		OPENSSL_free(p);
-		}
-	}
+{
+    if (!p)
+        return;
+    if (p->flags & X509_TRUST_DYNAMIC) {
+        if (p->flags & X509_TRUST_DYNAMIC_NAME)
+            OPENSSL_free(p->name);
+        OPENSSL_free(p);
+    }
+}
 
 void X509_TRUST_cleanup(void)
 {
-	unsigned int i;
-	for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i);
-	sk_X509_TRUST_pop_free(trtable, trtable_free);
-	trtable = NULL;
+    unsigned int i;
+    for (i = 0; i < X509_TRUST_COUNT; i++)
+        trtable_free(trstandard + i);
+    sk_X509_TRUST_pop_free(trtable, trtable_free);
+    trtable = NULL;
 }
 
 int X509_TRUST_get_flags(X509_TRUST *xp)
 {
-	return xp->flags;
+    return xp->flags;
 }
 
 char *X509_TRUST_get0_name(X509_TRUST *xp)
 {
-	return xp->name;
+    return xp->name;
 }
 
 int X509_TRUST_get_trust(X509_TRUST *xp)
 {
-	return xp->trust;
+    return xp->trust;
 }
 
 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
 {
-	if(x->aux && (x->aux->trust || x->aux->reject))
-		return obj_trust(trust->arg1, x, flags);
-	/* we don't have any trust settings: for compatibility
-	 * we return trusted if it is self signed
-	 */
-	return trust_compat(trust, x, flags);
+    if (x->aux && (x->aux->trust || x->aux->reject))
+        return obj_trust(trust->arg1, x, flags);
+    /*
+     * we don't have any trust settings: for compatibility we return trusted
+     * if it is self signed
+     */
+    return trust_compat(trust, x, flags);
 }
 
 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
 {
-	if(x->aux) return obj_trust(trust->arg1, x, flags);
-	return X509_TRUST_UNTRUSTED;
+    if (x->aux)
+        return obj_trust(trust->arg1, x, flags);
+    return X509_TRUST_UNTRUSTED;
 }
 
 static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
 {
-	X509_check_purpose(x, -1, 0);
-	if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
-	else return X509_TRUST_UNTRUSTED;
+    X509_check_purpose(x, -1, 0);
+    if (x->ex_flags & EXFLAG_SS)
+        return X509_TRUST_TRUSTED;
+    else
+        return X509_TRUST_UNTRUSTED;
 }
 
 static int obj_trust(int id, X509 *x, int flags)
 {
-	ASN1_OBJECT *obj;
-	size_t i;
-	X509_CERT_AUX *ax;
-	ax = x->aux;
-	if(!ax) return X509_TRUST_UNTRUSTED;
-	if(ax->reject) {
-		for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
-			obj = sk_ASN1_OBJECT_value(ax->reject, i);
-			if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
-		}
-	}	
-	if(ax->trust) {
-		for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
-			obj = sk_ASN1_OBJECT_value(ax->trust, i);
-			if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
-		}
-	}
-	return X509_TRUST_UNTRUSTED;
+    ASN1_OBJECT *obj;
+    size_t i;
+    X509_CERT_AUX *ax;
+    ax = x->aux;
+    if (!ax)
+        return X509_TRUST_UNTRUSTED;
+    if (ax->reject) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
+            obj = sk_ASN1_OBJECT_value(ax->reject, i);
+            if (OBJ_obj2nid(obj) == id)
+                return X509_TRUST_REJECTED;
+        }
+    }
+    if (ax->trust) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
+            obj = sk_ASN1_OBJECT_value(ax->trust, i);
+            if (OBJ_obj2nid(obj) == id)
+                return X509_TRUST_TRUSTED;
+        }
+    }
+    return X509_TRUST_UNTRUSTED;
 }
-
diff --git a/src/crypto/x509/x509_txt.c b/src/crypto/x509/x509_txt.c
index c286710..86af3fe 100644
--- a/src/crypto/x509/x509_txt.c
+++ b/src/crypto/x509/x509_txt.c
@@ -63,147 +63,144 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 const char *X509_verify_cert_error_string(long n)
-	{
-	static char buf[100];
+{
+    static char buf[100];
 
-	switch ((int)n)
-		{
-	case X509_V_OK:
-		return("ok");
-	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-		return("unable to get issuer certificate");
-	case X509_V_ERR_UNABLE_TO_GET_CRL:
-		return("unable to get certificate CRL");
-	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
-		return("unable to decrypt certificate's signature");
-	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
-		return("unable to decrypt CRL's signature");
-	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
-		return("unable to decode issuer public key");
-	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
-		return("certificate signature failure");
-	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
-		return("CRL signature failure");
-	case X509_V_ERR_CERT_NOT_YET_VALID:
-		return("certificate is not yet valid");
-	case X509_V_ERR_CRL_NOT_YET_VALID:
-		return("CRL is not yet valid");
-	case X509_V_ERR_CERT_HAS_EXPIRED:
-		return("certificate has expired");
-	case X509_V_ERR_CRL_HAS_EXPIRED:
-		return("CRL has expired");
-	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
-		return("format error in certificate's notBefore field");
-	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
-		return("format error in certificate's notAfter field");
-	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
-		return("format error in CRL's lastUpdate field");
-	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
-		return("format error in CRL's nextUpdate field");
-	case X509_V_ERR_OUT_OF_MEM:
-		return("out of memory");
-	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
-		return("self signed certificate");
-	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
-		return("self signed certificate in certificate chain");
-	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
-		return("unable to get local issuer certificate");
-	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
-		return("unable to verify the first certificate");
-	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
-		return("certificate chain too long");
-	case X509_V_ERR_CERT_REVOKED:
-		return("certificate revoked");
-	case X509_V_ERR_INVALID_CA:
-		return ("invalid CA certificate");
-	case X509_V_ERR_INVALID_NON_CA:
-		return ("invalid non-CA certificate (has CA markings)");
-	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
-		return ("path length constraint exceeded");
-	case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
-		return("proxy path length constraint exceeded");
-	case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
-		return("proxy certificates not allowed, please set the appropriate flag");
-	case X509_V_ERR_INVALID_PURPOSE:
-		return ("unsupported certificate purpose");
-	case X509_V_ERR_CERT_UNTRUSTED:
-		return ("certificate not trusted");
-	case X509_V_ERR_CERT_REJECTED:
-		return ("certificate rejected");
-	case X509_V_ERR_APPLICATION_VERIFICATION:
-		return("application verification failure");
-	case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
-		return("subject issuer mismatch");
-	case X509_V_ERR_AKID_SKID_MISMATCH:
-		return("authority and subject key identifier mismatch");
-	case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
-		return("authority and issuer serial number mismatch");
-	case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
-		return("key usage does not include certificate signing");
-	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
-		return("unable to get CRL issuer certificate");
-	case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
-		return("unhandled critical extension");
-	case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
-		return("key usage does not include CRL signing");
-	case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
-		return("key usage does not include digital signature");
-	case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
-		return("unhandled critical CRL extension");
-	case X509_V_ERR_INVALID_EXTENSION:
-		return("invalid or inconsistent certificate extension");
-	case X509_V_ERR_INVALID_POLICY_EXTENSION:
-		return("invalid or inconsistent certificate policy extension");
-	case X509_V_ERR_NO_EXPLICIT_POLICY:
-		return("no explicit policy");
-	case X509_V_ERR_DIFFERENT_CRL_SCOPE:
-	return("Different CRL scope");
-	case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
-	return("Unsupported extension feature");
- 	case X509_V_ERR_UNNESTED_RESOURCE:
- 		return("RFC 3779 resource not subset of parent's resources");
+    switch ((int)n) {
+    case X509_V_OK:
+        return ("ok");
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+        return ("unable to get issuer certificate");
+    case X509_V_ERR_UNABLE_TO_GET_CRL:
+        return ("unable to get certificate CRL");
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+        return ("unable to decrypt certificate's signature");
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+        return ("unable to decrypt CRL's signature");
+    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+        return ("unable to decode issuer public key");
+    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+        return ("certificate signature failure");
+    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+        return ("CRL signature failure");
+    case X509_V_ERR_CERT_NOT_YET_VALID:
+        return ("certificate is not yet valid");
+    case X509_V_ERR_CRL_NOT_YET_VALID:
+        return ("CRL is not yet valid");
+    case X509_V_ERR_CERT_HAS_EXPIRED:
+        return ("certificate has expired");
+    case X509_V_ERR_CRL_HAS_EXPIRED:
+        return ("CRL has expired");
+    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+        return ("format error in certificate's notBefore field");
+    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+        return ("format error in certificate's notAfter field");
+    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+        return ("format error in CRL's lastUpdate field");
+    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+        return ("format error in CRL's nextUpdate field");
+    case X509_V_ERR_OUT_OF_MEM:
+        return ("out of memory");
+    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+        return ("self signed certificate");
+    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+        return ("self signed certificate in certificate chain");
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+        return ("unable to get local issuer certificate");
+    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+        return ("unable to verify the first certificate");
+    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+        return ("certificate chain too long");
+    case X509_V_ERR_CERT_REVOKED:
+        return ("certificate revoked");
+    case X509_V_ERR_INVALID_CA:
+        return ("invalid CA certificate");
+    case X509_V_ERR_INVALID_NON_CA:
+        return ("invalid non-CA certificate (has CA markings)");
+    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+        return ("path length constraint exceeded");
+    case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+        return ("proxy path length constraint exceeded");
+    case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+        return
+            ("proxy certificates not allowed, please set the appropriate flag");
+    case X509_V_ERR_INVALID_PURPOSE:
+        return ("unsupported certificate purpose");
+    case X509_V_ERR_CERT_UNTRUSTED:
+        return ("certificate not trusted");
+    case X509_V_ERR_CERT_REJECTED:
+        return ("certificate rejected");
+    case X509_V_ERR_APPLICATION_VERIFICATION:
+        return ("application verification failure");
+    case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+        return ("subject issuer mismatch");
+    case X509_V_ERR_AKID_SKID_MISMATCH:
+        return ("authority and subject key identifier mismatch");
+    case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+        return ("authority and issuer serial number mismatch");
+    case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+        return ("key usage does not include certificate signing");
+    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+        return ("unable to get CRL issuer certificate");
+    case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+        return ("unhandled critical extension");
+    case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+        return ("key usage does not include CRL signing");
+    case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+        return ("key usage does not include digital signature");
+    case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+        return ("unhandled critical CRL extension");
+    case X509_V_ERR_INVALID_EXTENSION:
+        return ("invalid or inconsistent certificate extension");
+    case X509_V_ERR_INVALID_POLICY_EXTENSION:
+        return ("invalid or inconsistent certificate policy extension");
+    case X509_V_ERR_NO_EXPLICIT_POLICY:
+        return ("no explicit policy");
+    case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+        return ("Different CRL scope");
+    case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+        return ("Unsupported extension feature");
+    case X509_V_ERR_UNNESTED_RESOURCE:
+        return ("RFC 3779 resource not subset of parent's resources");
 
-	case X509_V_ERR_PERMITTED_VIOLATION:
-		return("permitted subtree violation");
-	case X509_V_ERR_EXCLUDED_VIOLATION:
-		return("excluded subtree violation");
-	case X509_V_ERR_SUBTREE_MINMAX:
-		return("name constraints minimum and maximum not supported");
-	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
-		return("unsupported name constraint type");
-	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
-		return("unsupported or invalid name constraint syntax");
-	case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
-		return("unsupported or invalid name syntax");
-	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
-		return("CRL path validation error");
+    case X509_V_ERR_PERMITTED_VIOLATION:
+        return ("permitted subtree violation");
+    case X509_V_ERR_EXCLUDED_VIOLATION:
+        return ("excluded subtree violation");
+    case X509_V_ERR_SUBTREE_MINMAX:
+        return ("name constraints minimum and maximum not supported");
+    case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+        return ("unsupported name constraint type");
+    case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+        return ("unsupported or invalid name constraint syntax");
+    case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
+        return ("unsupported or invalid name syntax");
+    case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+        return ("CRL path validation error");
 
-	case X509_V_ERR_SUITE_B_INVALID_VERSION:
-		return("Suite B: certificate version invalid");
-	case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
-		return("Suite B: invalid public key algorithm");
-	case X509_V_ERR_SUITE_B_INVALID_CURVE:
-		return("Suite B: invalid ECC curve");
-	case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
-		return("Suite B: invalid signature algorithm");
-	case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
-		return("Suite B: curve not allowed for this LOS");
-	case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
-		return("Suite B: cannot sign P-384 with P-256");
+    case X509_V_ERR_SUITE_B_INVALID_VERSION:
+        return ("Suite B: certificate version invalid");
+    case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
+        return ("Suite B: invalid public key algorithm");
+    case X509_V_ERR_SUITE_B_INVALID_CURVE:
+        return ("Suite B: invalid ECC curve");
+    case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
+        return ("Suite B: invalid signature algorithm");
+    case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
+        return ("Suite B: curve not allowed for this LOS");
+    case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
+        return ("Suite B: cannot sign P-384 with P-256");
 
-	case X509_V_ERR_HOSTNAME_MISMATCH:
-		return("Hostname mismatch");
-	case X509_V_ERR_EMAIL_MISMATCH:
-		return("Email address mismatch");
-	case X509_V_ERR_IP_ADDRESS_MISMATCH:
-		return("IP address mismatch");
+    case X509_V_ERR_HOSTNAME_MISMATCH:
+        return ("Hostname mismatch");
+    case X509_V_ERR_EMAIL_MISMATCH:
+        return ("Email address mismatch");
+    case X509_V_ERR_IP_ADDRESS_MISMATCH:
+        return ("IP address mismatch");
 
-	default:
-		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
-		return(buf);
-		}
-	}
-
-
+    default:
+        BIO_snprintf(buf, sizeof buf, "error number %ld", n);
+        return (buf);
+    }
+}
diff --git a/src/crypto/x509/x509_v3.c b/src/crypto/x509/x509_v3.c
index b042985..ecbc0dd 100644
--- a/src/crypto/x509/x509_v3.c
+++ b/src/crypto/x509/x509_v3.c
@@ -62,210 +62,217 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-
 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
-	{
-	if (x == NULL) return(0);
-	return(sk_X509_EXTENSION_num(x));
-	}
+{
+    if (x == NULL)
+        return (0);
+    return (sk_X509_EXTENSION_num(x));
+}
 
 int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
-			  int lastpos)
-	{
-	const ASN1_OBJECT *obj;
+                          int lastpos)
+{
+    const ASN1_OBJECT *obj;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL) return(-2);
-	return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
-	}
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-2);
+    return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
+}
 
-int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, const ASN1_OBJECT *obj,
-			  int lastpos)
-	{
-	int n;
-	X509_EXTENSION *ex;
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
+                          const ASN1_OBJECT *obj, int lastpos)
+{
+    int n;
+    X509_EXTENSION *ex;
 
-	if (sk == NULL) return(-1);
-	lastpos++;
-	if (lastpos < 0)
-		lastpos=0;
-	n=sk_X509_EXTENSION_num(sk);
-	for ( ; lastpos < n; lastpos++)
-		{
-		ex=sk_X509_EXTENSION_value(sk,lastpos);
-		if (OBJ_cmp(ex->object,obj) == 0)
-			return(lastpos);
-		}
-	return(-1);
-	}
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_EXTENSION_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_EXTENSION_value(sk, lastpos);
+        if (OBJ_cmp(ex->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
+}
 
 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
-			       int lastpos)
-	{
-	int n;
-	X509_EXTENSION *ex;
+                               int lastpos)
+{
+    int n;
+    X509_EXTENSION *ex;
 
-	if (sk == NULL) return(-1);
-	lastpos++;
-	if (lastpos < 0)
-		lastpos=0;
-	n=sk_X509_EXTENSION_num(sk);
-	for ( ; lastpos < n; lastpos++)
-		{
-		ex=sk_X509_EXTENSION_value(sk,lastpos);
-		if (	((ex->critical > 0) && crit) ||
-			((ex->critical <= 0) && !crit))
-			return(lastpos);
-		}
-	return(-1);
-	}
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_EXTENSION_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_EXTENSION_value(sk, lastpos);
+        if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
+            return (lastpos);
+    }
+    return (-1);
+}
 
 X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
-	{
-	if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
-		return NULL;
-	else
-		return sk_X509_EXTENSION_value(x,loc);
-	}
+{
+    if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc)
+        return NULL;
+    else
+        return sk_X509_EXTENSION_value(x, loc);
+}
 
 X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
-	{
-	X509_EXTENSION *ret;
+{
+    X509_EXTENSION *ret;
 
-	if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
-		return(NULL);
-	ret=sk_X509_EXTENSION_delete(x,loc);
-	return(ret);
-	}
+    if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc)
+        return (NULL);
+    ret = sk_X509_EXTENSION_delete(x, loc);
+    return (ret);
+}
 
 STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
-					 X509_EXTENSION *ex, int loc)
-	{
-	X509_EXTENSION *new_ex=NULL;
-	int n;
-	STACK_OF(X509_EXTENSION) *sk=NULL;
+                                         X509_EXTENSION *ex, int loc)
+{
+    X509_EXTENSION *new_ex = NULL;
+    int n;
+    STACK_OF(X509_EXTENSION) *sk = NULL;
 
-	if (x == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
-		goto err2;
-		}
+    if (x == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+        goto err2;
+    }
 
-	if (*x == NULL)
-		{
-		if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
-			goto err;
-		}
-	else
-		sk= *x;
+    if (*x == NULL) {
+        if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
+            goto err;
+    } else
+        sk = *x;
 
-	n=sk_X509_EXTENSION_num(sk);
-	if (loc > n) loc=n;
-	else if (loc < 0) loc=n;
+    n = sk_X509_EXTENSION_num(sk);
+    if (loc > n)
+        loc = n;
+    else if (loc < 0)
+        loc = n;
 
-	if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
-		goto err2;
-	if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
-		goto err;
-	if (*x == NULL)
-		*x=sk;
-	return(sk);
-err:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-err2:
-	if (new_ex != NULL) X509_EXTENSION_free(new_ex);
-	if (sk != NULL) sk_X509_EXTENSION_free(sk);
-	return(NULL);
-	}
+    if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
+        goto err2;
+    if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
+        goto err;
+    if (*x == NULL)
+        *x = sk;
+    return (sk);
+ err:
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ err2:
+    if (new_ex != NULL)
+        X509_EXTENSION_free(new_ex);
+    if (sk != NULL)
+        sk_X509_EXTENSION_free(sk);
+    return (NULL);
+}
 
 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
-	     int crit, ASN1_OCTET_STRING *data)
-	{
-	const ASN1_OBJECT *obj;
-	X509_EXTENSION *ret;
+                                             int crit,
+                                             ASN1_OCTET_STRING *data)
+{
+    const ASN1_OBJECT *obj;
+    X509_EXTENSION *ret;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
-		return(NULL);
-		}
-	ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
-	return(ret);
-	}
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+        return (NULL);
+    }
+    ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
+    return (ret);
+}
 
 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
-	     const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data)
-	{
-	X509_EXTENSION *ret;
+                                             const ASN1_OBJECT *obj, int crit,
+                                             ASN1_OCTET_STRING *data)
+{
+    X509_EXTENSION *ret;
 
-	if ((ex == NULL) || (*ex == NULL))
-		{
-		if ((ret=X509_EXTENSION_new()) == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			return(NULL);
-			}
-		}
-	else
-		ret= *ex;
+    if ((ex == NULL) || (*ex == NULL)) {
+        if ((ret = X509_EXTENSION_new()) == NULL) {
+            OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else
+        ret = *ex;
 
-	if (!X509_EXTENSION_set_object(ret,obj))
-		goto err;
-	if (!X509_EXTENSION_set_critical(ret,crit))
-		goto err;
-	if (!X509_EXTENSION_set_data(ret,data))
-		goto err;
-	
-	if ((ex != NULL) && (*ex == NULL)) *ex=ret;
-	return(ret);
-err:
-	if ((ex == NULL) || (ret != *ex))
-		X509_EXTENSION_free(ret);
-	return(NULL);
-	}
+    if (!X509_EXTENSION_set_object(ret, obj))
+        goto err;
+    if (!X509_EXTENSION_set_critical(ret, crit))
+        goto err;
+    if (!X509_EXTENSION_set_data(ret, data))
+        goto err;
+
+    if ((ex != NULL) && (*ex == NULL))
+        *ex = ret;
+    return (ret);
+ err:
+    if ((ex == NULL) || (ret != *ex))
+        X509_EXTENSION_free(ret);
+    return (NULL);
+}
 
 int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
-	{
-	if ((ex == NULL) || (obj == NULL))
-		return(0);
-	ASN1_OBJECT_free(ex->object);
-	ex->object=OBJ_dup(obj);
-	return ex->object != NULL;
-	}
+{
+    if ((ex == NULL) || (obj == NULL))
+        return (0);
+    ASN1_OBJECT_free(ex->object);
+    ex->object = OBJ_dup(obj);
+    return ex->object != NULL;
+}
 
 int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
-	{
-	if (ex == NULL) return(0);
-	ex->critical=(crit)?0xFF:-1;
-	return(1);
-	}
+{
+    if (ex == NULL)
+        return (0);
+    ex->critical = (crit) ? 0xFF : -1;
+    return (1);
+}
 
 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
-	{
-	int i;
+{
+    int i;
 
-	if (ex == NULL) return(0);
-	i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length);
-	if (!i) return(0);
-	return(1);
-	}
+    if (ex == NULL)
+        return (0);
+    i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length);
+    if (!i)
+        return (0);
+    return (1);
+}
 
 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
-	{
-	if (ex == NULL) return(NULL);
-	return(ex->object);
-	}
+{
+    if (ex == NULL)
+        return (NULL);
+    return (ex->object);
+}
 
 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
-	{
-	if (ex == NULL) return(NULL);
-	return(ex->value);
-	}
+{
+    if (ex == NULL)
+        return (NULL);
+    return (ex->value);
+}
 
 int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
-	{
-	if (ex == NULL) return(0);
-	if(ex->critical > 0) return 1;
-	return 0;
-	}
+{
+    if (ex == NULL)
+        return (0);
+    if (ex->critical > 0)
+        return 1;
+    return 0;
+}
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index c62a6f5..2ed2f03 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -71,27 +71,26 @@
 #include "vpm_int.h"
 #include "../internal.h"
 
-
 static CRYPTO_EX_DATA_CLASS g_ex_data_class =
-	CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
 
 /* CRL score values */
 
 /* No unhandled critical extensions */
 
-#define CRL_SCORE_NOCRITICAL	0x100
+#define CRL_SCORE_NOCRITICAL    0x100
 
 /* certificate is within CRL scope */
 
-#define CRL_SCORE_SCOPE		0x080
+#define CRL_SCORE_SCOPE         0x080
 
 /* CRL times valid */
 
-#define CRL_SCORE_TIME		0x040
+#define CRL_SCORE_TIME          0x040
 
 /* Issuer name matches certificate */
 
-#define CRL_SCORE_ISSUER_NAME	0x020
+#define CRL_SCORE_ISSUER_NAME   0x020
 
 /* If this score or above CRL is probably valid */
 
@@ -99,21 +98,21 @@
 
 /* CRL issuer is certificate issuer */
 
-#define CRL_SCORE_ISSUER_CERT	0x018
+#define CRL_SCORE_ISSUER_CERT   0x018
 
 /* CRL issuer is on certificate path */
 
-#define CRL_SCORE_SAME_PATH	0x008
+#define CRL_SCORE_SAME_PATH     0x008
 
 /* CRL issuer matches CRL AKID */
 
-#define CRL_SCORE_AKID		0x004
+#define CRL_SCORE_AKID          0x004
 
 /* Have a delta CRL with valid times */
 
-#define CRL_SCORE_TIME_DELTA	0x002
+#define CRL_SCORE_TIME_DELTA    0x002
 
-static int null_callback(int ok,X509_STORE_CTX *e);
+static int null_callback(int ok, X509_STORE_CTX *e);
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
 static int check_chain_extensions(X509_STORE_CTX *ctx);
@@ -125,2336 +124,2284 @@
 static int check_policy(X509_STORE_CTX *ctx);
 
 static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
-			unsigned int *preasons,
-			X509_CRL *crl, X509 *x);
+                         unsigned int *preasons, X509_CRL *crl, X509 *x);
 static int get_crl_delta(X509_STORE_CTX *ctx,
-				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
-static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
-			X509_CRL *base, STACK_OF(X509_CRL) *crls);
-static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
-				X509 **pissuer, int *pcrl_score);
+                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
+                         int *pcrl_score, X509_CRL *base,
+                         STACK_OF(X509_CRL) *crls);
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
+                           int *pcrl_score);
 static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
-				unsigned int *preasons);
+                           unsigned int *preasons);
 static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
 static int check_crl_chain(X509_STORE_CTX *ctx,
-			STACK_OF(X509) *cert_path,
-			STACK_OF(X509) *crl_path);
+                           STACK_OF(X509) *cert_path,
+                           STACK_OF(X509) *crl_path);
 
 static int internal_verify(X509_STORE_CTX *ctx);
 
-
 static int null_callback(int ok, X509_STORE_CTX *e)
-	{
-	return ok;
-	}
+{
+    return ok;
+}
 
 #if 0
 static int x509_subject_cmp(X509 **a, X509 **b)
-	{
-	return X509_subject_name_cmp(*a,*b);
-	}
+{
+    return X509_subject_name_cmp(*a, *b);
+}
 #endif
 /* Return 1 is a certificate is self signed */
 static int cert_self_signed(X509 *x)
-	{
-	X509_check_purpose(x, -1, 0);
-	if (x->ex_flags & EXFLAG_SS)
-		return 1;
-	else
-		return 0;
-	}
+{
+    X509_check_purpose(x, -1, 0);
+    if (x->ex_flags & EXFLAG_SS)
+        return 1;
+    else
+        return 0;
+}
 
 /* Given a certificate try and find an exact match in the store */
 
 static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
-	{
-	STACK_OF(X509) *certs;
-	X509 *xtmp = NULL;
-	size_t i;
-	/* Lookup all certs with matching subject name */
-	certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
-	if (certs == NULL)
-		return NULL;
-	/* Look for exact match */
-	for (i = 0; i < sk_X509_num(certs); i++)
-		{
-		xtmp = sk_X509_value(certs, i);
-		if (!X509_cmp(xtmp, x))
-			break;
-		}
-	if (i < sk_X509_num(certs))
-		X509_up_ref(xtmp);
-	else
-		xtmp = NULL;
-	sk_X509_pop_free(certs, X509_free);
-	return xtmp;
-	}
+{
+    STACK_OF(X509) *certs;
+    X509 *xtmp = NULL;
+    size_t i;
+    /* Lookup all certs with matching subject name */
+    certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
+    if (certs == NULL)
+        return NULL;
+    /* Look for exact match */
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        xtmp = sk_X509_value(certs, i);
+        if (!X509_cmp(xtmp, x))
+            break;
+    }
+    if (i < sk_X509_num(certs))
+        X509_up_ref(xtmp);
+    else
+        xtmp = NULL;
+    sk_X509_pop_free(certs, X509_free);
+    return xtmp;
+}
 
 int X509_verify_cert(X509_STORE_CTX *ctx)
-	{
-	X509 *x,*xtmp,*chain_ss=NULL;
-	int bad_chain = 0;
-	X509_VERIFY_PARAM *param = ctx->param;
-	int depth,i,ok=0;
-	int num;
-	int (*cb)(int xok,X509_STORE_CTX *xctx);
-	STACK_OF(X509) *sktmp=NULL;
-	if (ctx->cert == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
-		return -1;
-		}
-	if (ctx->chain != NULL)
-		{
-		/* This X509_STORE_CTX has already been used to verify a
-		 * cert. We cannot do another one. */
-		OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-		return -1;
-		}
+{
+    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
+    int bad_chain = 0;
+    X509_VERIFY_PARAM *param = ctx->param;
+    int depth, i, ok = 0;
+    int num, j, retry, trust;
+    int (*cb) (int xok, X509_STORE_CTX *xctx);
+    STACK_OF(X509) *sktmp = NULL;
+    if (ctx->cert == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+        return -1;
+    }
+    if (ctx->chain != NULL) {
+        /*
+         * This X509_STORE_CTX has already been used to verify a cert. We
+         * cannot do another one.
+         */
+        OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return -1;
+    }
 
-	cb=ctx->verify_cb;
+    cb = ctx->verify_cb;
 
-	/* first we make sure the chain we are going to build is
-	 * present and that the first entry is in place */
-	ctx->chain = sk_X509_new_null();
-	if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto end;
-		}
-	X509_up_ref(ctx->cert);
-	ctx->last_untrusted = 1;
+    /*
+     * first we make sure the chain we are going to build is present and that
+     * the first entry is in place
+     */
+    ctx->chain = sk_X509_new_null();
+    if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
+    X509_up_ref(ctx->cert);
+    ctx->last_untrusted = 1;
 
-	/* We use a temporary STACK so we can chop and hack at it */
-	if (ctx->untrusted != NULL
-	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto end;
-		}
+    /* We use a temporary STACK so we can chop and hack at it */
+    if (ctx->untrusted != NULL
+        && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
 
-	num=sk_X509_num(ctx->chain);
-	x=sk_X509_value(ctx->chain,num-1);
-	depth=param->depth;
+    num = sk_X509_num(ctx->chain);
+    x = sk_X509_value(ctx->chain, num - 1);
+    depth = param->depth;
 
+    for (;;) {
+        /* If we have enough, we break */
+        if (depth < num)
+            break;              /* FIXME: If this happens, we should take
+                                 * note of it and, if appropriate, use the
+                                 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
+                                 * later. */
 
-	for (;;)
-		{
-		/* If we have enough, we break */
-		if (depth < num) break; /* FIXME: If this happens, we should take
-		                         * note of it and, if appropriate, use the
-		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
-		                         * code later.
-		                         */
+        /* If we are self signed, we break */
+        if (cert_self_signed(x))
+            break;
+        /*
+         * If asked see if we can find issuer in trusted store first
+         */
+        if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
+            ok = ctx->get_issuer(&xtmp, ctx, x);
+            if (ok < 0)
+                goto end;
+            /*
+             * If successful for now free up cert so it will be picked up
+             * again later.
+             */
+            if (ok > 0) {
+                X509_free(xtmp);
+                break;
+            }
+        }
 
-		/* If we are self signed, we break */
-		if (cert_self_signed(x))
-			break;
-		/* If asked see if we can find issuer in trusted store first */
-		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
-			{
-			ok = ctx->get_issuer(&xtmp, ctx, x);
-			if (ok < 0)
-				goto end;
-			/* If successful for now free up cert so it
-			 * will be picked up again later.
-			 */
-			if (ok > 0)
-				{
-				X509_free(xtmp);
-				break;
-				}
-			}
+        /* If we were passed a cert chain, use it first */
+        if (ctx->untrusted != NULL) {
+            xtmp = find_issuer(ctx, sktmp, x);
+            if (xtmp != NULL) {
+                if (!sk_X509_push(ctx->chain, xtmp)) {
+                    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+                    ok = 0;
+                    goto end;
+                }
+                X509_up_ref(xtmp);
+                (void)sk_X509_delete_ptr(sktmp, xtmp);
+                ctx->last_untrusted++;
+                x = xtmp;
+                num++;
+                /*
+                 * reparse the full chain for the next one
+                 */
+                continue;
+            }
+        }
+        break;
+    }
 
-		/* If we were passed a cert chain, use it first */
-		if (ctx->untrusted != NULL)
-			{
-			xtmp=find_issuer(ctx, sktmp,x);
-			if (xtmp != NULL)
-				{
-				if (!sk_X509_push(ctx->chain,xtmp))
-					{
-					OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-					goto end;
-					}
-				X509_up_ref(xtmp);
-				(void)sk_X509_delete_ptr(sktmp,xtmp);
-				ctx->last_untrusted++;
-				x=xtmp;
-				num++;
-				/* reparse the full chain for
-				 * the next one */
-				continue;
-				}
-			}
-		break;
-		}
+    /* Remember how many untrusted certs we have */
+    j = num;
+    /*
+     * at this point, chain should contain a list of untrusted certificates.
+     * We now need to add at least one trusted one, if possible, otherwise we
+     * complain.
+     */
 
-	/* at this point, chain should contain a list of untrusted
-	 * certificates.  We now need to add at least one trusted one,
-	 * if possible, otherwise we complain. */
+    do {
+        /*
+         * Examine last certificate in chain and see if it is self signed.
+         */
+        i = sk_X509_num(ctx->chain);
+        x = sk_X509_value(ctx->chain, i - 1);
+        if (cert_self_signed(x)) {
+            /* we have a self signed certificate */
+            if (sk_X509_num(ctx->chain) == 1) {
+                /*
+                 * We have a single self signed certificate: see if we can
+                 * find it in the store. We must have an exact match to avoid
+                 * possible impersonation.
+                 */
+                ok = ctx->get_issuer(&xtmp, ctx, x);
+                if ((ok <= 0) || X509_cmp(x, xtmp)) {
+                    ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+                    ctx->current_cert = x;
+                    ctx->error_depth = i - 1;
+                    if (ok == 1)
+                        X509_free(xtmp);
+                    bad_chain = 1;
+                    ok = cb(0, ctx);
+                    if (!ok)
+                        goto end;
+                } else {
+                    /*
+                     * We have a match: replace certificate with store
+                     * version so we get any trust settings.
+                     */
+                    X509_free(x);
+                    x = xtmp;
+                    (void)sk_X509_set(ctx->chain, i - 1, x);
+                    ctx->last_untrusted = 0;
+                }
+            } else {
+                /*
+                 * extract and save self signed certificate for later use
+                 */
+                chain_ss = sk_X509_pop(ctx->chain);
+                ctx->last_untrusted--;
+                num--;
+                j--;
+                x = sk_X509_value(ctx->chain, num - 1);
+            }
+        }
+        /* We now lookup certs from the certificate store */
+        for (;;) {
+            /* If we have enough, we break */
+            if (depth < num)
+                break;
+            /* If we are self signed, we break */
+            if (cert_self_signed(x))
+                break;
+            ok = ctx->get_issuer(&xtmp, ctx, x);
 
-	/* Examine last certificate in chain and see if it
- 	 * is self signed.
- 	 */
+            if (ok < 0)
+                goto end;
+            if (ok == 0)
+                break;
+            x = xtmp;
+            if (!sk_X509_push(ctx->chain, x)) {
+                X509_free(xtmp);
+                OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+                ok = 0;
+                goto end;
+            }
+            num++;
+        }
 
-	i=sk_X509_num(ctx->chain);
-	x=sk_X509_value(ctx->chain,i-1);
-	if (cert_self_signed(x))
-		{
-		/* we have a self signed certificate */
-		if (sk_X509_num(ctx->chain) == 1)
-			{
-			/* We have a single self signed certificate: see if
-			 * we can find it in the store. We must have an exact
-			 * match to avoid possible impersonation.
-			 */
-			ok = ctx->get_issuer(&xtmp, ctx, x);
-			if ((ok <= 0) || X509_cmp(x, xtmp)) 
-				{
-				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
-				ctx->current_cert=x;
-				ctx->error_depth=i-1;
-				if (ok == 1) X509_free(xtmp);
-				bad_chain = 1;
-				ok=cb(0,ctx);
-				if (!ok) goto end;
-				}
-			else 
-				{
-				/* We have a match: replace certificate with store version
-				 * so we get any trust settings.
-				 */
-				X509_free(x);
-				x = xtmp;
-				(void)sk_X509_set(ctx->chain, i - 1, x);
-				ctx->last_untrusted=0;
-				}
-			}
-		else
-			{
-			/* extract and save self signed certificate for later use */
-			chain_ss=sk_X509_pop(ctx->chain);
-			ctx->last_untrusted--;
-			num--;
-			x=sk_X509_value(ctx->chain,num-1);
-			}
-		}
+        /* we now have our chain, lets check it... */
+        trust = check_trust(ctx);
 
-	/* We now lookup certs from the certificate store */
-	for (;;)
-		{
-		/* If we have enough, we break */
-		if (depth < num) break;
+        /* If explicitly rejected error */
+        if (trust == X509_TRUST_REJECTED) {
+            ok = 0;
+            goto end;
+        }
+        /*
+         * If it's not explicitly trusted then check if there is an alternative
+         * chain that could be used. We only do this if we haven't already
+         * checked via TRUSTED_FIRST and the user hasn't switched off alternate
+         * chain checking
+         */
+        retry = 0;
+        if (trust != X509_TRUST_TRUSTED
+            && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+            && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+            while (j-- > 1) {
+                xtmp2 = sk_X509_value(ctx->chain, j - 1);
+                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+                if (ok < 0)
+                    goto end;
+                /* Check if we found an alternate chain */
+                if (ok > 0) {
+                    /*
+                     * Free up the found cert we'll add it again later
+                     */
+                    X509_free(xtmp);
 
-		/* If we are self signed, we break */
-		if (cert_self_signed(x))
-			break;
+                    /*
+                     * Dump all the certs above this point - we've found an
+                     * alternate chain
+                     */
+                    while (num > j) {
+                        xtmp = sk_X509_pop(ctx->chain);
+                        X509_free(xtmp);
+                        num--;
+                    }
+                    ctx->last_untrusted = sk_X509_num(ctx->chain);
+                    retry = 1;
+                    break;
+                }
+            }
+        }
+    } while (retry);
 
-		ok = ctx->get_issuer(&xtmp, ctx, x);
+    /*
+     * If not explicitly trusted then indicate error unless it's a single
+     * self signed certificate in which case we've indicated an error already
+     * and set bad_chain == 1
+     */
+    if (trust != X509_TRUST_TRUSTED && !bad_chain) {
+        if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
+            if (ctx->last_untrusted >= num)
+                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
+            else
+                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+            ctx->current_cert = x;
+        } else {
 
-		if (ok < 0) goto end;
-		if (ok == 0) break;
+            sk_X509_push(ctx->chain, chain_ss);
+            num++;
+            ctx->last_untrusted = num;
+            ctx->current_cert = chain_ss;
+            ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
+            chain_ss = NULL;
+        }
 
-		x = xtmp;
-		if (!sk_X509_push(ctx->chain,x))
-			{
-			X509_free(xtmp);
-			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-			ok = 0;
-			goto end;
-			}
-		num++;
-		}
+        ctx->error_depth = num - 1;
+        bad_chain = 1;
+        ok = cb(0, ctx);
+        if (!ok)
+            goto end;
+    }
 
-	/* we now have our chain, lets check it... */
+    /* We have the chain complete: now we need to check its purpose */
+    ok = check_chain_extensions(ctx);
 
-	i = check_trust(ctx);
+    if (!ok)
+        goto end;
 
-	/* If explicitly rejected error */
-	if (i == X509_TRUST_REJECTED)
-		goto end;
-	/* If not explicitly trusted then indicate error unless it's
-	 * a single self signed certificate in which case we've indicated
-	 * an error already and set bad_chain == 1
-	 */
-	if (i != X509_TRUST_TRUSTED && !bad_chain)
-		{
-		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
-			{
-			if (ctx->last_untrusted >= num)
-				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
-			else
-				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
-			ctx->current_cert=x;
-			}
-		else
-			{
+    /* Check name constraints */
 
-			sk_X509_push(ctx->chain,chain_ss);
-			num++;
-			ctx->last_untrusted=num;
-			ctx->current_cert=chain_ss;
-			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
-			chain_ss=NULL;
-			}
+    ok = check_name_constraints(ctx);
 
-		ctx->error_depth=num-1;
-		bad_chain = 1;
-		ok=cb(0,ctx);
-		if (!ok) goto end;
-		}
+    if (!ok)
+        goto end;
 
-	/* We have the chain complete: now we need to check its purpose */
-	ok = check_chain_extensions(ctx);
+    ok = check_id(ctx);
 
-	if (!ok) goto end;
+    if (!ok)
+        goto end;
 
-	/* Check name constraints */
+    /*
+     * Check revocation status: we do this after copying parameters because
+     * they may be needed for CRL signature verification.
+     */
 
-	ok = check_name_constraints(ctx);
-	
-	if (!ok) goto end;
+    ok = ctx->check_revocation(ctx);
+    if (!ok)
+        goto end;
 
-	ok = check_id(ctx);
+    int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+                                      ctx->param->flags);
+    if (err != X509_V_OK) {
+        ctx->error = err;
+        ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
+        ok = cb(0, ctx);
+        if (!ok)
+            goto end;
+    }
 
-	if (!ok) goto end;
+    /* At this point, we have a chain and need to verify it */
+    if (ctx->verify != NULL)
+        ok = ctx->verify(ctx);
+    else
+        ok = internal_verify(ctx);
+    if (!ok)
+        goto end;
 
-	/* Check revocation status: we do this after copying parameters
-	 * because they may be needed for CRL signature verification.
-	 */
+    /* If we get this far evaluate policies */
+    if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
+        ok = ctx->check_policy(ctx);
 
-	ok = ctx->check_revocation(ctx);
-	if(!ok) goto end;
+ end:
+    if (sktmp != NULL)
+        sk_X509_free(sktmp);
+    if (chain_ss != NULL)
+        X509_free(chain_ss);
+    return ok;
+}
 
-	i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
-							ctx->param->flags);
-	if (i != X509_V_OK)
-		{
-		ctx->error = i;
-		ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
-		ok = cb(0, ctx);
-		if (!ok)
-			goto end;
-		}
-
-	/* At this point, we have a chain and need to verify it */
-	if (ctx->verify != NULL)
-		ok=ctx->verify(ctx);
-	else
-		ok=internal_verify(ctx);
-	if(!ok) goto end;
-
-	/* If we get this far evaluate policies */
-	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
-		ok = ctx->check_policy(ctx);
-
-end:
-	if (sktmp != NULL) sk_X509_free(sktmp);
-	if (chain_ss != NULL) X509_free(chain_ss);
-	return ok;
-	}
-
-
-/* Given a STACK_OF(X509) find the issuer of cert (if any)
+/*
+ * Given a STACK_OF(X509) find the issuer of cert (if any)
  */
 
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
 {
-	size_t i;
-	X509 *issuer;
-	for (i = 0; i < sk_X509_num(sk); i++)
-		{
-		issuer = sk_X509_value(sk, i);
-		if (ctx->check_issued(ctx, x, issuer))
-			return issuer;
-		}
-	return NULL;
+    size_t i;
+    X509 *issuer;
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        issuer = sk_X509_value(sk, i);
+        if (ctx->check_issued(ctx, x, issuer))
+            return issuer;
+    }
+    return NULL;
 }
 
 /* Given a possible certificate and issuer check them */
 
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
 {
-	int ret;
-	ret = X509_check_issued(issuer, x);
-	if (ret == X509_V_OK)
-		return 1;
-	/* If we haven't asked for issuer errors don't set ctx */
-	if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
-		return 0;
+    int ret;
+    ret = X509_check_issued(issuer, x);
+    if (ret == X509_V_OK)
+        return 1;
+    /* If we haven't asked for issuer errors don't set ctx */
+    if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
+        return 0;
 
-	ctx->error = ret;
-	ctx->current_cert = x;
-	ctx->current_issuer = issuer;
-	return ctx->verify_cb(0, ctx);
+    ctx->error = ret;
+    ctx->current_cert = x;
+    ctx->current_issuer = issuer;
+    return ctx->verify_cb(0, ctx);
 }
 
 /* Alternative lookup method: look from a STACK stored in other_ctx */
 
 static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
 {
-	*issuer = find_issuer(ctx, ctx->other_ctx, x);
-	if (*issuer)
-		{
-		X509_up_ref(*issuer);
-		return 1;
-		}
-	else
-		return 0;
+    *issuer = find_issuer(ctx, ctx->other_ctx, x);
+    if (*issuer) {
+        X509_up_ref(*issuer);
+        return 1;
+    } else
+        return 0;
 }
-	
 
-/* Check a certificate chains extensions for consistency
- * with the supplied purpose
+/*
+ * Check a certificate chains extensions for consistency with the supplied
+ * purpose
  */
 
 static int check_chain_extensions(X509_STORE_CTX *ctx)
 {
-	int i, ok=0, must_be_ca, plen = 0;
-	X509 *x;
-	int (*cb)(int xok,X509_STORE_CTX *xctx);
-	int proxy_path_length = 0;
-	int purpose;
-	int allow_proxy_certs;
-	cb=ctx->verify_cb;
+    int i, ok = 0, must_be_ca, plen = 0;
+    X509 *x;
+    int (*cb) (int xok, X509_STORE_CTX *xctx);
+    int proxy_path_length = 0;
+    int purpose;
+    int allow_proxy_certs;
+    cb = ctx->verify_cb;
 
-	/* must_be_ca can have 1 of 3 values:
-	   -1: we accept both CA and non-CA certificates, to allow direct
-	       use of self-signed certificates (which are marked as CA).
-	   0:  we only accept non-CA certificates.  This is currently not
-	       used, but the possibility is present for future extensions.
-	   1:  we only accept CA certificates.  This is currently used for
-	       all certificates in the chain except the leaf certificate.
-	*/
-	must_be_ca = -1;
+    /*
+     * must_be_ca can have 1 of 3 values: -1: we accept both CA and non-CA
+     * certificates, to allow direct use of self-signed certificates (which
+     * are marked as CA). 0: we only accept non-CA certificates.  This is
+     * currently not used, but the possibility is present for future
+     * extensions. 1: we only accept CA certificates.  This is currently used
+     * for all certificates in the chain except the leaf certificate.
+     */
+    must_be_ca = -1;
 
-	/* CRL path validation */
-	if (ctx->parent)
-		{
-		allow_proxy_certs = 0;
-		purpose = X509_PURPOSE_CRL_SIGN;
-		}
-	else
-		{
-		allow_proxy_certs =
-			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
-		/* A hack to keep people who don't want to modify their
-		   software happy */
-		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
-			allow_proxy_certs = 1;
-		purpose = ctx->param->purpose;
-		}
+    /* CRL path validation */
+    if (ctx->parent) {
+        allow_proxy_certs = 0;
+        purpose = X509_PURPOSE_CRL_SIGN;
+    } else {
+        allow_proxy_certs =
+            ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+        /*
+         * A hack to keep people who don't want to modify their software
+         * happy
+         */
+        if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+            allow_proxy_certs = 1;
+        purpose = ctx->param->purpose;
+    }
 
-	/* Check all untrusted certificates */
-	for (i = 0; i < ctx->last_untrusted; i++)
-		{
-		int ret;
-		x = sk_X509_value(ctx->chain, i);
-		if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
-			&& (x->ex_flags & EXFLAG_CRITICAL))
-			{
-			ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
-			ctx->error_depth = i;
-			ctx->current_cert = x;
-			ok=cb(0,ctx);
-			if (!ok) goto end;
-			}
-		if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
-			{
-			ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
-			ctx->error_depth = i;
-			ctx->current_cert = x;
-			ok=cb(0,ctx);
-			if (!ok) goto end;
-			}
-		ret = X509_check_ca(x);
-		switch(must_be_ca)
-			{
-		case -1:
-			if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
-				&& (ret != 1) && (ret != 0))
-				{
-				ret = 0;
-				ctx->error = X509_V_ERR_INVALID_CA;
-				}
-			else
-				ret = 1;
-			break;
-		case 0:
-			if (ret != 0)
-				{
-				ret = 0;
-				ctx->error = X509_V_ERR_INVALID_NON_CA;
-				}
-			else
-				ret = 1;
-			break;
-		default:
-			if ((ret == 0)
-				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
-					&& (ret != 1)))
-				{
-				ret = 0;
-				ctx->error = X509_V_ERR_INVALID_CA;
-				}
-			else
-				ret = 1;
-			break;
-			}
-		if (ret == 0)
-			{
-			ctx->error_depth = i;
-			ctx->current_cert = x;
-			ok=cb(0,ctx);
-			if (!ok) goto end;
-			}
-		if (ctx->param->purpose > 0)
-			{
-			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
-			if ((ret == 0)
-				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
-					&& (ret != 1)))
-				{
-				ctx->error = X509_V_ERR_INVALID_PURPOSE;
-				ctx->error_depth = i;
-				ctx->current_cert = x;
-				ok=cb(0,ctx);
-				if (!ok) goto end;
-				}
-			}
-		/* Check pathlen if not self issued */
-		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
-			   && (x->ex_pathlen != -1)
-			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
-			{
-			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
-			ctx->error_depth = i;
-			ctx->current_cert = x;
-			ok=cb(0,ctx);
-			if (!ok) goto end;
-			}
-		/* Increment path length if not self issued */
-		if (!(x->ex_flags & EXFLAG_SI))
-			plen++;
-		/* If this certificate is a proxy certificate, the next
-		   certificate must be another proxy certificate or a EE
-		   certificate.  If not, the next certificate must be a
-		   CA certificate.  */
-		if (x->ex_flags & EXFLAG_PROXY)
-			{
-			if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
-				{
-				ctx->error =
-					X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
-				ctx->error_depth = i;
-				ctx->current_cert = x;
-				ok=cb(0,ctx);
-				if (!ok) goto end;
-				}
-			proxy_path_length++;
-			must_be_ca = 0;
-			}
-		else
-			must_be_ca = 1;
-		}
-	ok = 1;
+    /* Check all untrusted certificates */
+    for (i = 0; i < ctx->last_untrusted; i++) {
+        int ret;
+        x = sk_X509_value(ctx->chain, i);
+        if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+            && (x->ex_flags & EXFLAG_CRITICAL)) {
+            ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
+            ctx->error_depth = i;
+            ctx->current_cert = x;
+            ok = cb(0, ctx);
+            if (!ok)
+                goto end;
+        }
+        if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
+            ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+            ctx->error_depth = i;
+            ctx->current_cert = x;
+            ok = cb(0, ctx);
+            if (!ok)
+                goto end;
+        }
+        ret = X509_check_ca(x);
+        switch (must_be_ca) {
+        case -1:
+            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+                && (ret != 1) && (ret != 0)) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_CA;
+            } else
+                ret = 1;
+            break;
+        case 0:
+            if (ret != 0) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_NON_CA;
+            } else
+                ret = 1;
+            break;
+        default:
+            if ((ret == 0)
+                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+                    && (ret != 1))) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_CA;
+            } else
+                ret = 1;
+            break;
+        }
+        if (ret == 0) {
+            ctx->error_depth = i;
+            ctx->current_cert = x;
+            ok = cb(0, ctx);
+            if (!ok)
+                goto end;
+        }
+        if (ctx->param->purpose > 0) {
+            ret = X509_check_purpose(x, purpose, must_be_ca > 0);
+            if ((ret == 0)
+                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+                    && (ret != 1))) {
+                ctx->error = X509_V_ERR_INVALID_PURPOSE;
+                ctx->error_depth = i;
+                ctx->current_cert = x;
+                ok = cb(0, ctx);
+                if (!ok)
+                    goto end;
+            }
+        }
+        /* Check pathlen if not self issued */
+        if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+            && (x->ex_pathlen != -1)
+            && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
+            ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
+            ctx->error_depth = i;
+            ctx->current_cert = x;
+            ok = cb(0, ctx);
+            if (!ok)
+                goto end;
+        }
+        /* Increment path length if not self issued */
+        if (!(x->ex_flags & EXFLAG_SI))
+            plen++;
+        /*
+         * If this certificate is a proxy certificate, the next certificate
+         * must be another proxy certificate or a EE certificate.  If not,
+         * the next certificate must be a CA certificate.
+         */
+        if (x->ex_flags & EXFLAG_PROXY) {
+            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
+                ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+                ctx->error_depth = i;
+                ctx->current_cert = x;
+                ok = cb(0, ctx);
+                if (!ok)
+                    goto end;
+            }
+            proxy_path_length++;
+            must_be_ca = 0;
+        } else
+            must_be_ca = 1;
+    }
+    ok = 1;
  end:
-	return ok;
+    return ok;
 }
 
 static int check_name_constraints(X509_STORE_CTX *ctx)
-	{
-	X509 *x;
-	int i, j, rv;
-	/* Check name constraints for all certificates */
-	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
-		{
-		x = sk_X509_value(ctx->chain, i);
-		/* Ignore self issued certs unless last in chain */
-		if (i && (x->ex_flags & EXFLAG_SI))
-			continue;
-		/* Check against constraints for all certificates higher in
-		 * chain including trust anchor. Trust anchor not strictly
-		 * speaking needed but if it includes constraints it is to be
-		 * assumed it expects them to be obeyed.
-		 */
-		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
-			{
-			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
-			if (nc)
-				{
-				rv = NAME_CONSTRAINTS_check(x, nc);
-				if (rv != X509_V_OK)
-					{
-					ctx->error = rv;
-					ctx->error_depth = i;
-					ctx->current_cert = x;
-					if (!ctx->verify_cb(0,ctx))
-						return 0;
-					}
-				}
-			}
-		}
-	return 1;
-	}
+{
+    X509 *x;
+    int i, j, rv;
+    /* Check name constraints for all certificates */
+    for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
+        x = sk_X509_value(ctx->chain, i);
+        /* Ignore self issued certs unless last in chain */
+        if (i && (x->ex_flags & EXFLAG_SI))
+            continue;
+        /*
+         * Check against constraints for all certificates higher in chain
+         * including trust anchor. Trust anchor not strictly speaking needed
+         * but if it includes constraints it is to be assumed it expects them
+         * to be obeyed.
+         */
+        for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
+            NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+            if (nc) {
+                rv = NAME_CONSTRAINTS_check(x, nc);
+                if (rv != X509_V_OK) {
+                    ctx->error = rv;
+                    ctx->error_depth = i;
+                    ctx->current_cert = x;
+                    if (!ctx->verify_cb(0, ctx))
+                        return 0;
+                }
+            }
+        }
+    }
+    return 1;
+}
 
 static int check_id_error(X509_STORE_CTX *ctx, int errcode)
-	{
-	ctx->error = errcode;
-	ctx->current_cert = ctx->cert;
-	ctx->error_depth = 0;
-	return ctx->verify_cb(0, ctx);
-	}
+{
+    ctx->error = errcode;
+    ctx->current_cert = ctx->cert;
+    ctx->error_depth = 0;
+    return ctx->verify_cb(0, ctx);
+}
 
 static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
-	{
-	size_t i;
-	size_t n = sk_OPENSSL_STRING_num(id->hosts);
-	char *name;
+{
+    size_t i;
+    size_t n = sk_OPENSSL_STRING_num(id->hosts);
+    char *name;
 
-	for (i = 0; i < n; ++i)
-		{
-		name = sk_OPENSSL_STRING_value(id->hosts, i);
-		if (X509_check_host(x, name, strlen(name), id->hostflags,
-				    &id->peername) > 0)
-			return 1;
-		}
-	return n == 0;
-	}
+    if (id->peername != NULL) {
+        OPENSSL_free(id->peername);
+        id->peername = NULL;
+    }
+    for (i = 0; i < n; ++i) {
+        name = sk_OPENSSL_STRING_value(id->hosts, i);
+        if (X509_check_host(x, name, strlen(name), id->hostflags,
+                            &id->peername) > 0)
+            return 1;
+    }
+    return n == 0;
+}
 
 static int check_id(X509_STORE_CTX *ctx)
-	{
-	X509_VERIFY_PARAM *vpm = ctx->param;
-	X509_VERIFY_PARAM_ID *id = vpm->id;
-	X509 *x = ctx->cert;
-	if (id->hosts && check_hosts(x, id) <= 0)
-		{
-		if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
-			return 0;
-		}
-	if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0)
-		{
-		if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
-			return 0;
-		}
-	if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0)
-		{
-		if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
-			return 0;
-		}
-	return 1;
-	}
+{
+    X509_VERIFY_PARAM *vpm = ctx->param;
+    X509_VERIFY_PARAM_ID *id = vpm->id;
+    X509 *x = ctx->cert;
+    if (id->hosts && check_hosts(x, id) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
+            return 0;
+    }
+    if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
+            return 0;
+    }
+    if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
+            return 0;
+    }
+    return 1;
+}
 
 static int check_trust(X509_STORE_CTX *ctx)
 {
-	size_t i;
-	int ok;
-	X509 *x = NULL;
-	int (*cb)(int xok,X509_STORE_CTX *xctx);
-	cb=ctx->verify_cb;
-	/* Check all trusted certificates in chain */
-	for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++)
-		{
-		x = sk_X509_value(ctx->chain, i);
-		ok = X509_check_trust(x, ctx->param->trust, 0);
-		/* If explicitly trusted return trusted */
-		if (ok == X509_TRUST_TRUSTED)
-			return X509_TRUST_TRUSTED;
-		/* If explicitly rejected notify callback and reject if
-		 * not overridden.
-		 */
-		if (ok == X509_TRUST_REJECTED)
-			{
-			ctx->error_depth = i;
-			ctx->current_cert = x;
-			ctx->error = X509_V_ERR_CERT_REJECTED;
-			ok = cb(0, ctx);
-			if (!ok)
-				return X509_TRUST_REJECTED;
-			}
-		}
-	/* If we accept partial chains and have at least one trusted
-	 * certificate return success.
-	 */
-	if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
-		{
-		X509 *mx;
-		if (ctx->last_untrusted < (int) sk_X509_num(ctx->chain))
-			return X509_TRUST_TRUSTED;
-		x = sk_X509_value(ctx->chain, 0);
-		mx = lookup_cert_match(ctx, x);
-		if (mx)
-			{
-			(void)sk_X509_set(ctx->chain, 0, mx);
-			X509_free(x);
-			ctx->last_untrusted = 0;
-			return X509_TRUST_TRUSTED;
-			}
-		}
+    size_t i;
+    int ok;
+    X509 *x = NULL;
+    int (*cb) (int xok, X509_STORE_CTX *xctx);
+    cb = ctx->verify_cb;
+    /* Check all trusted certificates in chain */
+    for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
+        x = sk_X509_value(ctx->chain, i);
+        ok = X509_check_trust(x, ctx->param->trust, 0);
+        /* If explicitly trusted return trusted */
+        if (ok == X509_TRUST_TRUSTED)
+            return X509_TRUST_TRUSTED;
+        /*
+         * If explicitly rejected notify callback and reject if not
+         * overridden.
+         */
+        if (ok == X509_TRUST_REJECTED) {
+            ctx->error_depth = i;
+            ctx->current_cert = x;
+            ctx->error = X509_V_ERR_CERT_REJECTED;
+            ok = cb(0, ctx);
+            if (!ok)
+                return X509_TRUST_REJECTED;
+        }
+    }
+    /*
+     * If we accept partial chains and have at least one trusted certificate
+     * return success.
+     */
+    if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+        X509 *mx;
+        if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
+            return X509_TRUST_TRUSTED;
+        x = sk_X509_value(ctx->chain, 0);
+        mx = lookup_cert_match(ctx, x);
+        if (mx) {
+            (void)sk_X509_set(ctx->chain, 0, mx);
+            X509_free(x);
+            ctx->last_untrusted = 0;
+            return X509_TRUST_TRUSTED;
+        }
+    }
 
-	/* If no trusted certs in chain at all return untrusted and
-	 * allow standard (no issuer cert) etc errors to be indicated.
-	 */
-	return X509_TRUST_UNTRUSTED;
+    /*
+     * If no trusted certs in chain at all return untrusted and allow
+     * standard (no issuer cert) etc errors to be indicated.
+     */
+    return X509_TRUST_UNTRUSTED;
 }
 
 static int check_revocation(X509_STORE_CTX *ctx)
-	{
-	int i, last, ok;
-	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
-		return 1;
-	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
-		last = sk_X509_num(ctx->chain) - 1;
-	else
-		{
-		/* If checking CRL paths this isn't the EE certificate */
-		if (ctx->parent)
-			return 1;
-		last = 0;
-		}
-	for(i = 0; i <= last; i++)
-		{
-		ctx->error_depth = i;
-		ok = check_cert(ctx);
-		if (!ok) return ok;
-		}
-	return 1;
-	}
+{
+    int i, last, ok;
+    if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
+        return 1;
+    if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
+        last = sk_X509_num(ctx->chain) - 1;
+    else {
+        /* If checking CRL paths this isn't the EE certificate */
+        if (ctx->parent)
+            return 1;
+        last = 0;
+    }
+    for (i = 0; i <= last; i++) {
+        ctx->error_depth = i;
+        ok = check_cert(ctx);
+        if (!ok)
+            return ok;
+    }
+    return 1;
+}
 
 static int check_cert(X509_STORE_CTX *ctx)
-                      OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-	{
-	X509_CRL *crl = NULL, *dcrl = NULL;
-	X509 *x;
-	int ok, cnum;
-	unsigned int last_reasons;
-	cnum = ctx->error_depth;
-	x = sk_X509_value(ctx->chain, cnum);
-	ctx->current_cert = x;
-	ctx->current_issuer = NULL;
-	ctx->current_crl_score = 0;
-	ctx->current_reasons = 0;
-	while (ctx->current_reasons != CRLDP_ALL_REASONS)
-		{
-		last_reasons = ctx->current_reasons;
-		/* Try to retrieve relevant CRL */
-		if (ctx->get_crl)
-			ok = ctx->get_crl(ctx, &crl, x);
-		else
-			ok = get_crl_delta(ctx, &crl, &dcrl, x);
-		/* If error looking up CRL, nothing we can do except
-		 * notify callback
-		 */
-		if(!ok)
-			{
-			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
-			ok = ctx->verify_cb(0, ctx);
-			goto err;
-			}
-		ctx->current_crl = crl;
-		ok = ctx->check_crl(ctx, crl);
-		if (!ok)
-			goto err;
+{
+    X509_CRL *crl = NULL, *dcrl = NULL;
+    X509 *x;
+    int ok = 0, cnum;
+    unsigned int last_reasons;
+    cnum = ctx->error_depth;
+    x = sk_X509_value(ctx->chain, cnum);
+    ctx->current_cert = x;
+    ctx->current_issuer = NULL;
+    ctx->current_crl_score = 0;
+    ctx->current_reasons = 0;
+    while (ctx->current_reasons != CRLDP_ALL_REASONS) {
+        last_reasons = ctx->current_reasons;
+        /* Try to retrieve relevant CRL */
+        if (ctx->get_crl)
+            ok = ctx->get_crl(ctx, &crl, x);
+        else
+            ok = get_crl_delta(ctx, &crl, &dcrl, x);
+        /*
+         * If error looking up CRL, nothing we can do except notify callback
+         */
+        if (!ok) {
+            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+            ok = ctx->verify_cb(0, ctx);
+            goto err;
+        }
+        ctx->current_crl = crl;
+        ok = ctx->check_crl(ctx, crl);
+        if (!ok)
+            goto err;
 
-		if (dcrl)
-			{
-			ok = ctx->check_crl(ctx, dcrl);
-			if (!ok)
-				goto err;
-			ok = ctx->cert_crl(ctx, dcrl, x);
-			if (!ok)
-				goto err;
-			}
-		else
-			ok = 1;
+        if (dcrl) {
+            ok = ctx->check_crl(ctx, dcrl);
+            if (!ok)
+                goto err;
+            ok = ctx->cert_crl(ctx, dcrl, x);
+            if (!ok)
+                goto err;
+        } else
+            ok = 1;
 
-		/* Don't look in full CRL if delta reason is removefromCRL */
-		if (ok != 2)
-			{
-			ok = ctx->cert_crl(ctx, crl, x);
-			if (!ok)
-				goto err;
-			}
+        /* Don't look in full CRL if delta reason is removefromCRL */
+        if (ok != 2) {
+            ok = ctx->cert_crl(ctx, crl, x);
+            if (!ok)
+                goto err;
+        }
 
-		X509_CRL_free(crl);
-		X509_CRL_free(dcrl);
-		crl = NULL;
-		dcrl = NULL;
-		/* If reasons not updated we wont get anywhere by
-		 * another iteration, so exit loop.
-		 */
-		if (last_reasons == ctx->current_reasons)
-			{
-			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
-			ok = ctx->verify_cb(0, ctx);
-			goto err;
-			}
-		}
-	err:
-	X509_CRL_free(crl);
-	X509_CRL_free(dcrl);
+        X509_CRL_free(crl);
+        X509_CRL_free(dcrl);
+        crl = NULL;
+        dcrl = NULL;
+        /*
+         * If reasons not updated we wont get anywhere by another iteration,
+         * so exit loop.
+         */
+        if (last_reasons == ctx->current_reasons) {
+            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+            ok = ctx->verify_cb(0, ctx);
+            goto err;
+        }
+    }
+ err:
+    X509_CRL_free(crl);
+    X509_CRL_free(dcrl);
 
-	ctx->current_crl = NULL;
-	return ok;
+    ctx->current_crl = NULL;
+    return ok;
 
-	}
+}
 
 /* Check CRL times against values in X509_STORE_CTX */
 
 static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
-	{
-	time_t *ptime;
-	int i;
-	if (notify)
-		ctx->current_crl = crl;
-	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
-		ptime = &ctx->param->check_time;
-	else
-		ptime = NULL;
+{
+    time_t *ptime;
+    int i;
+    if (notify)
+        ctx->current_crl = crl;
+    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+        ptime = &ctx->param->check_time;
+    else
+        ptime = NULL;
 
-	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
-	if (i == 0)
-		{
-		if (!notify)
-			return 0;
-		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
+    if (i == 0) {
+        if (!notify)
+            return 0;
+        ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	if (i > 0)
-		{
-		if (!notify)
-			return 0;
-		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    if (i > 0) {
+        if (!notify)
+            return 0;
+        ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	if(X509_CRL_get_nextUpdate(crl))
-		{
-		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
+    if (X509_CRL_get_nextUpdate(crl)) {
+        i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
 
-		if (i == 0)
-			{
-			if (!notify)
-				return 0;
-			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
-			if (!ctx->verify_cb(0, ctx))
-				return 0;
-			}
-		/* Ignore expiry of base CRL is delta is valid */
-		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
-			{
-			if (!notify)
-				return 0;
-			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
-			if (!ctx->verify_cb(0, ctx))
-				return 0;
-			}
-		}
+        if (i == 0) {
+            if (!notify)
+                return 0;
+            ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
+        }
+        /* Ignore expiry of base CRL is delta is valid */
+        if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
+            if (!notify)
+                return 0;
+            ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
+        }
+    }
 
-	if (notify)
-		ctx->current_crl = NULL;
+    if (notify)
+        ctx->current_crl = NULL;
 
-	return 1;
-	}
+    return 1;
+}
 
 static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
-			X509 **pissuer, int *pscore, unsigned int *preasons,
-			STACK_OF(X509_CRL) *crls)
-	{
-	int crl_score, best_score = *pscore;
-	size_t i;
-	unsigned int reasons, best_reasons = 0;
-	X509 *x = ctx->current_cert;
-	X509_CRL *crl, *best_crl = NULL;
-	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
+                      X509 **pissuer, int *pscore, unsigned int *preasons,
+                      STACK_OF(X509_CRL) *crls)
+{
+    int crl_score, best_score = *pscore;
+    size_t i;
+    unsigned int reasons, best_reasons = 0;
+    X509 *x = ctx->current_cert;
+    X509_CRL *crl, *best_crl = NULL;
+    X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
 
-	for (i = 0; i < sk_X509_CRL_num(crls); i++)
-		{
-		crl = sk_X509_CRL_value(crls, i);
-		reasons = *preasons;
-		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+        crl = sk_X509_CRL_value(crls, i);
+        reasons = *preasons;
+        crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
 
-		if (crl_score > best_score)
-			{
-			best_crl = crl;
-			best_crl_issuer = crl_issuer;
-			best_score = crl_score;
-			best_reasons = reasons;
-			}
-		}
+        if (crl_score > best_score) {
+            best_crl = crl;
+            best_crl_issuer = crl_issuer;
+            best_score = crl_score;
+            best_reasons = reasons;
+        }
+    }
 
-	if (best_crl)
-		{
-		if (*pcrl)
-			X509_CRL_free(*pcrl);
-		*pcrl = best_crl;
-		*pissuer = best_crl_issuer;
-		*pscore = best_score;
-		*preasons = best_reasons;
-		X509_CRL_up_ref(best_crl);
-		if (*pdcrl)
-			{
-			X509_CRL_free(*pdcrl);
-			*pdcrl = NULL;
-			}
-		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
-		}
+    if (best_crl) {
+        if (*pcrl)
+            X509_CRL_free(*pcrl);
+        *pcrl = best_crl;
+        *pissuer = best_crl_issuer;
+        *pscore = best_score;
+        *preasons = best_reasons;
+        X509_CRL_up_ref(best_crl);
+        if (*pdcrl) {
+            X509_CRL_free(*pdcrl);
+            *pdcrl = NULL;
+        }
+        get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
+    }
 
-	if (best_score >= CRL_SCORE_VALID)
-		return 1;
+    if (best_score >= CRL_SCORE_VALID)
+        return 1;
 
-	return 0;
-	}
+    return 0;
+}
 
-/* Compare two CRL extensions for delta checking purposes. They should be
+/*
+ * Compare two CRL extensions for delta checking purposes. They should be
  * both present or both absent. If both present all fields must be identical.
  */
 
 static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
-	{
-	ASN1_OCTET_STRING *exta, *extb;
-	int i;
-	i = X509_CRL_get_ext_by_NID(a, nid, -1);
-	if (i >= 0)
-		{
-		/* Can't have multiple occurrences */
-		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
-			return 0;
-		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
-		}
-	else
-		exta = NULL;
+{
+    ASN1_OCTET_STRING *exta, *extb;
+    int i;
+    i = X509_CRL_get_ext_by_NID(a, nid, -1);
+    if (i >= 0) {
+        /* Can't have multiple occurrences */
+        if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
+            return 0;
+        exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
+    } else
+        exta = NULL;
 
-	i = X509_CRL_get_ext_by_NID(b, nid, -1);
+    i = X509_CRL_get_ext_by_NID(b, nid, -1);
 
-	if (i >= 0)
-		{
+    if (i >= 0) {
 
-		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
-			return 0;
-		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
-		}
-	else
-		extb = NULL;
+        if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
+            return 0;
+        extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
+    } else
+        extb = NULL;
 
-	if (!exta && !extb)
-		return 1;
+    if (!exta && !extb)
+        return 1;
 
-	if (!exta || !extb)
-		return 0;
+    if (!exta || !extb)
+        return 0;
 
+    if (ASN1_OCTET_STRING_cmp(exta, extb))
+        return 0;
 
-	if (ASN1_OCTET_STRING_cmp(exta, extb))
-		return 0;
-
-	return 1;
-	}
+    return 1;
+}
 
 /* See if a base and delta are compatible */
 
 static int check_delta_base(X509_CRL *delta, X509_CRL *base)
-	{
-	/* Delta CRL must be a delta */
-	if (!delta->base_crl_number)
-			return 0;
-	/* Base must have a CRL number */
-	if (!base->crl_number)
-			return 0;
-	/* Issuer names must match */
-	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
-				X509_CRL_get_issuer(delta)))
-		return 0;
-	/* AKID and IDP must match */
-	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
-			return 0;
-	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
-			return 0;
-	/* Delta CRL base number must not exceed Full CRL number. */
-	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
-			return 0;
-	/* Delta CRL number must exceed full CRL number */
-	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
-			return 1;
-	return 0;
-	}
+{
+    /* Delta CRL must be a delta */
+    if (!delta->base_crl_number)
+        return 0;
+    /* Base must have a CRL number */
+    if (!base->crl_number)
+        return 0;
+    /* Issuer names must match */
+    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
+        return 0;
+    /* AKID and IDP must match */
+    if (!crl_extension_match(delta, base, NID_authority_key_identifier))
+        return 0;
+    if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
+        return 0;
+    /* Delta CRL base number must not exceed Full CRL number. */
+    if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
+        return 0;
+    /* Delta CRL number must exceed full CRL number */
+    if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
+        return 1;
+    return 0;
+}
 
-/* For a given base CRL find a delta... maybe extend to delta scoring
- * or retrieve a chain of deltas...
+/*
+ * For a given base CRL find a delta... maybe extend to delta scoring or
+ * retrieve a chain of deltas...
  */
 
 static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
-			X509_CRL *base, STACK_OF(X509_CRL) *crls)
-	{
-	X509_CRL *delta;
-	size_t i;
-	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
-		return;
-	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
-		return;
-	for (i = 0; i < sk_X509_CRL_num(crls); i++)
-		{
-		delta = sk_X509_CRL_value(crls, i);
-		if (check_delta_base(delta, base))
-			{
-			if (check_crl_time(ctx, delta, 0))
-				*pscore |= CRL_SCORE_TIME_DELTA;
-			X509_CRL_up_ref(delta);
-			*dcrl = delta;
-			return;
-			}
-		}
-	*dcrl = NULL;
-	}
+                         X509_CRL *base, STACK_OF(X509_CRL) *crls)
+{
+    X509_CRL *delta;
+    size_t i;
+    if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
+        return;
+    if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
+        return;
+    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+        delta = sk_X509_CRL_value(crls, i);
+        if (check_delta_base(delta, base)) {
+            if (check_crl_time(ctx, delta, 0))
+                *pscore |= CRL_SCORE_TIME_DELTA;
+            X509_CRL_up_ref(delta);
+            *dcrl = delta;
+            return;
+        }
+    }
+    *dcrl = NULL;
+}
 
-/* For a given CRL return how suitable it is for the supplied certificate 'x'.
- * The return value is a mask of several criteria.
- * If the issuer is not the certificate issuer this is returned in *pissuer.
- * The reasons mask is also used to determine if the CRL is suitable: if
- * no new reasons the CRL is rejected, otherwise reasons is updated.
+/*
+ * For a given CRL return how suitable it is for the supplied certificate
+ * 'x'. The return value is a mask of several criteria. If the issuer is not
+ * the certificate issuer this is returned in *pissuer. The reasons mask is
+ * also used to determine if the CRL is suitable: if no new reasons the CRL
+ * is rejected, otherwise reasons is updated.
  */
 
 static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
-			unsigned int *preasons,
-			X509_CRL *crl, X509 *x)
-	{
+                         unsigned int *preasons, X509_CRL *crl, X509 *x)
+{
 
-	int crl_score = 0;
-	unsigned int tmp_reasons = *preasons, crl_reasons;
+    int crl_score = 0;
+    unsigned int tmp_reasons = *preasons, crl_reasons;
 
-	/* First see if we can reject CRL straight away */
+    /* First see if we can reject CRL straight away */
 
-	/* Invalid IDP cannot be processed */
-	if (crl->idp_flags & IDP_INVALID)
-		return 0;
-	/* Reason codes or indirect CRLs need extended CRL support */
-	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
-		{
-		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
-			return 0;
-		}
-	else if (crl->idp_flags & IDP_REASONS)
-		{
-		/* If no new reasons reject */
-		if (!(crl->idp_reasons & ~tmp_reasons))
-			return 0;
-		}
-	/* Don't process deltas at this stage */
-	else if (crl->base_crl_number)
-		return 0;
-	/* If issuer name doesn't match certificate need indirect CRL */
-	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
-		{
-		if (!(crl->idp_flags & IDP_INDIRECT))
-			return 0;
-		}
-	else
-		crl_score |= CRL_SCORE_ISSUER_NAME;
+    /* Invalid IDP cannot be processed */
+    if (crl->idp_flags & IDP_INVALID)
+        return 0;
+    /* Reason codes or indirect CRLs need extended CRL support */
+    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
+        if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
+            return 0;
+    } else if (crl->idp_flags & IDP_REASONS) {
+        /* If no new reasons reject */
+        if (!(crl->idp_reasons & ~tmp_reasons))
+            return 0;
+    }
+    /* Don't process deltas at this stage */
+    else if (crl->base_crl_number)
+        return 0;
+    /* If issuer name doesn't match certificate need indirect CRL */
+    if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
+        if (!(crl->idp_flags & IDP_INDIRECT))
+            return 0;
+    } else
+        crl_score |= CRL_SCORE_ISSUER_NAME;
 
-	if (!(crl->flags & EXFLAG_CRITICAL))
-		crl_score |= CRL_SCORE_NOCRITICAL;
+    if (!(crl->flags & EXFLAG_CRITICAL))
+        crl_score |= CRL_SCORE_NOCRITICAL;
 
-	/* Check expiry */
-	if (check_crl_time(ctx, crl, 0))
-		crl_score |= CRL_SCORE_TIME;
+    /* Check expiry */
+    if (check_crl_time(ctx, crl, 0))
+        crl_score |= CRL_SCORE_TIME;
 
-	/* Check authority key ID and locate certificate issuer */
-	crl_akid_check(ctx, crl, pissuer, &crl_score);
+    /* Check authority key ID and locate certificate issuer */
+    crl_akid_check(ctx, crl, pissuer, &crl_score);
 
-	/* If we can't locate certificate issuer at this point forget it */
+    /* If we can't locate certificate issuer at this point forget it */
 
-	if (!(crl_score & CRL_SCORE_AKID))
-		return 0;
+    if (!(crl_score & CRL_SCORE_AKID))
+        return 0;
 
-	/* Check cert for matching CRL distribution points */
+    /* Check cert for matching CRL distribution points */
 
-	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
-		{
-		/* If no new reasons reject */
-		if (!(crl_reasons & ~tmp_reasons))
-			return 0;
-		tmp_reasons |= crl_reasons;
-		crl_score |= CRL_SCORE_SCOPE;
-		}
+    if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
+        /* If no new reasons reject */
+        if (!(crl_reasons & ~tmp_reasons))
+            return 0;
+        tmp_reasons |= crl_reasons;
+        crl_score |= CRL_SCORE_SCOPE;
+    }
 
-	*preasons = tmp_reasons;
+    *preasons = tmp_reasons;
 
-	return crl_score;
+    return crl_score;
 
-	}
+}
 
 static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
-				X509 **pissuer, int *pcrl_score)
-	{
-	X509 *crl_issuer = NULL;
-	X509_NAME *cnm = X509_CRL_get_issuer(crl);
-	int cidx = ctx->error_depth;
-	size_t i;
+                           X509 **pissuer, int *pcrl_score)
+{
+    X509 *crl_issuer = NULL;
+    X509_NAME *cnm = X509_CRL_get_issuer(crl);
+    int cidx = ctx->error_depth;
+    size_t i;
 
-	if ((size_t) cidx != sk_X509_num(ctx->chain) - 1)
-		cidx++;
+    if ((size_t)cidx != sk_X509_num(ctx->chain) - 1)
+        cidx++;
 
-	crl_issuer = sk_X509_value(ctx->chain, cidx);
+    crl_issuer = sk_X509_value(ctx->chain, cidx);
 
-	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
-		{
-		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
-			{
-			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
-			*pissuer = crl_issuer;
-			return;
-			}
-		}
+    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+        if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
+            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
+            *pissuer = crl_issuer;
+            return;
+        }
+    }
 
-	for (cidx++; cidx < (int) sk_X509_num(ctx->chain); cidx++)
-		{
-		crl_issuer = sk_X509_value(ctx->chain, cidx);
-		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
-			continue;
-		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
-			{
-			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
-			*pissuer = crl_issuer;
-			return;
-			}
-		}
+    for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
+        crl_issuer = sk_X509_value(ctx->chain, cidx);
+        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+            continue;
+        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
+            *pissuer = crl_issuer;
+            return;
+        }
+    }
 
-	/* Anything else needs extended CRL support */
+    /* Anything else needs extended CRL support */
 
-	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
-		return;
+    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+        return;
 
-	/* Otherwise the CRL issuer is not on the path. Look for it in the
-	 * set of untrusted certificates.
-	 */
-	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
-		{
-		crl_issuer = sk_X509_value(ctx->untrusted, i);
-		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
-			continue;
-		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
-			{
-			*pissuer = crl_issuer;
-			*pcrl_score |= CRL_SCORE_AKID;
-			return;
-			}
-		}
-	}
+    /*
+     * Otherwise the CRL issuer is not on the path. Look for it in the set of
+     * untrusted certificates.
+     */
+    for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
+        crl_issuer = sk_X509_value(ctx->untrusted, i);
+        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+            continue;
+        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+            *pissuer = crl_issuer;
+            *pcrl_score |= CRL_SCORE_AKID;
+            return;
+        }
+    }
+}
 
-/* Check the path of a CRL issuer certificate. This creates a new
+/*
+ * Check the path of a CRL issuer certificate. This creates a new
  * X509_STORE_CTX and populates it with most of the parameters from the
- * parent. This could be optimised somewhat since a lot of path checking
- * will be duplicated by the parent, but this will rarely be used in 
- * practice.
+ * parent. This could be optimised somewhat since a lot of path checking will
+ * be duplicated by the parent, but this will rarely be used in practice.
  */
 
 static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
-	{
-	X509_STORE_CTX crl_ctx;
-	int ret;
-	/* Don't allow recursive CRL path validation */
-	if (ctx->parent)
-		return 0;
-	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
-		return -1;
+{
+    X509_STORE_CTX crl_ctx;
+    int ret;
+    /* Don't allow recursive CRL path validation */
+    if (ctx->parent)
+        return 0;
+    if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
+        return -1;
 
-	crl_ctx.crls = ctx->crls;
-	/* Copy verify params across */
-	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
+    crl_ctx.crls = ctx->crls;
+    /* Copy verify params across */
+    X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
 
-	crl_ctx.parent = ctx;
-	crl_ctx.verify_cb = ctx->verify_cb;
+    crl_ctx.parent = ctx;
+    crl_ctx.verify_cb = ctx->verify_cb;
 
-	/* Verify CRL issuer */
-	ret = X509_verify_cert(&crl_ctx);
+    /* Verify CRL issuer */
+    ret = X509_verify_cert(&crl_ctx);
 
-	if (ret <= 0)
-		goto err;
+    if (ret <= 0)
+        goto err;
 
-	/* Check chain is acceptable */
+    /* Check chain is acceptable */
 
-	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
-	err:
-	X509_STORE_CTX_cleanup(&crl_ctx);
-	return ret;
-	}
+    ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
+ err:
+    X509_STORE_CTX_cleanup(&crl_ctx);
+    return ret;
+}
 
-/* RFC3280 says nothing about the relationship between CRL path
- * and certificate path, which could lead to situations where a
- * certificate could be revoked or validated by a CA not authorised
- * to do so. RFC5280 is more strict and states that the two paths must
- * end in the same trust anchor, though some discussions remain...
- * until this is resolved we use the RFC5280 version
+/*
+ * RFC3280 says nothing about the relationship between CRL path and
+ * certificate path, which could lead to situations where a certificate could
+ * be revoked or validated by a CA not authorised to do so. RFC5280 is more
+ * strict and states that the two paths must end in the same trust anchor,
+ * though some discussions remain... until this is resolved we use the
+ * RFC5280 version
  */
 
 static int check_crl_chain(X509_STORE_CTX *ctx,
-			STACK_OF(X509) *cert_path,
-			STACK_OF(X509) *crl_path)
-	{
-	X509 *cert_ta, *crl_ta;
-	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
-	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
-	if (!X509_cmp(cert_ta, crl_ta))
-		return 1;
-	return 0;
-	}
+                           STACK_OF(X509) *cert_path,
+                           STACK_OF(X509) *crl_path)
+{
+    X509 *cert_ta, *crl_ta;
+    cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
+    crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
+    if (!X509_cmp(cert_ta, crl_ta))
+        return 1;
+    return 0;
+}
 
-/* Check for match between two dist point names: three separate cases.
- * 1. Both are relative names and compare X509_NAME types.
- * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
- * 3. Both are full names and compare two GENERAL_NAMES.
- * 4. One is NULL: automatic match.
+/*
+ * Check for match between two dist point names: three separate cases. 1.
+ * Both are relative names and compare X509_NAME types. 2. One full, one
+ * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
+ * compare two GENERAL_NAMES. 4. One is NULL: automatic match.
  */
 
-
 static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
-	{
-	X509_NAME *nm = NULL;
-	GENERAL_NAMES *gens = NULL;
-	GENERAL_NAME *gena, *genb;
-	size_t i, j;
-	if (!a || !b)
-		return 1;
-	if (a->type == 1)
-		{
-		if (!a->dpname)
-			return 0;
-		/* Case 1: two X509_NAME */
-		if (b->type == 1)
-			{
-			if (!b->dpname)
-				return 0;
-			if (!X509_NAME_cmp(a->dpname, b->dpname))
-				return 1;
-			else
-				return 0;
-			}
-		/* Case 2: set name and GENERAL_NAMES appropriately */
-		nm = a->dpname;
-		gens = b->name.fullname;
-		}
-	else if (b->type == 1)
-		{
-		if (!b->dpname)
-			return 0;
-		/* Case 2: set name and GENERAL_NAMES appropriately */
-		gens = a->name.fullname;
-		nm = b->dpname;
-		}
+{
+    X509_NAME *nm = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gena, *genb;
+    size_t i, j;
+    if (!a || !b)
+        return 1;
+    if (a->type == 1) {
+        if (!a->dpname)
+            return 0;
+        /* Case 1: two X509_NAME */
+        if (b->type == 1) {
+            if (!b->dpname)
+                return 0;
+            if (!X509_NAME_cmp(a->dpname, b->dpname))
+                return 1;
+            else
+                return 0;
+        }
+        /* Case 2: set name and GENERAL_NAMES appropriately */
+        nm = a->dpname;
+        gens = b->name.fullname;
+    } else if (b->type == 1) {
+        if (!b->dpname)
+            return 0;
+        /* Case 2: set name and GENERAL_NAMES appropriately */
+        gens = a->name.fullname;
+        nm = b->dpname;
+    }
 
-	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
-	if (nm)
-		{
-		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
-			{
-			gena = sk_GENERAL_NAME_value(gens, i);	
-			if (gena->type != GEN_DIRNAME)
-				continue;
-			if (!X509_NAME_cmp(nm, gena->d.directoryName))
-				return 1;
-			}
-		return 0;
-		}
+    /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
+    if (nm) {
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            gena = sk_GENERAL_NAME_value(gens, i);
+            if (gena->type != GEN_DIRNAME)
+                continue;
+            if (!X509_NAME_cmp(nm, gena->d.directoryName))
+                return 1;
+        }
+        return 0;
+    }
 
-	/* Else case 3: two GENERAL_NAMES */
+    /* Else case 3: two GENERAL_NAMES */
 
-	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
-		{
-		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
-		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
-			{
-			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
-			if (!GENERAL_NAME_cmp(gena, genb))
-				return 1;
-			}
-		}
+    for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
+        gena = sk_GENERAL_NAME_value(a->name.fullname, i);
+        for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
+            genb = sk_GENERAL_NAME_value(b->name.fullname, j);
+            if (!GENERAL_NAME_cmp(gena, genb))
+                return 1;
+        }
+    }
 
-	return 0;
+    return 0;
 
-	}
+}
 
 static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
-	{
-	size_t i;
-	X509_NAME *nm = X509_CRL_get_issuer(crl);
-	/* If no CRLissuer return is successful iff don't need a match */
-	if (!dp->CRLissuer)
-		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
-	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
-		{
-		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
-		if (gen->type != GEN_DIRNAME)
-			continue;
-		if (!X509_NAME_cmp(gen->d.directoryName, nm))
-			return 1;
-		}
-	return 0;
-	}
+{
+    size_t i;
+    X509_NAME *nm = X509_CRL_get_issuer(crl);
+    /* If no CRLissuer return is successful iff don't need a match */
+    if (!dp->CRLissuer)
+        return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
+    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+        if (gen->type != GEN_DIRNAME)
+            continue;
+        if (!X509_NAME_cmp(gen->d.directoryName, nm))
+            return 1;
+    }
+    return 0;
+}
 
 /* Check CRLDP and IDP */
 
 static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
-				unsigned int *preasons)
-	{
-	size_t i;
-	if (crl->idp_flags & IDP_ONLYATTR)
-		return 0;
-	if (x->ex_flags & EXFLAG_CA)
-		{
-		if (crl->idp_flags & IDP_ONLYUSER)
-			return 0;
-		}
-	else
-		{
-		if (crl->idp_flags & IDP_ONLYCA)
-			return 0;
-		}
-	*preasons = crl->idp_reasons;
-	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
-		{
-		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
-		if (crldp_check_crlissuer(dp, crl, crl_score))
-			{
-			if (!crl->idp ||
-			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
-				{
-				*preasons &= dp->dp_reasons;
-				return 1;
-				}
-			}
-		}
-	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
-		return 1;
-	return 0;
-	}
+                           unsigned int *preasons)
+{
+    size_t i;
+    if (crl->idp_flags & IDP_ONLYATTR)
+        return 0;
+    if (x->ex_flags & EXFLAG_CA) {
+        if (crl->idp_flags & IDP_ONLYUSER)
+            return 0;
+    } else {
+        if (crl->idp_flags & IDP_ONLYCA)
+            return 0;
+    }
+    *preasons = crl->idp_reasons;
+    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
+        DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+        if (crldp_check_crlissuer(dp, crl, crl_score)) {
+            if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
+                *preasons &= dp->dp_reasons;
+                return 1;
+            }
+        }
+    }
+    if ((!crl->idp || !crl->idp->distpoint)
+        && (crl_score & CRL_SCORE_ISSUER_NAME))
+        return 1;
+    return 0;
+}
 
-/* Retrieve CRL corresponding to current certificate.
- * If deltas enabled try to find a delta CRL too
+/*
+ * Retrieve CRL corresponding to current certificate. If deltas enabled try
+ * to find a delta CRL too
  */
-	
+
 static int get_crl_delta(X509_STORE_CTX *ctx,
-				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
-	{
-	int ok;
-	X509 *issuer = NULL;
-	int crl_score = 0;
-	unsigned int reasons;
-	X509_CRL *crl = NULL, *dcrl = NULL;
-	STACK_OF(X509_CRL) *skcrl;
-	X509_NAME *nm = X509_get_issuer_name(x);
-	reasons = ctx->current_reasons;
-	ok = get_crl_sk(ctx, &crl, &dcrl, 
-				&issuer, &crl_score, &reasons, ctx->crls);
+                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
+{
+    int ok;
+    X509 *issuer = NULL;
+    int crl_score = 0;
+    unsigned int reasons;
+    X509_CRL *crl = NULL, *dcrl = NULL;
+    STACK_OF(X509_CRL) *skcrl;
+    X509_NAME *nm = X509_get_issuer_name(x);
+    reasons = ctx->current_reasons;
+    ok = get_crl_sk(ctx, &crl, &dcrl,
+                    &issuer, &crl_score, &reasons, ctx->crls);
 
-	if (ok)
-		goto done;
+    if (ok)
+        goto done;
 
-	/* Lookup CRLs from store */
+    /* Lookup CRLs from store */
 
-	skcrl = ctx->lookup_crls(ctx, nm);
+    skcrl = ctx->lookup_crls(ctx, nm);
 
-	/* If no CRLs found and a near match from get_crl_sk use that */
-	if (!skcrl && crl)
-		goto done;
+    /* If no CRLs found and a near match from get_crl_sk use that */
+    if (!skcrl && crl)
+        goto done;
 
-	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
+    get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
 
-	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
+    sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
 
-	done:
+ done:
 
-	/* If we got any kind of CRL use it and return success */
-	if (crl)
-		{
-		ctx->current_issuer = issuer;
-		ctx->current_crl_score = crl_score;
-		ctx->current_reasons = reasons;
-		*pcrl = crl;
-		*pdcrl = dcrl;
-		return 1;
-		}
+    /* If we got any kind of CRL use it and return success */
+    if (crl) {
+        ctx->current_issuer = issuer;
+        ctx->current_crl_score = crl_score;
+        ctx->current_reasons = reasons;
+        *pcrl = crl;
+        *pdcrl = dcrl;
+        return 1;
+    }
 
-	return 0;
-	}
+    return 0;
+}
 
 /* Check CRL validity */
 static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
-	{
-	X509 *issuer = NULL;
-	EVP_PKEY *ikey = NULL;
-	int ok = 0, chnum, cnum;
-	cnum = ctx->error_depth;
-	chnum = sk_X509_num(ctx->chain) - 1;
-	/* if we have an alternative CRL issuer cert use that */
-	if (ctx->current_issuer)
-		issuer = ctx->current_issuer;
+{
+    X509 *issuer = NULL;
+    EVP_PKEY *ikey = NULL;
+    int ok = 0, chnum, cnum;
+    cnum = ctx->error_depth;
+    chnum = sk_X509_num(ctx->chain) - 1;
+    /* if we have an alternative CRL issuer cert use that */
+    if (ctx->current_issuer)
+        issuer = ctx->current_issuer;
 
-	/* Else find CRL issuer: if not last certificate then issuer
-	 * is next certificate in chain.
-	 */
-	else if (cnum < chnum)
-		issuer = sk_X509_value(ctx->chain, cnum + 1);
-	else
-		{
-		issuer = sk_X509_value(ctx->chain, chnum);
-		/* If not self signed, can't check signature */
-		if(!ctx->check_issued(ctx, issuer, issuer))
-			{
-			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
-			ok = ctx->verify_cb(0, ctx);
-			if(!ok) goto err;
-			}
-		}
+    /*
+     * Else find CRL issuer: if not last certificate then issuer is next
+     * certificate in chain.
+     */
+    else if (cnum < chnum)
+        issuer = sk_X509_value(ctx->chain, cnum + 1);
+    else {
+        issuer = sk_X509_value(ctx->chain, chnum);
+        /* If not self signed, can't check signature */
+        if (!ctx->check_issued(ctx, issuer, issuer)) {
+            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
+            ok = ctx->verify_cb(0, ctx);
+            if (!ok)
+                goto err;
+        }
+    }
 
-	if(issuer)
-		{
-		/* Skip most tests for deltas because they have already
-		 * been done
-		 */
-		if (!crl->base_crl_number)
-			{
-			/* Check for cRLSign bit if keyUsage present */
-			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
-				!(issuer->ex_kusage & KU_CRL_SIGN))
-				{
-				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
-				ok = ctx->verify_cb(0, ctx);
-				if(!ok) goto err;
-				}
+    if (issuer) {
+        /*
+         * Skip most tests for deltas because they have already been done
+         */
+        if (!crl->base_crl_number) {
+            /* Check for cRLSign bit if keyUsage present */
+            if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+                !(issuer->ex_kusage & KU_CRL_SIGN)) {
+                ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
+                ok = ctx->verify_cb(0, ctx);
+                if (!ok)
+                    goto err;
+            }
 
-			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
-				{
-				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
-				ok = ctx->verify_cb(0, ctx);
-				if(!ok) goto err;
-				}
+            if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
+                ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
+                ok = ctx->verify_cb(0, ctx);
+                if (!ok)
+                    goto err;
+            }
 
-			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
-				{
-				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
-					{
-					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
-					ok = ctx->verify_cb(0, ctx);
-					if(!ok) goto err;
-					}
-				}
+            if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
+                if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
+                    ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
+                    ok = ctx->verify_cb(0, ctx);
+                    if (!ok)
+                        goto err;
+                }
+            }
 
-			if (crl->idp_flags & IDP_INVALID)
-				{
-				ctx->error = X509_V_ERR_INVALID_EXTENSION;
-				ok = ctx->verify_cb(0, ctx);
-				if(!ok) goto err;
-				}
+            if (crl->idp_flags & IDP_INVALID) {
+                ctx->error = X509_V_ERR_INVALID_EXTENSION;
+                ok = ctx->verify_cb(0, ctx);
+                if (!ok)
+                    goto err;
+            }
 
+        }
 
-			}
+        if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
+            ok = check_crl_time(ctx, crl, 1);
+            if (!ok)
+                goto err;
+        }
 
-		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
-			{
-			ok = check_crl_time(ctx, crl, 1);
-			if (!ok)
-				goto err;
-			}
+        /* Attempt to get issuer certificate public key */
+        ikey = X509_get_pubkey(issuer);
 
-		/* Attempt to get issuer certificate public key */
-		ikey = X509_get_pubkey(issuer);
+        if (!ikey) {
+            ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+            ok = ctx->verify_cb(0, ctx);
+            if (!ok)
+                goto err;
+        } else {
+            int rv;
+            rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
+            if (rv != X509_V_OK) {
+                ctx->error = rv;
+                ok = ctx->verify_cb(0, ctx);
+                if (!ok)
+                    goto err;
+            }
+            /* Verify CRL signature */
+            if (X509_CRL_verify(crl, ikey) <= 0) {
+                ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
+                ok = ctx->verify_cb(0, ctx);
+                if (!ok)
+                    goto err;
+            }
+        }
+    }
 
-		if(!ikey)
-			{
-			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
-			ok = ctx->verify_cb(0, ctx);
-			if (!ok) goto err;
-			}
-		else
-			{
-			int rv;
-			rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
-			if (rv != X509_V_OK)
-				{
-				ctx->error=rv;
-				ok = ctx->verify_cb(0, ctx);
-				if (!ok)
-					goto err;
-				}
-			/* Verify CRL signature */
-			if(X509_CRL_verify(crl, ikey) <= 0)
-				{
-				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
-				ok = ctx->verify_cb(0, ctx);
-				if (!ok) goto err;
-				}
-			}
-		}
+    ok = 1;
 
-	ok = 1;
-
-	err:
-	EVP_PKEY_free(ikey);
-	return ok;
-	}
+ err:
+    EVP_PKEY_free(ikey);
+    return ok;
+}
 
 /* Check certificate against CRL */
 static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
-	{
-	int ok;
-	X509_REVOKED *rev;
-	/* The rules changed for this... previously if a CRL contained
-	 * unhandled critical extensions it could still be used to indicate
-	 * a certificate was revoked. This has since been changed since 
-	 * critical extension can change the meaning of CRL entries.
-	 */
-	if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
-		&& (crl->flags & EXFLAG_CRITICAL))
-		{
-		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
-		ok = ctx->verify_cb(0, ctx);
-		if(!ok)
-			return 0;
-		}
-	/* Look for serial number of certificate in CRL
-	 * If found make sure reason is not removeFromCRL.
-	 */
-	if (X509_CRL_get0_by_cert(crl, &rev, x))
-		{
-		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
-			return 2;
-		ctx->error = X509_V_ERR_CERT_REVOKED;
-		ok = ctx->verify_cb(0, ctx);
-		if (!ok)
-			return 0;
-		}
+{
+    int ok;
+    X509_REVOKED *rev;
+    /*
+     * The rules changed for this... previously if a CRL contained unhandled
+     * critical extensions it could still be used to indicate a certificate
+     * was revoked. This has since been changed since critical extension can
+     * change the meaning of CRL entries.
+     */
+    if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+        && (crl->flags & EXFLAG_CRITICAL)) {
+        ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
+        ok = ctx->verify_cb(0, ctx);
+        if (!ok)
+            return 0;
+    }
+    /*
+     * Look for serial number of certificate in CRL If found make sure reason
+     * is not removeFromCRL.
+     */
+    if (X509_CRL_get0_by_cert(crl, &rev, x)) {
+        if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+            return 2;
+        ctx->error = X509_V_ERR_CERT_REVOKED;
+        ok = ctx->verify_cb(0, ctx);
+        if (!ok)
+            return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 static int check_policy(X509_STORE_CTX *ctx)
-	{
-	int ret;
-	if (ctx->parent)
-		return 1;
-	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
-				ctx->param->policies, ctx->param->flags);
-	if (ret == 0)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	/* Invalid or inconsistent extensions */
-	if (ret == -1)
-		{
-		/* Locate certificates with bad extensions and notify
-		 * callback.
-		 */
-		X509 *x;
-		size_t i;
-		for (i = 1; i < sk_X509_num(ctx->chain); i++)
-			{
-			x = sk_X509_value(ctx->chain, i);
-			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
-				continue;
-			ctx->current_cert = x;
-			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
-			if(!ctx->verify_cb(0, ctx))
-				return 0;
-			}
-		return 1;
-		}
-	if (ret == -2)
-		{
-		ctx->current_cert = NULL;
-		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
-		return ctx->verify_cb(0, ctx);
-		}
+{
+    int ret;
+    if (ctx->parent)
+        return 1;
+    ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
+                            ctx->param->policies, ctx->param->flags);
+    if (ret == 0) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    /* Invalid or inconsistent extensions */
+    if (ret == -1) {
+        /*
+         * Locate certificates with bad extensions and notify callback.
+         */
+        X509 *x;
+        size_t i;
+        for (i = 1; i < sk_X509_num(ctx->chain); i++) {
+            x = sk_X509_value(ctx->chain, i);
+            if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
+                continue;
+            ctx->current_cert = x;
+            ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
+        }
+        return 1;
+    }
+    if (ret == -2) {
+        ctx->current_cert = NULL;
+        ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
+        return ctx->verify_cb(0, ctx);
+    }
 
-	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
-		{
-		ctx->current_cert = NULL;
-		ctx->error = X509_V_OK;
-		if (!ctx->verify_cb(2, ctx))
-			return 0;
-		}
+    if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
+        ctx->current_cert = NULL;
+        ctx->error = X509_V_OK;
+        if (!ctx->verify_cb(2, ctx))
+            return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
-	{
-	time_t *ptime;
-	int i;
+{
+    time_t *ptime;
+    int i;
 
-	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
-		ptime = &ctx->param->check_time;
-	else
-		ptime = NULL;
+    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+        ptime = &ctx->param->check_time;
+    else
+        ptime = NULL;
 
-	i=X509_cmp_time(X509_get_notBefore(x), ptime);
-	if (i == 0)
-		{
-		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
-		ctx->current_cert=x;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    i = X509_cmp_time(X509_get_notBefore(x), ptime);
+    if (i == 0) {
+        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
+        ctx->current_cert = x;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	if (i > 0)
-		{
-		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
-		ctx->current_cert=x;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    if (i > 0) {
+        ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
+        ctx->current_cert = x;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	i=X509_cmp_time(X509_get_notAfter(x), ptime);
-	if (i == 0)
-		{
-		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
-		ctx->current_cert=x;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    i = X509_cmp_time(X509_get_notAfter(x), ptime);
+    if (i == 0) {
+        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
+        ctx->current_cert = x;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	if (i < 0)
-		{
-		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
-		ctx->current_cert=x;
-		if (!ctx->verify_cb(0, ctx))
-			return 0;
-		}
+    if (i < 0) {
+        ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
+        ctx->current_cert = x;
+        if (!ctx->verify_cb(0, ctx))
+            return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 static int internal_verify(X509_STORE_CTX *ctx)
-	{
-	int ok=0,n;
-	X509 *xs,*xi;
-	EVP_PKEY *pkey=NULL;
-	int (*cb)(int xok,X509_STORE_CTX *xctx);
+{
+    int ok = 0, n;
+    X509 *xs, *xi;
+    EVP_PKEY *pkey = NULL;
+    int (*cb) (int xok, X509_STORE_CTX *xctx);
 
-	cb=ctx->verify_cb;
+    cb = ctx->verify_cb;
 
-	n=sk_X509_num(ctx->chain);
-	ctx->error_depth=n-1;
-	n--;
-	xi=sk_X509_value(ctx->chain,n);
+    n = sk_X509_num(ctx->chain);
+    ctx->error_depth = n - 1;
+    n--;
+    xi = sk_X509_value(ctx->chain, n);
 
-	if (ctx->check_issued(ctx, xi, xi))
-		xs=xi;
-	else
-		{
-		if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
-			{
-			xs = xi;
-			goto check_cert;
-			}
-		if (n <= 0)
-			{
-			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
-			ctx->current_cert=xi;
-			ok=cb(0,ctx);
-			goto end;
-			}
-		else
-			{
-			n--;
-			ctx->error_depth=n;
-			xs=sk_X509_value(ctx->chain,n);
-			}
-		}
+    if (ctx->check_issued(ctx, xi, xi))
+        xs = xi;
+    else {
+        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+            xs = xi;
+            goto check_cert;
+        }
+        if (n <= 0) {
+            ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+            ctx->current_cert = xi;
+            ok = cb(0, ctx);
+            goto end;
+        } else {
+            n--;
+            ctx->error_depth = n;
+            xs = sk_X509_value(ctx->chain, n);
+        }
+    }
 
-/*	ctx->error=0;  not needed */
-	while (n >= 0)
-		{
-		ctx->error_depth=n;
+/*      ctx->error=0;  not needed */
+    while (n >= 0) {
+        ctx->error_depth = n;
 
-		/* Skip signature check for self signed certificates unless
-		 * explicitly asked for. It doesn't add any security and
-		 * just wastes time.
-		 */
-		if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
-			{
-			if ((pkey=X509_get_pubkey(xi)) == NULL)
-				{
-				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
-				ctx->current_cert=xi;
-				ok=(*cb)(0,ctx);
-				if (!ok) goto end;
-				}
-			else if (X509_verify(xs,pkey) <= 0)
-				{
-				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
-				ctx->current_cert=xs;
-				ok=(*cb)(0,ctx);
-				if (!ok)
-					{
-					EVP_PKEY_free(pkey);
-					goto end;
-					}
-				}
-			EVP_PKEY_free(pkey);
-			pkey=NULL;
-			}
+        /*
+         * Skip signature check for self signed certificates unless
+         * explicitly asked for. It doesn't add any security and just wastes
+         * time.
+         */
+        if (!xs->valid
+            && (xs != xi
+                || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
+            if ((pkey = X509_get_pubkey(xi)) == NULL) {
+                ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+                ctx->current_cert = xi;
+                ok = (*cb) (0, ctx);
+                if (!ok)
+                    goto end;
+            } else if (X509_verify(xs, pkey) <= 0) {
+                ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
+                ctx->current_cert = xs;
+                ok = (*cb) (0, ctx);
+                if (!ok) {
+                    EVP_PKEY_free(pkey);
+                    goto end;
+                }
+            }
+            EVP_PKEY_free(pkey);
+            pkey = NULL;
+        }
 
-		xs->valid = 1;
+        xs->valid = 1;
 
-		check_cert:
-		ok = check_cert_time(ctx, xs);
-		if (!ok)
-			goto end;
+ check_cert:
+        ok = check_cert_time(ctx, xs);
+        if (!ok)
+            goto end;
 
-		/* The last error (if any) is still in the error value */
-		ctx->current_issuer=xi;
-		ctx->current_cert=xs;
-		ok=(*cb)(1,ctx);
-		if (!ok) goto end;
+        /* The last error (if any) is still in the error value */
+        ctx->current_issuer = xi;
+        ctx->current_cert = xs;
+        ok = (*cb) (1, ctx);
+        if (!ok)
+            goto end;
 
-		n--;
-		if (n >= 0)
-			{
-			xi=xs;
-			xs=sk_X509_value(ctx->chain,n);
-			}
-		}
-	ok=1;
-end:
-	return ok;
-	}
+        n--;
+        if (n >= 0) {
+            xi = xs;
+            xs = sk_X509_value(ctx->chain, n);
+        }
+    }
+    ok = 1;
+ end:
+    return ok;
+}
 
 int X509_cmp_current_time(const ASN1_TIME *ctm)
 {
-	return X509_cmp_time(ctm, NULL);
+    return X509_cmp_time(ctm, NULL);
 }
 
 int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
-	{
-	char *str;
-	ASN1_TIME atm;
-	long offset;
-	char buff1[24],buff2[24],*p;
-	int i, j, remaining;
+{
+    char *str;
+    ASN1_TIME atm;
+    long offset;
+    char buff1[24], buff2[24], *p;
+    int i, j, remaining;
 
-	p=buff1;
-	remaining = ctm->length;
-	str=(char *)ctm->data;
-	/* Note that the following (historical) code allows much more slack in
-	 * the time format than RFC5280. In RFC5280, the representation is
-	 * fixed:
-	 * UTCTime: YYMMDDHHMMSSZ
-	 * GeneralizedTime: YYYYMMDDHHMMSSZ */
-	if (ctm->type == V_ASN1_UTCTIME)
-		{
-		/* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
-		int min_length = sizeof("YYMMDDHHMMZ") - 1;
-		int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
-		if (remaining < min_length || remaining > max_length)
-			return 0;
-		memcpy(p,str,10);
-		p+=10;
-		str+=10;
-		remaining -= 10;
-		}
-	else
-		{
-		/* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
-		int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
-		int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
-		if (remaining < min_length || remaining > max_length)
-			return 0;
-		memcpy(p,str,12);
-		p+=12;
-		str+=12;
-		remaining -= 12;
-		}
+    p = buff1;
+    remaining = ctm->length;
+    str = (char *)ctm->data;
+    /*
+     * Note that the following (historical) code allows much more slack in
+     * the time format than RFC5280. In RFC5280, the representation is fixed:
+     * UTCTime: YYMMDDHHMMSSZ GeneralizedTime: YYYYMMDDHHMMSSZ
+     */
+    if (ctm->type == V_ASN1_UTCTIME) {
+        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+        int min_length = sizeof("YYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
+            return 0;
+        memcpy(p, str, 10);
+        p += 10;
+        str += 10;
+        remaining -= 10;
+    } else {
+        /*
+         * YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm
+         */
+        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
+            return 0;
+        memcpy(p, str, 12);
+        p += 12;
+        str += 12;
+        remaining -= 12;
+    }
 
-	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
-		{ *(p++)='0'; *(p++)='0'; }
-	else
-		{ 
-		/* SS (seconds) */
-		if (remaining < 2)
-			return 0;
-		*(p++)= *(str++);
-		*(p++)= *(str++);
-		remaining -= 2;
-		/* Skip any (up to three) fractional seconds...
-		 * TODO(emilia): in RFC5280, fractional seconds are forbidden.
-		 * Can we just kill them altogether? */
-		if (remaining && *str == '.')
-			{
-			str++;
-			remaining--;
-			for (i = 0; i < 3 && remaining; i++, str++, remaining--)
-				{
-				if (*str < '0' || *str > '9')
-					break;
-				}
-			}
-		
-		}
-	*(p++)='Z';
-	*(p++)='\0';
+    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
+        *(p++) = '0';
+        *(p++) = '0';
+    } else {
+        /* SS (seconds) */
+        if (remaining < 2)
+            return 0;
+        *(p++) = *(str++);
+        *(p++) = *(str++);
+        remaining -= 2;
+        /*
+         * Skip any (up to three) fractional seconds... TODO(emilia): in
+         * RFC5280, fractional seconds are forbidden. Can we just kill them
+         * altogether?
+         */
+        if (remaining && *str == '.') {
+            str++;
+            remaining--;
+            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+                if (*str < '0' || *str > '9')
+                    break;
+            }
+        }
 
-	/* We now need either a terminating 'Z' or an offset. */
-	if (!remaining)
-		return 0;
-	if (*str == 'Z')
-		{
-		if (remaining != 1)
-			return 0;
-		offset=0;
-		}
-	else
-		{
-		/* (+-)HHMM */
-		if ((*str != '+') && (*str != '-'))
-			return 0;
-		/* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
-		if (remaining != 5)
-			return 0;
-		if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
-			str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
-			return 0;
-		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
-		offset+=(str[3]-'0')*10+(str[4]-'0');
-		if (*str == '-')
-			offset= -offset;
-		}
-	atm.type=ctm->type;
-	atm.flags = 0;
-	atm.length=sizeof(buff2);
-	atm.data=(unsigned char *)buff2;
+    }
+    *(p++) = 'Z';
+    *(p++) = '\0';
 
-	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
-		return 0;
+    /* We now need either a terminating 'Z' or an offset. */
+    if (!remaining)
+        return 0;
+    if (*str == 'Z') {
+        if (remaining != 1)
+            return 0;
+        offset = 0;
+    } else {
+        /* (+-)HHMM */
+        if ((*str != '+') && (*str != '-'))
+            return 0;
+        /*
+         * Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280.
+         */
+        if (remaining != 5)
+            return 0;
+        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+            return 0;
+        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
+        offset += (str[3] - '0') * 10 + (str[4] - '0');
+        if (*str == '-')
+            offset = -offset;
+    }
+    atm.type = ctm->type;
+    atm.flags = 0;
+    atm.length = sizeof(buff2);
+    atm.data = (unsigned char *)buff2;
 
-	if (ctm->type == V_ASN1_UTCTIME)
-		{
-		i=(buff1[0]-'0')*10+(buff1[1]-'0');
-		if (i < 50) i+=100; /* cf. RFC 2459 */
-		j=(buff2[0]-'0')*10+(buff2[1]-'0');
-		if (j < 50) j+=100;
+    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
+        return 0;
 
-		if (i < j) return -1;
-		if (i > j) return 1;
-		}
-	i=strcmp(buff1,buff2);
-	if (i == 0) /* wait a second then return younger :-) */
-		return -1;
-	else
-		return i;
-	}
+    if (ctm->type == V_ASN1_UTCTIME) {
+        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+        if (i < 50)
+            i += 100;           /* cf. RFC 2459 */
+        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+        if (j < 50)
+            j += 100;
+
+        if (i < j)
+            return -1;
+        if (i > j)
+            return 1;
+    }
+    i = strcmp(buff1, buff2);
+    if (i == 0)                 /* wait a second then return younger :-) */
+        return -1;
+    else
+        return i;
+}
 
 ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
 {
-	return X509_time_adj(s, adj, NULL);
+    return X509_time_adj(s, adj, NULL);
 }
 
 ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
-	{
-	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
-	}
+{
+    return X509_time_adj_ex(s, 0, offset_sec, in_tm);
+}
 
 ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
-				int offset_day, long offset_sec, time_t *in_tm)
-	{
-	time_t t = 0;
+                            int offset_day, long offset_sec, time_t *in_tm)
+{
+    time_t t = 0;
 
-	if (in_tm) t = *in_tm;
-	else time(&t);
+    if (in_tm)
+        t = *in_tm;
+    else
+        time(&t);
 
-	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
-		{
-		if (s->type == V_ASN1_UTCTIME)
-			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
-		if (s->type == V_ASN1_GENERALIZEDTIME)
-			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
-								offset_sec);
-		}
-	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
-	}
+    if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
+        if (s->type == V_ASN1_UTCTIME)
+            return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+        if (s->type == V_ASN1_GENERALIZEDTIME)
+            return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+    }
+    return ASN1_TIME_adj(s, t, offset_day, offset_sec);
+}
 
 /* Make a delta CRL as the diff between two full CRLs */
 
 X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
-			EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
-	{
-	X509_CRL *crl = NULL;
-	int i;
-	size_t j;
-	STACK_OF(X509_REVOKED) *revs = NULL;
-	/* CRLs can't be delta already */
-	if (base->base_crl_number || newer->base_crl_number)
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
-			return NULL;
-			}
-	/* Base and new CRL must have a CRL number */
-	if (!base->crl_number || !newer->crl_number)
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
-			return NULL;
-			}
-	/* Issuer names must match */
-	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
-				X509_CRL_get_issuer(newer)))
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
-			return NULL;
-			}
-	/* AKID and IDP must match */
-	if (!crl_extension_match(base, newer, NID_authority_key_identifier))
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
-			return NULL;
-			}
-	if (!crl_extension_match(base, newer, NID_issuing_distribution_point))
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
-			return NULL;
-			}
-	/* Newer CRL number must exceed full CRL number */
-	if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0)
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
-			return NULL;
-			}
-	/* CRLs must verify */
-	if (skey && (X509_CRL_verify(base, skey) <= 0 ||
-			X509_CRL_verify(newer, skey) <= 0))
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
-		return NULL;
-		}
-	/* Create new CRL */
-	crl = X509_CRL_new();
-	if (!crl || !X509_CRL_set_version(crl, 1))
-		goto memerr;
-	/* Set issuer name */
-	if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
-		goto memerr;
+                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
+{
+    X509_CRL *crl = NULL;
+    int i;
+    size_t j;
+    STACK_OF(X509_REVOKED) *revs = NULL;
+    /* CRLs can't be delta already */
+    if (base->base_crl_number || newer->base_crl_number) {
+        OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
+        return NULL;
+    }
+    /* Base and new CRL must have a CRL number */
+    if (!base->crl_number || !newer->crl_number) {
+        OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
+        return NULL;
+    }
+    /* Issuer names must match */
+    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
+        OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
+        return NULL;
+    }
+    /* AKID and IDP must match */
+    if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
+        return NULL;
+    }
+    if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
+        return NULL;
+    }
+    /* Newer CRL number must exceed full CRL number */
+    if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
+        OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
+        return NULL;
+    }
+    /* CRLs must verify */
+    if (skey && (X509_CRL_verify(base, skey) <= 0 ||
+                 X509_CRL_verify(newer, skey) <= 0)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
+        return NULL;
+    }
+    /* Create new CRL */
+    crl = X509_CRL_new();
+    if (!crl || !X509_CRL_set_version(crl, 1))
+        goto memerr;
+    /* Set issuer name */
+    if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
+        goto memerr;
 
-	if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
-		goto memerr;
-	if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
-		goto memerr;
+    if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
+        goto memerr;
+    if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
+        goto memerr;
 
-	/* Set base CRL number: must be critical */
+    /* Set base CRL number: must be critical */
 
-	if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
-		goto memerr;
+    if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
+        goto memerr;
 
-	/* Copy extensions across from newest CRL to delta: this will set
-	 * CRL number to correct value too.
-	 */
+    /*
+     * Copy extensions across from newest CRL to delta: this will set CRL
+     * number to correct value too.
+     */
 
-	for (i = 0; i < X509_CRL_get_ext_count(newer); i++)
-		{
-		X509_EXTENSION *ext;
-		ext = X509_CRL_get_ext(newer, i);
-		if (!X509_CRL_add_ext(crl, ext, -1))
-			goto memerr;
-		}
+    for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
+        X509_EXTENSION *ext;
+        ext = X509_CRL_get_ext(newer, i);
+        if (!X509_CRL_add_ext(crl, ext, -1))
+            goto memerr;
+    }
 
-	/* Go through revoked entries, copying as needed */
+    /* Go through revoked entries, copying as needed */
 
-	revs = X509_CRL_get_REVOKED(newer);
+    revs = X509_CRL_get_REVOKED(newer);
 
-	for (j = 0; j < sk_X509_REVOKED_num(revs); j++)
-		{
-		X509_REVOKED *rvn, *rvtmp;
-		rvn = sk_X509_REVOKED_value(revs, j);
-		/* Add only if not also in base.
-		 * TODO: need something cleverer here for some more complex
-		 * CRLs covering multiple CAs.
-		 */
-		if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber))
-			{
-			rvtmp = X509_REVOKED_dup(rvn);
-			if (!rvtmp)
-				goto memerr;
-			if (!X509_CRL_add0_revoked(crl, rvtmp))
-				{
-				X509_REVOKED_free(rvtmp);
-				goto memerr;
-				}
-			}
-		}
-	/* TODO: optionally prune deleted entries */
+    for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
+        X509_REVOKED *rvn, *rvtmp;
+        rvn = sk_X509_REVOKED_value(revs, j);
+        /*
+         * Add only if not also in base. TODO: need something cleverer here
+         * for some more complex CRLs covering multiple CAs.
+         */
+        if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
+            rvtmp = X509_REVOKED_dup(rvn);
+            if (!rvtmp)
+                goto memerr;
+            if (!X509_CRL_add0_revoked(crl, rvtmp)) {
+                X509_REVOKED_free(rvtmp);
+                goto memerr;
+            }
+        }
+    }
+    /* TODO: optionally prune deleted entries */
 
-	if (skey && md && !X509_CRL_sign(crl, skey, md))
-		goto memerr;
-	
-	return crl;
+    if (skey && md && !X509_CRL_sign(crl, skey, md))
+        goto memerr;
 
-	memerr:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	if (crl)
-		X509_CRL_free(crl);
-	return NULL;
-	}
+    return crl;
 
-int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
-	{
-	/* This function is (usually) called only once, by
-	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
-	int index;
-	if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-			dup_func, free_func))
-		{
-		return -1;
-		}
-	return index;
-	}
+ memerr:
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    if (crl)
+        X509_CRL_free(crl);
+    return NULL;
+}
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
+                                    CRYPTO_EX_unused * unused,
+                                    CRYPTO_EX_dup *dup_func,
+                                    CRYPTO_EX_free *free_func)
+{
+    /*
+     * This function is (usually) called only once, by
+     * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
+     */
+    int index;
+    if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
+                                 dup_func, free_func)) {
+        return -1;
+    }
+    return index;
+}
 
 int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
-	{
-	return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
-	}
+{
+    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
 
 void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
-	{
-	return CRYPTO_get_ex_data(&ctx->ex_data,idx);
-	}
+{
+    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
 
 int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
-	{
-	return ctx->error;
-	}
+{
+    return ctx->error;
+}
 
 void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
-	{
-	ctx->error=err;
-	}
+{
+    ctx->error = err;
+}
 
 int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
-	{
-	return ctx->error_depth;
-	}
+{
+    return ctx->error_depth;
+}
 
 X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
-	{
-	return ctx->current_cert;
-	}
+{
+    return ctx->current_cert;
+}
 
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
-	{
-	return ctx->chain;
-	}
+{
+    return ctx->chain;
+}
 
 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
-	{
-	if (!ctx->chain)
-		return NULL;
-	return X509_chain_up_ref(ctx->chain);
-	}
+{
+    if (!ctx->chain)
+        return NULL;
+    return X509_chain_up_ref(ctx->chain);
+}
 
 X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
-	{
-	return ctx->current_issuer;
-	}
+{
+    return ctx->current_issuer;
+}
 
 X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
-	{
-	return ctx->current_crl;
-	}
+{
+    return ctx->current_crl;
+}
 
 X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
-	{
-	return ctx->parent;
-	}
+{
+    return ctx->parent;
+}
 
 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
-	{
-	ctx->cert=x;
-	}
+{
+    ctx->cert = x;
+}
 
 void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
-	{
-	ctx->untrusted=sk;
-	}
+{
+    ctx->untrusted = sk;
+}
 
 void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
-	{
-	ctx->crls=sk;
-	}
+{
+    ctx->crls = sk;
+}
 
 int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
-	{
-	return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
-	}
+{
+    return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
+}
 
 int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
-	{
-	return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
-	}
+{
+    return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
+}
 
-/* This function is used to set the X509_STORE_CTX purpose and trust
- * values. This is intended to be used when another structure has its
- * own trust and purpose values which (if set) will be inherited by
- * the ctx. If they aren't set then we will usually have a default
- * purpose in mind which should then be used to set the trust value.
- * An example of this is SSL use: an SSL structure will have its own
- * purpose and trust settings which the application can set: if they
- * aren't set then we use the default of SSL client/server.
+/*
+ * This function is used to set the X509_STORE_CTX purpose and trust values.
+ * This is intended to be used when another structure has its own trust and
+ * purpose values which (if set) will be inherited by the ctx. If they aren't
+ * set then we will usually have a default purpose in mind which should then
+ * be used to set the trust value. An example of this is SSL use: an SSL
+ * structure will have its own purpose and trust settings which the
+ * application can set: if they aren't set then we use the default of SSL
+ * client/server.
  */
 
 int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
-				int purpose, int trust)
+                                   int purpose, int trust)
 {
-	int idx;
-	/* If purpose not set use default */
-	if (!purpose) purpose = def_purpose;
-	/* If we have a purpose then check it is valid */
-	if (purpose)
-		{
-		X509_PURPOSE *ptmp;
-		idx = X509_PURPOSE_get_by_id(purpose);
-		if (idx == -1)
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
-			return 0;
-			}
-		ptmp = X509_PURPOSE_get0(idx);
-		if (ptmp->trust == X509_TRUST_DEFAULT)
-			{
-			idx = X509_PURPOSE_get_by_id(def_purpose);
-			if (idx == -1)
-				{
-				OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
-				return 0;
-				}
-			ptmp = X509_PURPOSE_get0(idx);
-			}
-		/* If trust not set then get from purpose default */
-		if (!trust) trust = ptmp->trust;
-		}
-	if (trust)
-		{
-		idx = X509_TRUST_get_by_id(trust);
-		if (idx == -1)
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
-			return 0;
-			}
-		}
+    int idx;
+    /* If purpose not set use default */
+    if (!purpose)
+        purpose = def_purpose;
+    /* If we have a purpose then check it is valid */
+    if (purpose) {
+        X509_PURPOSE *ptmp;
+        idx = X509_PURPOSE_get_by_id(purpose);
+        if (idx == -1) {
+            OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
+            return 0;
+        }
+        ptmp = X509_PURPOSE_get0(idx);
+        if (ptmp->trust == X509_TRUST_DEFAULT) {
+            idx = X509_PURPOSE_get_by_id(def_purpose);
+            if (idx == -1) {
+                OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
+                return 0;
+            }
+            ptmp = X509_PURPOSE_get0(idx);
+        }
+        /* If trust not set then get from purpose default */
+        if (!trust)
+            trust = ptmp->trust;
+    }
+    if (trust) {
+        idx = X509_TRUST_get_by_id(trust);
+        if (idx == -1) {
+            OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
+            return 0;
+        }
+    }
 
-	if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
-	if (trust && !ctx->param->trust) ctx->param->trust = trust;
-	return 1;
+    if (purpose && !ctx->param->purpose)
+        ctx->param->purpose = purpose;
+    if (trust && !ctx->param->trust)
+        ctx->param->trust = trust;
+    return 1;
 }
 
 X509_STORE_CTX *X509_STORE_CTX_new(void)
 {
-	X509_STORE_CTX *ctx;
-	ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
-	if (!ctx)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return NULL;
-		}
-	memset(ctx, 0, sizeof(X509_STORE_CTX));
-	return ctx;
+    X509_STORE_CTX *ctx;
+    ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
+    if (!ctx) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    memset(ctx, 0, sizeof(X509_STORE_CTX));
+    return ctx;
 }
 
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
 {
-	X509_STORE_CTX_cleanup(ctx);
-	OPENSSL_free(ctx);
+    if (ctx == NULL) {
+        return;
+    }
+    X509_STORE_CTX_cleanup(ctx);
+    OPENSSL_free(ctx);
 }
 
 int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
-	     STACK_OF(X509) *chain)
-	{
-	int ret = 1;
+                        STACK_OF(X509) *chain)
+{
+    int ret = 1;
 
-	memset(ctx, 0, sizeof(X509_STORE_CTX));
-	ctx->ctx=store;
-	ctx->cert=x509;
-	ctx->untrusted=chain;
+    memset(ctx, 0, sizeof(X509_STORE_CTX));
+    ctx->ctx = store;
+    ctx->cert = x509;
+    ctx->untrusted = chain;
 
-	CRYPTO_new_ex_data(&ctx->ex_data);
+    CRYPTO_new_ex_data(&ctx->ex_data);
 
-	ctx->param = X509_VERIFY_PARAM_new();
-	if (!ctx->param)
-		goto err;
+    ctx->param = X509_VERIFY_PARAM_new();
+    if (!ctx->param)
+        goto err;
 
-	/* Inherit callbacks and flags from X509_STORE if not set
-	 * use defaults. */
+    /*
+     * Inherit callbacks and flags from X509_STORE if not set use defaults.
+     */
 
-	if (store)
-		ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
-	else
-		ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
+    if (store)
+        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+    else
+        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
 
-	if (store)
-		{
-		ctx->verify_cb = store->verify_cb;
-		ctx->cleanup = store->cleanup;
-		}
-	else
-		ctx->cleanup = 0;
+    if (store) {
+        ctx->verify_cb = store->verify_cb;
+        ctx->cleanup = store->cleanup;
+    } else
+        ctx->cleanup = 0;
 
-	if (ret)
-		ret = X509_VERIFY_PARAM_inherit(ctx->param,
-					X509_VERIFY_PARAM_lookup("default"));
+    if (ret)
+        ret = X509_VERIFY_PARAM_inherit(ctx->param,
+                                        X509_VERIFY_PARAM_lookup("default"));
 
-	if (ret == 0)
-		goto err;
+    if (ret == 0)
+        goto err;
 
-	if (store && store->check_issued)
-		ctx->check_issued = store->check_issued;
-	else
-		ctx->check_issued = check_issued;
+    if (store && store->check_issued)
+        ctx->check_issued = store->check_issued;
+    else
+        ctx->check_issued = check_issued;
 
-	if (store && store->get_issuer)
-		ctx->get_issuer = store->get_issuer;
-	else
-		ctx->get_issuer = X509_STORE_CTX_get1_issuer;
+    if (store && store->get_issuer)
+        ctx->get_issuer = store->get_issuer;
+    else
+        ctx->get_issuer = X509_STORE_CTX_get1_issuer;
 
-	if (store && store->verify_cb)
-		ctx->verify_cb = store->verify_cb;
-	else
-		ctx->verify_cb = null_callback;
+    if (store && store->verify_cb)
+        ctx->verify_cb = store->verify_cb;
+    else
+        ctx->verify_cb = null_callback;
 
-	if (store && store->verify)
-		ctx->verify = store->verify;
-	else
-		ctx->verify = internal_verify;
+    if (store && store->verify)
+        ctx->verify = store->verify;
+    else
+        ctx->verify = internal_verify;
 
-	if (store && store->check_revocation)
-		ctx->check_revocation = store->check_revocation;
-	else
-		ctx->check_revocation = check_revocation;
+    if (store && store->check_revocation)
+        ctx->check_revocation = store->check_revocation;
+    else
+        ctx->check_revocation = check_revocation;
 
-	if (store && store->get_crl)
-		ctx->get_crl = store->get_crl;
-	else
-		ctx->get_crl = NULL;
+    if (store && store->get_crl)
+        ctx->get_crl = store->get_crl;
+    else
+        ctx->get_crl = NULL;
 
-	if (store && store->check_crl)
-		ctx->check_crl = store->check_crl;
-	else
-		ctx->check_crl = check_crl;
+    if (store && store->check_crl)
+        ctx->check_crl = store->check_crl;
+    else
+        ctx->check_crl = check_crl;
 
-	if (store && store->cert_crl)
-		ctx->cert_crl = store->cert_crl;
-	else
-		ctx->cert_crl = cert_crl;
+    if (store && store->cert_crl)
+        ctx->cert_crl = store->cert_crl;
+    else
+        ctx->cert_crl = cert_crl;
 
-	if (store && store->lookup_certs)
-		ctx->lookup_certs = store->lookup_certs;
-	else
-		ctx->lookup_certs = X509_STORE_get1_certs;
+    if (store && store->lookup_certs)
+        ctx->lookup_certs = store->lookup_certs;
+    else
+        ctx->lookup_certs = X509_STORE_get1_certs;
 
-	if (store && store->lookup_crls)
-		ctx->lookup_crls = store->lookup_crls;
-	else
-		ctx->lookup_crls = X509_STORE_get1_crls;
+    if (store && store->lookup_crls)
+        ctx->lookup_crls = store->lookup_crls;
+    else
+        ctx->lookup_crls = X509_STORE_get1_crls;
 
-	ctx->check_policy = check_policy;
+    ctx->check_policy = check_policy;
 
-	return 1;
+    return 1;
 
-err:
-	CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
-	if (ctx->param != NULL)
-		{
-		X509_VERIFY_PARAM_free(ctx->param);
-		}
+ err:
+    CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
+    if (ctx->param != NULL) {
+        X509_VERIFY_PARAM_free(ctx->param);
+    }
 
-	memset(ctx, 0, sizeof(X509_STORE_CTX));
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	return 0;
-	}
+    memset(ctx, 0, sizeof(X509_STORE_CTX));
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
 
-/* Set alternative lookup method: just a STACK of trusted certificates.
- * This avoids X509_STORE nastiness where it isn't needed.
+/*
+ * Set alternative lookup method: just a STACK of trusted certificates. This
+ * avoids X509_STORE nastiness where it isn't needed.
  */
 
 void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
 {
-	ctx->other_ctx = sk;
-	ctx->get_issuer = get_issuer_sk;
+    ctx->other_ctx = sk;
+    ctx->get_issuer = get_issuer_sk;
 }
 
 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
-	{
-	if (ctx->cleanup) ctx->cleanup(ctx);
-	if (ctx->param != NULL)
-		{
-		if (ctx->parent == NULL)
-			X509_VERIFY_PARAM_free(ctx->param);
-		ctx->param=NULL;
-		}
-	if (ctx->tree != NULL)
-		{
-		X509_policy_tree_free(ctx->tree);
-		ctx->tree=NULL;
-		}
-	if (ctx->chain != NULL)
-		{
-		sk_X509_pop_free(ctx->chain,X509_free);
-		ctx->chain=NULL;
-		}
-	CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
-	memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
-	}
+{
+    /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
+     * also calls this function. */
+    if (ctx->cleanup != NULL) {
+        ctx->cleanup(ctx);
+        ctx->cleanup = NULL;
+    }
+    if (ctx->param != NULL) {
+        if (ctx->parent == NULL)
+            X509_VERIFY_PARAM_free(ctx->param);
+        ctx->param = NULL;
+    }
+    if (ctx->tree != NULL) {
+        X509_policy_tree_free(ctx->tree);
+        ctx->tree = NULL;
+    }
+    if (ctx->chain != NULL) {
+        sk_X509_pop_free(ctx->chain, X509_free);
+        ctx->chain = NULL;
+    }
+    CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
+    memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
+}
 
 void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
-	{
-	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
-	}
+{
+    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+}
 
 void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
-	{
-	X509_VERIFY_PARAM_set_flags(ctx->param, flags);
-	}
+{
+    X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
 
-void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
-	{
-	X509_VERIFY_PARAM_set_time(ctx->param, t);
-	}
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+                             time_t t)
+{
+    X509_VERIFY_PARAM_set_time(ctx->param, t);
+}
 
 void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
-				  int (*verify_cb)(int, X509_STORE_CTX *))
-	{
-	ctx->verify_cb=verify_cb;
-	}
+                                  int (*verify_cb) (int, X509_STORE_CTX *))
+{
+    ctx->verify_cb = verify_cb;
+}
 
 X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
-	{
-	return ctx->tree;
-	}
+{
+    return ctx->tree;
+}
 
 int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
-	{
-	return ctx->explicit_policy;
-	}
+{
+    return ctx->explicit_policy;
+}
 
 int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
-	{
-	const X509_VERIFY_PARAM *param;
-	param = X509_VERIFY_PARAM_lookup(name);
-	if (!param)
-		return 0;
-	return X509_VERIFY_PARAM_inherit(ctx->param, param);
-	}
+{
+    const X509_VERIFY_PARAM *param;
+    param = X509_VERIFY_PARAM_lookup(name);
+    if (!param)
+        return 0;
+    return X509_VERIFY_PARAM_inherit(ctx->param, param);
+}
 
 X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
-	{
-	return ctx->param;
-	}
+{
+    return ctx->param;
+}
 
 void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
-	{
-	if (ctx->param)
-		X509_VERIFY_PARAM_free(ctx->param);
-	ctx->param = param;
-	}
+{
+    if (ctx->param)
+        X509_VERIFY_PARAM_free(ctx->param);
+    ctx->param = param;
+}
 
 IMPLEMENT_ASN1_SET_OF(X509)
+
 IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 8c8f98e..b51bc17 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -64,609 +66,571 @@
 
 #include "vpm_int.h"
 
-
 /* X509_VERIFY_PARAM functions */
 
 #define SET_HOST 0
 #define ADD_HOST 1
 
-static char *str_copy(char *s) { return OPENSSL_strdup(s); }
-static void str_free(char *s) { OPENSSL_free(s); }
+static char *str_copy(char *s)
+{
+    return OPENSSL_strdup(s);
+}
+
+static void str_free(char *s)
+{
+    OPENSSL_free(s);
+}
 
 #define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
 
 static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
-				    const char *name, size_t namelen)
-	{
-	char *copy;
+                                    const char *name, size_t namelen)
+{
+    char *copy;
 
-	/*
-	 * Refuse names with embedded NUL bytes.
-	 * XXX: Do we need to push an error onto the error stack?
-	 */
-	if (name && memchr(name, '\0', namelen))
-		 return 0;
+    /*
+     * Refuse names with embedded NUL bytes.
+     * XXX: Do we need to push an error onto the error stack?
+     */
+    if (name && memchr(name, '\0', namelen))
+        return 0;
 
-	if (mode == SET_HOST && id->hosts)
-		{
-		string_stack_free(id->hosts);
-		id->hosts = NULL;
-		}
-	if (name == NULL || namelen == 0)
-		return 1;
+    if (mode == SET_HOST && id->hosts) {
+        string_stack_free(id->hosts);
+        id->hosts = NULL;
+    }
+    if (name == NULL || namelen == 0)
+        return 1;
 
-	copy = BUF_strndup(name, namelen);
-	if (copy == NULL)
-		return 0;
+    copy = BUF_strndup(name, namelen);
+    if (copy == NULL)
+        return 0;
 
-	if (id->hosts == NULL &&
-	    (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL)
-		{
-		OPENSSL_free(copy);
-		return 0;
-		}
+    if (id->hosts == NULL &&
+        (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
+        OPENSSL_free(copy);
+        return 0;
+    }
 
-	if (!sk_OPENSSL_STRING_push(id->hosts, copy))
-		{
-		OPENSSL_free(copy);
-		if (sk_OPENSSL_STRING_num(id->hosts) == 0)
-			{
-			sk_OPENSSL_STRING_free(id->hosts);
-			id->hosts = NULL;
-			}
-		return 0;
-		}
+    if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
+        OPENSSL_free(copy);
+        if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
+            sk_OPENSSL_STRING_free(id->hosts);
+            id->hosts = NULL;
+        }
+        return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
-	{
-	X509_VERIFY_PARAM_ID *paramid;
-	if (!param)
-		return;
-	param->name = NULL;
-	param->purpose = 0;
-	param->trust = 0;
-	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
-	param->inh_flags = 0;
-	param->flags = 0;
-	param->depth = -1;
-	if (param->policies)
-		{
-		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
-		param->policies = NULL;
-		}
-	paramid = param->id;
-	if (paramid->hosts)
-		{
-		string_stack_free(paramid->hosts);
-		paramid->hosts = NULL;
-		}
-	if (paramid->peername)
-		{
-		OPENSSL_free(paramid->peername);
-		paramid->peername = NULL;
-		}
-	if (paramid->email)
-		{
-		OPENSSL_free(paramid->email);
-		paramid->email = NULL;
-		paramid->emaillen = 0;
-		}
-	if (paramid->ip)
-		{
-		OPENSSL_free(paramid->ip);
-		paramid->ip = NULL;
-		paramid->iplen = 0;
-		}
+{
+    X509_VERIFY_PARAM_ID *paramid;
+    if (!param)
+        return;
+    param->name = NULL;
+    param->purpose = 0;
+    param->trust = 0;
+    /*
+     * param->inh_flags = X509_VP_FLAG_DEFAULT;
+     */
+    param->inh_flags = 0;
+    param->flags = 0;
+    param->depth = -1;
+    if (param->policies) {
+        sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+        param->policies = NULL;
+    }
+    paramid = param->id;
+    if (paramid->hosts) {
+        string_stack_free(paramid->hosts);
+        paramid->hosts = NULL;
+    }
+    if (paramid->peername) {
+        OPENSSL_free(paramid->peername);
+        paramid->peername = NULL;
+    }
+    if (paramid->email) {
+        OPENSSL_free(paramid->email);
+        paramid->email = NULL;
+        paramid->emaillen = 0;
+    }
+    if (paramid->ip) {
+        OPENSSL_free(paramid->ip);
+        paramid->ip = NULL;
+        paramid->iplen = 0;
+    }
 
-	}
+}
 
 X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
-	{
-	X509_VERIFY_PARAM *param;
-	X509_VERIFY_PARAM_ID *paramid;
-	param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
-	if (!param)
-		return NULL;
-	paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID));
-	if (!paramid)
-		{
-		OPENSSL_free(param);
-		return NULL;
-		}
-	memset(param, 0, sizeof(X509_VERIFY_PARAM));
-	memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID));
-	param->id = paramid;
-	x509_verify_param_zero(param);
-	return param;
-	}
+{
+    X509_VERIFY_PARAM *param;
+    X509_VERIFY_PARAM_ID *paramid;
+    param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+    if (!param)
+        return NULL;
+    paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID));
+    if (!paramid) {
+        OPENSSL_free(param);
+        return NULL;
+    }
+    memset(param, 0, sizeof(X509_VERIFY_PARAM));
+    memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID));
+    param->id = paramid;
+    x509_verify_param_zero(param);
+    return param;
+}
 
 void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
-	{
-	if (param == NULL)
-		return;
-	x509_verify_param_zero(param);
-	OPENSSL_free(param->id);
-	OPENSSL_free(param);
-	}
+{
+    if (param == NULL)
+        return;
+    x509_verify_param_zero(param);
+    OPENSSL_free(param->id);
+    OPENSSL_free(param);
+}
 
-/* This function determines how parameters are "inherited" from one structure
- * to another. There are several different ways this can happen.
- *
- * 1. If a child structure needs to have its values initialized from a parent
- *    they are simply copied across. For example SSL_CTX copied to SSL.
- * 2. If the structure should take on values only if they are currently unset.
- *    For example the values in an SSL structure will take appropriate value
- *    for SSL servers or clients but only if the application has not set new
- *    ones.
- *
- * The "inh_flags" field determines how this function behaves. 
- *
- * Normally any values which are set in the default are not copied from the
- * destination and verify flags are ORed together.
- *
- * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
- * to the destination. Effectively the values in "to" become default values
- * which will be used only if nothing new is set in "from".
- *
- * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
- * they are set or not. Flags is still Ored though.
- *
- * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
- * of ORed.
- *
- * If X509_VP_FLAG_LOCKED is set then no values are copied.
- *
- * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
- * after the next call.
+/*
+ * This function determines how parameters are "inherited" from one structure
+ * to another. There are several different ways this can happen. 1. If a
+ * child structure needs to have its values initialized from a parent they are
+ * simply copied across. For example SSL_CTX copied to SSL. 2. If the
+ * structure should take on values only if they are currently unset.  For
+ * example the values in an SSL structure will take appropriate value for SSL
+ * servers or clients but only if the application has not set new ones. The
+ * "inh_flags" field determines how this function behaves. Normally any
+ * values which are set in the default are not copied from the destination and
+ * verify flags are ORed together. If X509_VP_FLAG_DEFAULT is set then
+ * anything set in the source is copied to the destination. Effectively the
+ * values in "to" become default values which will be used only if nothing new
+ * is set in "from". If X509_VP_FLAG_OVERWRITE is set then all value are
+ * copied across whether they are set or not. Flags is still Ored though. If
+ * X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead of
+ * ORed. If X509_VP_FLAG_LOCKED is set then no values are copied. If
+ * X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed after
+ * the next call.
  */
 
 /* Macro to test if a field should be copied from src to dest */
 
 #define test_x509_verify_param_copy(field, def) \
-	(to_overwrite || \
-		((src->field != def) && (to_default || (dest->field == def))))
+        (to_overwrite || \
+                ((src->field != def) && (to_default || (dest->field == def))))
 
 /* As above but for ID fields */
 
 #define test_x509_verify_param_copy_id(idf, def) \
-	test_x509_verify_param_copy(id->idf, def)
+        test_x509_verify_param_copy(id->idf, def)
 
 /* Macro to test and copy a field if necessary */
 
 #define x509_verify_param_copy(field, def) \
-	if (test_x509_verify_param_copy(field, def)) \
-		dest->field = src->field
-
+        if (test_x509_verify_param_copy(field, def)) \
+                dest->field = src->field
 
 int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
-						const X509_VERIFY_PARAM *src)
-	{
-	unsigned long inh_flags;
-	int to_default, to_overwrite;
-	X509_VERIFY_PARAM_ID *id;
-	if (!src)
-		return 1;
-	id = src->id;
-	inh_flags = dest->inh_flags | src->inh_flags;
+                              const X509_VERIFY_PARAM *src)
+{
+    unsigned long inh_flags;
+    int to_default, to_overwrite;
+    X509_VERIFY_PARAM_ID *id;
+    if (!src)
+        return 1;
+    id = src->id;
+    inh_flags = dest->inh_flags | src->inh_flags;
 
-	if (inh_flags & X509_VP_FLAG_ONCE)
-		dest->inh_flags = 0;
+    if (inh_flags & X509_VP_FLAG_ONCE)
+        dest->inh_flags = 0;
 
-	if (inh_flags & X509_VP_FLAG_LOCKED)
-		return 1;
+    if (inh_flags & X509_VP_FLAG_LOCKED)
+        return 1;
 
-	if (inh_flags & X509_VP_FLAG_DEFAULT)
-		to_default = 1;
-	else
-		to_default = 0;
+    if (inh_flags & X509_VP_FLAG_DEFAULT)
+        to_default = 1;
+    else
+        to_default = 0;
 
-	if (inh_flags & X509_VP_FLAG_OVERWRITE)
-		to_overwrite = 1;
-	else
-		to_overwrite = 0;
+    if (inh_flags & X509_VP_FLAG_OVERWRITE)
+        to_overwrite = 1;
+    else
+        to_overwrite = 0;
 
-	x509_verify_param_copy(purpose, 0);
-	x509_verify_param_copy(trust, 0);
-	x509_verify_param_copy(depth, -1);
+    x509_verify_param_copy(purpose, 0);
+    x509_verify_param_copy(trust, 0);
+    x509_verify_param_copy(depth, -1);
 
-	/* If overwrite or check time not set, copy across */
+    /* If overwrite or check time not set, copy across */
 
-	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME))
-		{
-		dest->check_time = src->check_time;
-		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
-		/* Don't need to copy flag: that is done below */
-		}
+    if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
+        dest->check_time = src->check_time;
+        dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
+        /* Don't need to copy flag: that is done below */
+    }
 
-	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
-		dest->flags = 0;
+    if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
+        dest->flags = 0;
 
-	dest->flags |= src->flags;
+    dest->flags |= src->flags;
 
-	if (test_x509_verify_param_copy(policies, NULL))
-		{
-		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
-			return 0;
-		}
+    if (test_x509_verify_param_copy(policies, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
+            return 0;
+    }
 
-	/* Copy the host flags if and only if we're copying the host list */
-	if (test_x509_verify_param_copy_id(hosts, NULL))
-		{
-		if (dest->id->hosts)
-			{
-			string_stack_free(dest->id->hosts);
-			dest->id->hosts = NULL;
-			}
-		if (id->hosts)
-			{
-			dest->id->hosts =
-			    sk_OPENSSL_STRING_deep_copy(id->hosts,
-							str_copy, str_free);
-			if (dest->id->hosts == NULL)
-				return 0;
-			dest->id->hostflags = id->hostflags;
-			}
-		}
+    /* Copy the host flags if and only if we're copying the host list */
+    if (test_x509_verify_param_copy_id(hosts, NULL)) {
+        if (dest->id->hosts) {
+            string_stack_free(dest->id->hosts);
+            dest->id->hosts = NULL;
+        }
+        if (id->hosts) {
+            dest->id->hosts =
+                sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free);
+            if (dest->id->hosts == NULL)
+                return 0;
+            dest->id->hostflags = id->hostflags;
+        }
+    }
 
-	if (test_x509_verify_param_copy_id(email, NULL))
-		{
-		if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
-			return 0;
-		}
+    if (test_x509_verify_param_copy_id(email, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
+            return 0;
+    }
 
-	if (test_x509_verify_param_copy_id(ip, NULL))
-		{
-		if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
-			return 0;
-		}
+    if (test_x509_verify_param_copy_id(ip, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
+            return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
-						const X509_VERIFY_PARAM *from)
-	{
-	unsigned long save_flags = to->inh_flags;
-	int ret;
-	to->inh_flags |= X509_VP_FLAG_DEFAULT;
-	ret = X509_VERIFY_PARAM_inherit(to, from);
-	to->inh_flags = save_flags;
-	return ret;
-	}
+                           const X509_VERIFY_PARAM *from)
+{
+    unsigned long save_flags = to->inh_flags;
+    int ret;
+    to->inh_flags |= X509_VP_FLAG_DEFAULT;
+    ret = X509_VERIFY_PARAM_inherit(to, from);
+    to->inh_flags = save_flags;
+    return ret;
+}
 
 static int int_x509_param_set1(char **pdest, size_t *pdestlen,
-				const char *src, size_t srclen)
-	{
-	void *tmp;
-	if (src)
-		{
-		if (srclen == 0)
-			{
-			tmp = BUF_strdup(src);
-			srclen = strlen(src);
-			}
-		else
-			tmp = BUF_memdup(src, srclen);
-		if (!tmp)
-			return 0;
-		}
-	else
-		{
-		tmp = NULL;
-		srclen = 0;
-		}
-	if (*pdest)
-		OPENSSL_free(*pdest);
-	*pdest = tmp;
-	if (pdestlen)
-		*pdestlen = srclen;
-	return 1;
-	}
+                               const char *src, size_t srclen)
+{
+    void *tmp;
+    if (src) {
+        if (srclen == 0) {
+            tmp = BUF_strdup(src);
+            srclen = strlen(src);
+        } else
+            tmp = BUF_memdup(src, srclen);
+        if (!tmp)
+            return 0;
+    } else {
+        tmp = NULL;
+        srclen = 0;
+    }
+    if (*pdest)
+        OPENSSL_free(*pdest);
+    *pdest = tmp;
+    if (pdestlen)
+        *pdestlen = srclen;
+    return 1;
+}
 
 int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
-	{
-	if (param->name)
-		OPENSSL_free(param->name);
-	param->name = BUF_strdup(name);
-	if (param->name)
-		return 1;
-	return 0;
-	}
+{
+    if (param->name)
+        OPENSSL_free(param->name);
+    param->name = BUF_strdup(name);
+    if (param->name)
+        return 1;
+    return 0;
+}
 
 int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
-	{
-	param->flags |= flags;
-	if (flags & X509_V_FLAG_POLICY_MASK)
-		param->flags |= X509_V_FLAG_POLICY_CHECK;
-	return 1;
-	}
+{
+    param->flags |= flags;
+    if (flags & X509_V_FLAG_POLICY_MASK)
+        param->flags |= X509_V_FLAG_POLICY_CHECK;
+    return 1;
+}
 
-int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
-	{
-	param->flags &= ~flags;
-	return 1;
-	}
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+                                  unsigned long flags)
+{
+    param->flags &= ~flags;
+    return 1;
+}
 
 unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
-	{
-	return param->flags;
-	}
+{
+    return param->flags;
+}
 
 int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
-	{
-	return X509_PURPOSE_set(&param->purpose, purpose);
-	}
+{
+    return X509_PURPOSE_set(&param->purpose, purpose);
+}
 
 int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
-	{
-	return X509_TRUST_set(&param->trust, trust);
-	}
+{
+    return X509_TRUST_set(&param->trust, trust);
+}
 
 void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
-	{
-	param->depth = depth;
-	}
+{
+    param->depth = depth;
+}
 
 void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
-	{
-	param->check_time = t;
-	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
-	}
+{
+    param->check_time = t;
+    param->flags |= X509_V_FLAG_USE_CHECK_TIME;
+}
 
-int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
-	{
-	if (!param->policies)
-		{
-		param->policies = sk_ASN1_OBJECT_new_null();
-		if (!param->policies)
-			return 0;
-		}
-	if (!sk_ASN1_OBJECT_push(param->policies, policy))
-		return 0;
-	return 1;
-	}
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+                                  ASN1_OBJECT *policy)
+{
+    if (!param->policies) {
+        param->policies = sk_ASN1_OBJECT_new_null();
+        if (!param->policies)
+            return 0;
+    }
+    if (!sk_ASN1_OBJECT_push(param->policies, policy))
+        return 0;
+    return 1;
+}
 
-int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
-					STACK_OF(ASN1_OBJECT) *policies)
-	{
-	size_t i;
-	ASN1_OBJECT *oid, *doid;
-	if (!param)
-		return 0;
-	if (param->policies)
-		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+                                    STACK_OF(ASN1_OBJECT) *policies)
+{
+    size_t i;
+    ASN1_OBJECT *oid, *doid;
+    if (!param)
+        return 0;
+    if (param->policies)
+        sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
 
-	if (!policies)
-		{
-		param->policies = NULL;
-		return 1;
-		}
+    if (!policies) {
+        param->policies = NULL;
+        return 1;
+    }
 
-	param->policies = sk_ASN1_OBJECT_new_null();
-	if (!param->policies)
-		return 0;
+    param->policies = sk_ASN1_OBJECT_new_null();
+    if (!param->policies)
+        return 0;
 
-	for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++)
-		{
-		oid = sk_ASN1_OBJECT_value(policies, i);
-		doid = OBJ_dup(oid);
-		if (!doid)
-			return 0;
-		if (!sk_ASN1_OBJECT_push(param->policies, doid))
-			{
-			ASN1_OBJECT_free(doid);
-			return 0;
-			}
-		}
-	param->flags |= X509_V_FLAG_POLICY_CHECK;
-	return 1;
-	}
+    for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
+        oid = sk_ASN1_OBJECT_value(policies, i);
+        doid = OBJ_dup(oid);
+        if (!doid)
+            return 0;
+        if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
+            ASN1_OBJECT_free(doid);
+            return 0;
+        }
+    }
+    param->flags |= X509_V_FLAG_POLICY_CHECK;
+    return 1;
+}
 
 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
-				const char *name, size_t namelen)
-	{
-	return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
-	}
+                                const char *name, size_t namelen)
+{
+    return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
+}
 
 int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
-				const char *name, size_t namelen)
-	{
-	return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
-	}
+                                const char *name, size_t namelen)
+{
+    return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
+}
 
 void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
-					unsigned int flags)
-	{
-	param->id->hostflags = flags;
-	}
+                                     unsigned int flags)
+{
+    param->id->hostflags = flags;
+}
 
 char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
-	{
-	return param->id->peername;
-	}
+{
+    return param->id->peername;
+}
 
 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
-				const char *email, size_t emaillen)
-	{
-	return int_x509_param_set1(&param->id->email, &param->id->emaillen,
-					email, emaillen);
-	}
+                                 const char *email, size_t emaillen)
+{
+    return int_x509_param_set1(&param->id->email, &param->id->emaillen,
+                               email, emaillen);
+}
 
 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
-					const unsigned char *ip, size_t iplen)
-	{
-	if (iplen != 0 && iplen != 4 && iplen != 16)
-		return 0;
-	return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
-				   (char *)ip, iplen);
-	}
+                              const unsigned char *ip, size_t iplen)
+{
+    if (iplen != 0 && iplen != 4 && iplen != 16)
+        return 0;
+    return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
+                               (char *)ip, iplen);
+}
 
 int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
-	{
-	unsigned char ipout[16];
-	size_t iplen;
+{
+    unsigned char ipout[16];
+    size_t iplen;
 
-	iplen = (size_t) a2i_ipadd(ipout, ipasc);
-	if (iplen == 0)
-		return 0;
-	return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
-	}
+    iplen = (size_t)a2i_ipadd(ipout, ipasc);
+    if (iplen == 0)
+        return 0;
+    return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
+}
 
 int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
-	{
-	return param->depth;
-	}
+{
+    return param->depth;
+}
 
 const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
-	{
-	return param->name;
-	}
+{
+    return param->name;
+}
 
-static const X509_VERIFY_PARAM_ID _empty_id = {NULL, 0U, NULL, NULL, 0, NULL, 0};
+static const X509_VERIFY_PARAM_ID _empty_id =
+    { NULL, 0U, NULL, NULL, 0, NULL, 0 };
 
 #define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
 
-/* Default verify parameters: these are used for various
- * applications and can be overridden by the user specified table.
- * NB: the 'name' field *must* be in alphabetical order because it
- * will be searched using OBJ_search.
+/*
+ * Default verify parameters: these are used for various applications and can
+ * be overridden by the user specified table. NB: the 'name' field *must* be
+ * in alphabetical order because it will be searched using OBJ_search.
  */
 
 static const X509_VERIFY_PARAM default_table[] = {
-	{
-	(char *) "default",	/* X509 default parameters */
-	0,		/* Check time */
-	0,		/* internal flags */
-	0,		/* flags */
-	0,		/* purpose */
-	0,		/* trust */
-	100,		/* depth */
-	NULL,		/* policies */
-	vpm_empty_id
-	},
-	{
-	(char *) "pkcs7",			/* S/MIME sign parameters */
-	0,				/* Check time */
-	0,				/* internal flags */
-	0,				/* flags */
-	X509_PURPOSE_SMIME_SIGN,	/* purpose */
-	X509_TRUST_EMAIL,		/* trust */
-	-1,				/* depth */
-	NULL,				/* policies */
-	vpm_empty_id
-	},
-	{
-	(char *) "smime_sign",			/* S/MIME sign parameters */
-	0,				/* Check time */
-	0,				/* internal flags */
-	0,				/* flags */
-	X509_PURPOSE_SMIME_SIGN,	/* purpose */
-	X509_TRUST_EMAIL,		/* trust */
-	-1,				/* depth */
-	NULL,				/* policies */
-	vpm_empty_id
-	},
-	{
-	(char *) "ssl_client",			/* SSL/TLS client parameters */
-	0,				/* Check time */
-	0,				/* internal flags */
-	0,				/* flags */
-	X509_PURPOSE_SSL_CLIENT,	/* purpose */
-	X509_TRUST_SSL_CLIENT,		/* trust */
-	-1,				/* depth */
-	NULL,				/* policies */
-	vpm_empty_id
-	},
-	{
-	(char *) "ssl_server",			/* SSL/TLS server parameters */
-	0,				/* Check time */
-	0,				/* internal flags */
-	0,				/* flags */
-	X509_PURPOSE_SSL_SERVER,	/* purpose */
-	X509_TRUST_SSL_SERVER,		/* trust */
-	-1,				/* depth */
-	NULL,				/* policies */
-	vpm_empty_id
-	}};
+    {
+     (char *)"default",         /* X509 default parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     0,                         /* purpose */
+     0,                         /* trust */
+     100,                       /* depth */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     (char *)"pkcs7",           /* S/MIME sign parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SMIME_SIGN,   /* purpose */
+     X509_TRUST_EMAIL,          /* trust */
+     -1,                        /* depth */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     (char *)"smime_sign",      /* S/MIME sign parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SMIME_SIGN,   /* purpose */
+     X509_TRUST_EMAIL,          /* trust */
+     -1,                        /* depth */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     (char *)"ssl_client",      /* SSL/TLS client parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SSL_CLIENT,   /* purpose */
+     X509_TRUST_SSL_CLIENT,     /* trust */
+     -1,                        /* depth */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     (char *)"ssl_server",      /* SSL/TLS server parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SSL_SERVER,   /* purpose */
+     X509_TRUST_SSL_SERVER,     /* trust */
+     -1,                        /* depth */
+     NULL,                      /* policies */
+     vpm_empty_id}
+};
 
 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
 
-static int param_cmp(const X509_VERIFY_PARAM **a,
-			const X509_VERIFY_PARAM **b)
-	{
-	return strcmp((*a)->name, (*b)->name);
-	}
+static int param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b)
+{
+    return strcmp((*a)->name, (*b)->name);
+}
 
 int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
-	{
-	X509_VERIFY_PARAM *ptmp;
-	if (!param_table)
-		{
-		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
-		if (!param_table)
-			return 0;
-		}
-	else
-		{
-		size_t idx;
+{
+    X509_VERIFY_PARAM *ptmp;
+    if (!param_table) {
+        param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
+        if (!param_table)
+            return 0;
+    } else {
+        size_t idx;
 
-		if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param))
-			{
-			ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
-			X509_VERIFY_PARAM_free(ptmp);
-			(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
-			}
-		}
-	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
-		return 0;
-	return 1;
-	}
+        if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) {
+            ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+            X509_VERIFY_PARAM_free(ptmp);
+            (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
+        }
+    }
+    if (!sk_X509_VERIFY_PARAM_push(param_table, param))
+        return 0;
+    return 1;
+}
 
 int X509_VERIFY_PARAM_get_count(void)
-	{
-	int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
-	if (param_table)
-		num += sk_X509_VERIFY_PARAM_num(param_table);
-	return num;
-	}
+{
+    int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+    if (param_table)
+        num += sk_X509_VERIFY_PARAM_num(param_table);
+    return num;
+}
 
 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
-	{
-	int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
-	if (id < num)
-		return default_table + id;
-	return sk_X509_VERIFY_PARAM_value(param_table, id - num);
-	}
+{
+    int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+    if (id < num)
+        return default_table + id;
+    return sk_X509_VERIFY_PARAM_value(param_table, id - num);
+}
 
 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
-	{
-	X509_VERIFY_PARAM pm;
-	unsigned i, limit;
+{
+    X509_VERIFY_PARAM pm;
+    unsigned i, limit;
 
-	pm.name = (char *)name;
-	if (param_table)
-		{
-		size_t idx;
-		if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
-			return sk_X509_VERIFY_PARAM_value(param_table, idx);
-		}
+    pm.name = (char *)name;
+    if (param_table) {
+        size_t idx;
+        if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
+            return sk_X509_VERIFY_PARAM_value(param_table, idx);
+    }
 
-	limit = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
-	for (i = 0; i < limit; i++) {
-		if (strcmp(default_table[i].name, name) == 0) {
-			return &default_table[i];
-		}
-	}
-	return NULL;
-	}
+    limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+    for (i = 0; i < limit; i++) {
+        if (strcmp(default_table[i].name, name) == 0) {
+            return &default_table[i];
+        }
+    }
+    return NULL;
+}
 
 void X509_VERIFY_PARAM_table_cleanup(void)
-	{
-	if (param_table)
-		sk_X509_VERIFY_PARAM_pop_free(param_table,
-						X509_VERIFY_PARAM_free);
-	param_table = NULL;
-	}
+{
+    if (param_table)
+        sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
+    param_table = NULL;
+}
diff --git a/src/crypto/x509/x509cset.c b/src/crypto/x509/x509cset.c
index 82d61d0..a292710 100644
--- a/src/crypto/x509/x509cset.c
+++ b/src/crypto/x509/x509cset.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
 /* ====================================================================
  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -59,114 +61,109 @@
 
 #include "../internal.h"
 
-
 int X509_CRL_set_version(X509_CRL *x, long version)
-	{
-	if (x == NULL) return(0);
-	if (x->crl->version == NULL)
-		{
-		if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL)
-			return(0);
-		}
-	return(ASN1_INTEGER_set(x->crl->version,version));
-	}
+{
+    if (x == NULL)
+        return (0);
+    if (x->crl->version == NULL) {
+        if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL)
+            return (0);
+    }
+    return (ASN1_INTEGER_set(x->crl->version, version));
+}
 
 int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
-	{
-	if ((x == NULL) || (x->crl == NULL)) return(0);
-	return(X509_NAME_set(&x->crl->issuer,name));
-	}
-
+{
+    if ((x == NULL) || (x->crl == NULL))
+        return (0);
+    return (X509_NAME_set(&x->crl->issuer, name));
+}
 
 int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
-	{
-	ASN1_TIME *in;
+{
+    ASN1_TIME *in;
 
-	if (x == NULL) return(0);
-	in=x->crl->lastUpdate;
-	if (in != tm)
-		{
-		in=M_ASN1_TIME_dup(tm);
-		if (in != NULL)
-			{
-			M_ASN1_TIME_free(x->crl->lastUpdate);
-			x->crl->lastUpdate=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if (x == NULL)
+        return (0);
+    in = x->crl->lastUpdate;
+    if (in != tm) {
+        in = M_ASN1_TIME_dup(tm);
+        if (in != NULL) {
+            M_ASN1_TIME_free(x->crl->lastUpdate);
+            x->crl->lastUpdate = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
-	{
-	ASN1_TIME *in;
+{
+    ASN1_TIME *in;
 
-	if (x == NULL) return(0);
-	in=x->crl->nextUpdate;
-	if (in != tm)
-		{
-		in=M_ASN1_TIME_dup(tm);
-		if (in != NULL)
-			{
-			M_ASN1_TIME_free(x->crl->nextUpdate);
-			x->crl->nextUpdate=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if (x == NULL)
+        return (0);
+    in = x->crl->nextUpdate;
+    if (in != tm) {
+        in = M_ASN1_TIME_dup(tm);
+        if (in != NULL) {
+            M_ASN1_TIME_free(x->crl->nextUpdate);
+            x->crl->nextUpdate = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_CRL_sort(X509_CRL *c)
-	{
-	size_t i;
-	X509_REVOKED *r;
-	/* sort the data so it will be written in serial
-	 * number order */
-	sk_X509_REVOKED_sort(c->crl->revoked);
-	for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++)
-		{
-		r=sk_X509_REVOKED_value(c->crl->revoked,i);
-		r->sequence=i;
-		}
-	c->crl->enc.modified = 1;
-	return 1;
-	}
+{
+    size_t i;
+    X509_REVOKED *r;
+    /*
+     * sort the data so it will be written in serial number order
+     */
+    sk_X509_REVOKED_sort(c->crl->revoked);
+    for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) {
+        r = sk_X509_REVOKED_value(c->crl->revoked, i);
+        r->sequence = i;
+    }
+    c->crl->enc.modified = 1;
+    return 1;
+}
 
 void X509_CRL_up_ref(X509_CRL *crl)
-	{
-	CRYPTO_refcount_inc(&crl->references);
-	}
+{
+    CRYPTO_refcount_inc(&crl->references);
+}
 
 int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
-	{
-	ASN1_TIME *in;
+{
+    ASN1_TIME *in;
 
-	if (x == NULL) return(0);
-	in=x->revocationDate;
-	if (in != tm)
-		{
-		in=M_ASN1_TIME_dup(tm);
-		if (in != NULL)
-			{
-			M_ASN1_TIME_free(x->revocationDate);
-			x->revocationDate=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if (x == NULL)
+        return (0);
+    in = x->revocationDate;
+    if (in != tm) {
+        in = M_ASN1_TIME_dup(tm);
+        if (in != NULL) {
+            M_ASN1_TIME_free(x->revocationDate);
+            x->revocationDate = in;
+        }
+    }
+    return (in != NULL);
+}
 
 int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
-	{
-	ASN1_INTEGER *in;
+{
+    ASN1_INTEGER *in;
 
-	if (x == NULL) return(0);
-	in=x->serialNumber;
-	if (in != serial)
-		{
-		in=M_ASN1_INTEGER_dup(serial);
-		if (in != NULL)
-			{
-			M_ASN1_INTEGER_free(x->serialNumber);
-			x->serialNumber=in;
-			}
-		}
-	return(in != NULL);
-	}
+    if (x == NULL)
+        return (0);
+    in = x->serialNumber;
+    if (in != serial) {
+        in = M_ASN1_INTEGER_dup(serial);
+        if (in != NULL) {
+            M_ASN1_INTEGER_free(x->serialNumber);
+            x->serialNumber = in;
+        }
+    }
+    return (in != NULL);
+}
diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c
index 8b10fa2..050e16a 100644
--- a/src/crypto/x509/x509name.c
+++ b/src/crypto/x509/x509name.c
@@ -63,313 +63,324 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
-
 int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
-	{
-	const ASN1_OBJECT *obj;
+{
+    const ASN1_OBJECT *obj;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL) return(-1);
-	return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
-	}
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-1);
+    return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
+}
 
-int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
-	     int len)
-	{
-	int i;
-	ASN1_STRING *data;
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+                              char *buf, int len)
+{
+    int i;
+    ASN1_STRING *data;
 
-	i=X509_NAME_get_index_by_OBJ(name,obj,-1);
-	if (i < 0) return(-1);
-	data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
-	i=(data->length > (len-1))?(len-1):data->length;
-	if (buf == NULL) return(data->length);
-	memcpy(buf,data->data,i);
-	buf[i]='\0';
-	return(i);
-	}
+    i = X509_NAME_get_index_by_OBJ(name, obj, -1);
+    if (i < 0)
+        return (-1);
+    data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+    i = (data->length > (len - 1)) ? (len - 1) : data->length;
+    if (buf == NULL)
+        return (data->length);
+    memcpy(buf, data->data, i);
+    buf[i] = '\0';
+    return (i);
+}
 
 int X509_NAME_entry_count(X509_NAME *name)
-	{
-	if (name == NULL) return(0);
-	return(sk_X509_NAME_ENTRY_num(name->entries));
-	}
+{
+    if (name == NULL)
+        return (0);
+    return (sk_X509_NAME_ENTRY_num(name->entries));
+}
 
 int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
-	{
-	const ASN1_OBJECT *obj;
+{
+    const ASN1_OBJECT *obj;
 
-	obj=OBJ_nid2obj(nid);
-	if (obj == NULL) return(-2);
-	return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
-	}
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-2);
+    return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
+}
 
 /* NOTE: you should be passsing -1, not 0 as lastpos */
 int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
-	     int lastpos)
-	{
-	int n;
-	X509_NAME_ENTRY *ne;
-	STACK_OF(X509_NAME_ENTRY) *sk;
+                               int lastpos)
+{
+    int n;
+    X509_NAME_ENTRY *ne;
+    STACK_OF(X509_NAME_ENTRY) *sk;
 
-	if (name == NULL) return(-1);
-	if (lastpos < 0)
-		lastpos= -1;
-	sk=name->entries;
-	n=sk_X509_NAME_ENTRY_num(sk);
-	for (lastpos++; lastpos < n; lastpos++)
-		{
-		ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
-		if (OBJ_cmp(ne->object,obj) == 0)
-			return(lastpos);
-		}
-	return(-1);
-	}
+    if (name == NULL)
+        return (-1);
+    if (lastpos < 0)
+        lastpos = -1;
+    sk = name->entries;
+    n = sk_X509_NAME_ENTRY_num(sk);
+    for (lastpos++; lastpos < n; lastpos++) {
+        ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
+        if (OBJ_cmp(ne->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
+}
 
 X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
-	{
-	if(name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
-		return(NULL);
-	else
-		return(sk_X509_NAME_ENTRY_value(name->entries,loc));
-	}
+{
+    if (name == NULL || loc < 0
+        || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc)
+        return (NULL);
+    else
+        return (sk_X509_NAME_ENTRY_value(name->entries, loc));
+}
 
 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
-	{
-	X509_NAME_ENTRY *ret;
-	int i,n,set_prev,set_next;
-	STACK_OF(X509_NAME_ENTRY) *sk;
+{
+    X509_NAME_ENTRY *ret;
+    int i, n, set_prev, set_next;
+    STACK_OF(X509_NAME_ENTRY) *sk;
 
-	if (name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
-		return(NULL);
-	sk=name->entries;
-	ret=sk_X509_NAME_ENTRY_delete(sk,loc);
-	n=sk_X509_NAME_ENTRY_num(sk);
-	name->modified=1;
-	if (loc == n) return(ret);
+    if (name == NULL || loc < 0
+        || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc)
+        return (NULL);
+    sk = name->entries;
+    ret = sk_X509_NAME_ENTRY_delete(sk, loc);
+    n = sk_X509_NAME_ENTRY_num(sk);
+    name->modified = 1;
+    if (loc == n)
+        return (ret);
 
-	/* else we need to fixup the set field */
-	if (loc != 0)
-		set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
-	else
-		set_prev=ret->set-1;
-	set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
+    /* else we need to fixup the set field */
+    if (loc != 0)
+        set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
+    else
+        set_prev = ret->set - 1;
+    set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
 
-	/* set_prev is the previous set
-	 * set is the current set
-	 * set_next is the following
-	 * prev  1 1	1 1	1 1	1 1
-	 * set   1	1	2	2
-	 * next  1 1	2 2	2 2	3 2
-	 * so basically only if prev and next differ by 2, then
-	 * re-number down by 1 */
-	if (set_prev+1 < set_next)
-		for (i=loc; i<n; i++)
-			sk_X509_NAME_ENTRY_value(sk,i)->set--;
-	return(ret);
-	}
+    /*
+     * set_prev is the previous set set is the current set set_next is the
+     * following prev 1 1 1 1 1 1 1 1 set 1 1 2 2 next 1 1 2 2 2 2 3 2 so
+     * basically only if prev and next differ by 2, then re-number down by 1
+     */
+    if (set_prev + 1 < set_next)
+        for (i = loc; i < n; i++)
+            sk_X509_NAME_ENTRY_value(sk, i)->set--;
+    return (ret);
+}
 
 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
-			unsigned char *bytes, int len, int loc, int set)
+                               unsigned char *bytes, int len, int loc,
+                               int set)
 {
-	X509_NAME_ENTRY *ne;
-	int ret;
-	ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
-	if(!ne) return 0;
-	ret = X509_NAME_add_entry(name, ne, loc, set);
-	X509_NAME_ENTRY_free(ne);
-	return ret;
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
 }
 
 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
-			unsigned char *bytes, int len, int loc, int set)
+                               unsigned char *bytes, int len, int loc,
+                               int set)
 {
-	X509_NAME_ENTRY *ne;
-	int ret;
-	ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
-	if(!ne) return 0;
-	ret = X509_NAME_add_entry(name, ne, loc, set);
-	X509_NAME_ENTRY_free(ne);
-	return ret;
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
 }
 
 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
-			const unsigned char *bytes, int len, int loc, int set)
+                               const unsigned char *bytes, int len, int loc,
+                               int set)
 {
-	X509_NAME_ENTRY *ne;
-	int ret;
-	ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
-	if(!ne) return 0;
-	ret = X509_NAME_add_entry(name, ne, loc, set);
-	X509_NAME_ENTRY_free(ne);
-	return ret;
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
 }
 
-/* if set is -1, append to previous set, 0 'a new one', and 1,
- * prepend to the guy we are about to stomp on. */
+/*
+ * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
+ * guy we are about to stomp on.
+ */
 int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
-	     int set)
-	{
-	X509_NAME_ENTRY *new_name=NULL;
-	int n,i,inc;
-	STACK_OF(X509_NAME_ENTRY) *sk;
+                        int set)
+{
+    X509_NAME_ENTRY *new_name = NULL;
+    int n, i, inc;
+    STACK_OF(X509_NAME_ENTRY) *sk;
 
-	if (name == NULL) return(0);
-	sk=name->entries;
-	n=sk_X509_NAME_ENTRY_num(sk);
-	if (loc > n) loc=n;
-	else if (loc < 0) loc=n;
+    if (name == NULL)
+        return (0);
+    sk = name->entries;
+    n = sk_X509_NAME_ENTRY_num(sk);
+    if (loc > n)
+        loc = n;
+    else if (loc < 0)
+        loc = n;
 
-	name->modified=1;
+    name->modified = 1;
 
-	if (set == -1)
-		{
-		if (loc == 0)
-			{
-			set=0;
-			inc=1;
-			}
-		else
-			{
-			set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
-			inc=0;
-			}
-		}
-	else /* if (set >= 0) */
-		{
-		if (loc >= n)
-			{
-			if (loc != 0)
-				set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
-			else
-				set=0;
-			}
-		else
-			set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
-		inc=(set == 0)?1:0;
-		}
+    if (set == -1) {
+        if (loc == 0) {
+            set = 0;
+            inc = 1;
+        } else {
+            set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
+            inc = 0;
+        }
+    } else {                    /* if (set >= 0) */
 
-	if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
-		goto err;
-	new_name->set=set;
-	if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	if (inc)
-		{
-		n=sk_X509_NAME_ENTRY_num(sk);
-		for (i=loc+1; i<n; i++)
-			sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
-		}	
-	return(1);
-err:
-	if (new_name != NULL)
-		X509_NAME_ENTRY_free(new_name);
-	return(0);
-	}
+        if (loc >= n) {
+            if (loc != 0)
+                set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
+            else
+                set = 0;
+        } else
+            set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+        inc = (set == 0) ? 1 : 0;
+    }
+
+    if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL)
+        goto err;
+    new_name->set = set;
+    if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (inc) {
+        n = sk_X509_NAME_ENTRY_num(sk);
+        for (i = loc + 1; i < n; i++)
+            sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
+    }
+    return (1);
+ err:
+    if (new_name != NULL)
+        X509_NAME_ENTRY_free(new_name);
+    return (0);
+}
 
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
-		const char *field, int type, const unsigned char *bytes, int len)
-	{
-	ASN1_OBJECT *obj;
-	X509_NAME_ENTRY *nentry;
+                                               const char *field, int type,
+                                               const unsigned char *bytes,
+                                               int len)
+{
+    ASN1_OBJECT *obj;
+    X509_NAME_ENTRY *nentry;
 
-	obj=OBJ_txt2obj(field, 0);
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
-		ERR_add_error_data(2, "name=", field);
-		return(NULL);
-		}
-	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
-	ASN1_OBJECT_free(obj);
-	return nentry;
-	}
+    obj = OBJ_txt2obj(field, 0);
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
+        ERR_add_error_data(2, "name=", field);
+        return (NULL);
+    }
+    nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+    ASN1_OBJECT_free(obj);
+    return nentry;
+}
 
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
-	     int type, unsigned char *bytes, int len)
-	{
-	const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
-	if (obj == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
-		return NULL;
-		}
-	return X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
-	}
+                                               int type, unsigned char *bytes,
+                                               int len)
+{
+    const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+        return NULL;
+    }
+    return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+}
 
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
-	     const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
-	{
-	X509_NAME_ENTRY *ret;
+                                               const ASN1_OBJECT *obj,
+                                               int type,
+                                               const unsigned char *bytes,
+                                               int len)
+{
+    X509_NAME_ENTRY *ret;
 
-	if ((ne == NULL) || (*ne == NULL))
-		{
-		if ((ret=X509_NAME_ENTRY_new()) == NULL)
-			return(NULL);
-		}
-	else
-		ret= *ne;
+    if ((ne == NULL) || (*ne == NULL)) {
+        if ((ret = X509_NAME_ENTRY_new()) == NULL)
+            return (NULL);
+    } else
+        ret = *ne;
 
-	if (!X509_NAME_ENTRY_set_object(ret,obj))
-		goto err;
-	if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
-		goto err;
+    if (!X509_NAME_ENTRY_set_object(ret, obj))
+        goto err;
+    if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
+        goto err;
 
-	if ((ne != NULL) && (*ne == NULL)) *ne=ret;
-	return(ret);
-err:
-	if ((ne == NULL) || (ret != *ne))
-		X509_NAME_ENTRY_free(ret);
-	return(NULL);
-	}
+    if ((ne != NULL) && (*ne == NULL))
+        *ne = ret;
+    return (ret);
+ err:
+    if ((ne == NULL) || (ret != *ne))
+        X509_NAME_ENTRY_free(ret);
+    return (NULL);
+}
 
 int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
-	{
-	if ((ne == NULL) || (obj == NULL))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
-		return(0);
-		}
-	ASN1_OBJECT_free(ne->object);
-	ne->object=OBJ_dup(obj);
-	return((ne->object == NULL)?0:1);
-	}
+{
+    if ((ne == NULL) || (obj == NULL)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    ASN1_OBJECT_free(ne->object);
+    ne->object = OBJ_dup(obj);
+    return ((ne->object == NULL) ? 0 : 1);
+}
 
 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
-	     const unsigned char *bytes, int len)
-	{
-	int i;
+                             const unsigned char *bytes, int len)
+{
+    int i;
 
-	if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
-	if((type > 0) && (type & MBSTRING_FLAG)) 
-		return ASN1_STRING_set_by_NID(&ne->value, bytes,
-						len, type,
-					OBJ_obj2nid(ne->object)) ? 1 : 0;
-	if (len < 0) len=strlen((const char *)bytes);
-	i=ASN1_STRING_set(ne->value,bytes,len);
-	if (!i) return(0);
-	if (type != V_ASN1_UNDEF)
-		{
-		if (type == V_ASN1_APP_CHOOSE)
-			ne->value->type=ASN1_PRINTABLE_type(bytes,len);
-		else
-			ne->value->type=type;
-		}
-	return(1);
-	}
+    if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
+        return (0);
+    if ((type > 0) && (type & MBSTRING_FLAG))
+        return ASN1_STRING_set_by_NID(&ne->value, bytes,
+                                      len, type,
+                                      OBJ_obj2nid(ne->object)) ? 1 : 0;
+    if (len < 0)
+        len = strlen((const char *)bytes);
+    i = ASN1_STRING_set(ne->value, bytes, len);
+    if (!i)
+        return (0);
+    if (type != V_ASN1_UNDEF) {
+        if (type == V_ASN1_APP_CHOOSE)
+            ne->value->type = ASN1_PRINTABLE_type(bytes, len);
+        else
+            ne->value->type = type;
+    }
+    return (1);
+}
 
 ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
-	{
-	if (ne == NULL) return(NULL);
-	return(ne->object);
-	}
+{
+    if (ne == NULL)
+        return (NULL);
+    return (ne->object);
+}
 
 ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
-	{
-	if (ne == NULL) return(NULL);
-	return(ne->value);
-	}
-
+{
+    if (ne == NULL)
+        return (NULL);
+    return (ne->value);
+}
diff --git a/src/crypto/x509/x509rset.c b/src/crypto/x509/x509rset.c
index dbab555..c4e6683 100644
--- a/src/crypto/x509/x509rset.c
+++ b/src/crypto/x509/x509rset.c
@@ -59,22 +59,23 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 int X509_REQ_set_version(X509_REQ *x, long version)
-	{
-	if (x == NULL) return(0);
-	return(ASN1_INTEGER_set(x->req_info->version,version));
-	}
+{
+    if (x == NULL)
+        return (0);
+    return (ASN1_INTEGER_set(x->req_info->version, version));
+}
 
 int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
-	{
-	if ((x == NULL) || (x->req_info == NULL)) return(0);
-	return(X509_NAME_set(&x->req_info->subject,name));
-	}
+{
+    if ((x == NULL) || (x->req_info == NULL))
+        return (0);
+    return (X509_NAME_set(&x->req_info->subject, name));
+}
 
 int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
-	{
-	if ((x == NULL) || (x->req_info == NULL)) return(0);
-	return(X509_PUBKEY_set(&x->req_info->pubkey,pkey));
-	}
-
+{
+    if ((x == NULL) || (x->req_info == NULL))
+        return (0);
+    return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
+}
diff --git a/src/crypto/x509/x509spki.c b/src/crypto/x509/x509spki.c
index ccf93e0..4a9b95e 100644
--- a/src/crypto/x509/x509spki.c
+++ b/src/crypto/x509/x509spki.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -59,77 +61,77 @@
 #include <openssl/mem.h>
 #include <openssl/x509.h>
 
-
 int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
 {
-	if ((x == NULL) || (x->spkac == NULL)) return(0);
-	return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey));
+    if ((x == NULL) || (x->spkac == NULL))
+        return (0);
+    return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
 }
 
 EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
 {
-	if ((x == NULL) || (x->spkac == NULL))
-		return(NULL);
-	return(X509_PUBKEY_get(x->spkac->pubkey));
+    if ((x == NULL) || (x->spkac == NULL))
+        return (NULL);
+    return (X509_PUBKEY_get(x->spkac->pubkey));
 }
 
 /* Load a Netscape SPKI from a base64 encoded string */
 
-NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
 {
-	unsigned char *spki_der;
-	const unsigned char *p;
-	size_t spki_len;
-	NETSCAPE_SPKI *spki;
-	if (len <= 0)
-		len = strlen(str);
-	if (!EVP_DecodedLength(&spki_len, len)) {
-		OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
-		return NULL;
-	}
-	if (!(spki_der = OPENSSL_malloc(spki_len))) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	if (!EVP_DecodeBase64(spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) {
-		OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
-		OPENSSL_free(spki_der);
-		return NULL;
-	}
-	p = spki_der;
-	spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
-	OPENSSL_free(spki_der);
-	return spki;
+    unsigned char *spki_der;
+    const unsigned char *p;
+    size_t spki_len;
+    NETSCAPE_SPKI *spki;
+    if (len <= 0)
+        len = strlen(str);
+    if (!EVP_DecodedLength(&spki_len, len)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
+        return NULL;
+    }
+    if (!(spki_der = OPENSSL_malloc(spki_len))) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!EVP_DecodeBase64
+        (spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) {
+        OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
+        OPENSSL_free(spki_der);
+        return NULL;
+    }
+    p = spki_der;
+    spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+    OPENSSL_free(spki_der);
+    return spki;
 }
 
 /* Generate a base64 encoded string from an SPKI */
 
-char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
 {
-	unsigned char *der_spki, *p;
-	char *b64_str;
-	size_t b64_len;
-	int der_len;
-	der_len = i2d_NETSCAPE_SPKI(spki, NULL);
-	if (!EVP_EncodedLength(&b64_len, der_len))
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
-		return NULL;
-		}
-	der_spki = OPENSSL_malloc(der_len);
-	if (der_spki == NULL) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	b64_str = OPENSSL_malloc(b64_len);
-	if (b64_str == NULL) {
-		OPENSSL_free(der_spki);
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	p = der_spki;
-	i2d_NETSCAPE_SPKI(spki, &p);
-	EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
-	OPENSSL_free(der_spki);
-	return b64_str;
+    unsigned char *der_spki, *p;
+    char *b64_str;
+    size_t b64_len;
+    int der_len;
+    der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+    if (!EVP_EncodedLength(&b64_len, der_len)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
+        return NULL;
+    }
+    der_spki = OPENSSL_malloc(der_len);
+    if (der_spki == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    b64_str = OPENSSL_malloc(b64_len);
+    if (b64_str == NULL) {
+        OPENSSL_free(der_spki);
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    p = der_spki;
+    i2d_NETSCAPE_SPKI(spki, &p);
+    EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
+    OPENSSL_free(der_spki);
+    return b64_str;
 }
diff --git a/src/crypto/x509/x509type.c b/src/crypto/x509/x509type.c
index e7c7935..d4f5a4d 100644
--- a/src/crypto/x509/x509type.c
+++ b/src/crypto/x509/x509type.c
@@ -58,71 +58,69 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
 int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
-	{
-	EVP_PKEY *pk;
-	int ret=0,i;
+{
+    EVP_PKEY *pk;
+    int ret = 0, i;
 
-	if (x == NULL) return(0);
+    if (x == NULL)
+        return (0);
 
-	if (pkey == NULL)
-		pk=X509_get_pubkey(x);
-	else
-		pk=pkey;
+    if (pkey == NULL)
+        pk = X509_get_pubkey(x);
+    else
+        pk = pkey;
 
-	if (pk == NULL) return(0);
+    if (pk == NULL)
+        return (0);
 
-	switch (pk->type)
-		{
-	case EVP_PKEY_RSA:
-		ret=EVP_PK_RSA|EVP_PKT_SIGN;
-/*		if (!sign only extension) */
-			ret|=EVP_PKT_ENC;
-	break;
-	case EVP_PKEY_DSA:
-		ret=EVP_PK_DSA|EVP_PKT_SIGN;
-		break;
-	case EVP_PKEY_EC:
-		ret=EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH;
-		break;
-	case EVP_PKEY_DH:
-		ret=EVP_PK_DH|EVP_PKT_EXCH;
-		break;	
-	case NID_id_GostR3410_94:
-	case NID_id_GostR3410_2001:
-		ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
-		break;
-	default:
-		break;
-		}
+    switch (pk->type) {
+    case EVP_PKEY_RSA:
+        ret = EVP_PK_RSA | EVP_PKT_SIGN;
+/*              if (!sign only extension) */
+        ret |= EVP_PKT_ENC;
+        break;
+    case EVP_PKEY_DSA:
+        ret = EVP_PK_DSA | EVP_PKT_SIGN;
+        break;
+    case EVP_PKEY_EC:
+        ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
+        break;
+    case EVP_PKEY_DH:
+        ret = EVP_PK_DH | EVP_PKT_EXCH;
+        break;
+    case NID_id_GostR3410_94:
+    case NID_id_GostR3410_2001:
+        ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
+        break;
+    default:
+        break;
+    }
 
-	i=OBJ_obj2nid(x->sig_alg->algorithm);
-	if (i && OBJ_find_sigid_algs(i, NULL, &i))
-		{
+    i = OBJ_obj2nid(x->sig_alg->algorithm);
+    if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
 
-		switch (i)
-			{
-		case NID_rsaEncryption:
-		case NID_rsa:
-			ret|=EVP_PKS_RSA;
-			break;
-		case NID_dsa:
-		case NID_dsa_2:
-			ret|=EVP_PKS_DSA;
-			break;
-		case NID_X9_62_id_ecPublicKey:
-			ret|=EVP_PKS_EC;
-			break;
-		default:
-			break;
-			}
-		}
+        switch (i) {
+        case NID_rsaEncryption:
+        case NID_rsa:
+            ret |= EVP_PKS_RSA;
+            break;
+        case NID_dsa:
+        case NID_dsa_2:
+            ret |= EVP_PKS_DSA;
+            break;
+        case NID_X9_62_id_ecPublicKey:
+            ret |= EVP_PKS_EC;
+            break;
+        default:
+            break;
+        }
+    }
 
-	if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
-					   for, not bytes */
-		ret|=EVP_PKT_EXP;
-	if(pkey==NULL) EVP_PKEY_free(pk);
-	return(ret);
-	}
-
+    if (EVP_PKEY_size(pk) <= 1024 / 8) /* /8 because it's 1024 bits we look
+                                        * for, not bytes */
+        ret |= EVP_PKT_EXP;
+    if (pkey == NULL)
+        EVP_PKEY_free(pk);
+    return (ret);
+}
diff --git a/src/crypto/x509/x_algor.c b/src/crypto/x509/x_algor.c
index ae694e3..abacd06 100644
--- a/src/crypto/x509/x_algor.c
+++ b/src/crypto/x509/x_algor.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2000. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
 /* ====================================================================
  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -61,12 +63,12 @@
 
 
 ASN1_SEQUENCE(X509_ALGOR) = {
-	ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
-	ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+        ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+        ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
 } ASN1_SEQUENCE_END(X509_ALGOR)
 
-ASN1_ITEM_TEMPLATE(X509_ALGORS) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
 ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
@@ -75,80 +77,75 @@
 
 IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
 
-int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval)
-	{
-	if (!alg)
-		return 0;
-	if (ptype != V_ASN1_UNDEF)
-		{
-		if (alg->parameter == NULL)
-			alg->parameter = ASN1_TYPE_new();
-		if (alg->parameter == NULL)
-			return 0;
-		}
-	if (alg)
-		{
-		if (alg->algorithm)
-			ASN1_OBJECT_free(alg->algorithm);
-		alg->algorithm = (ASN1_OBJECT*) aobj;
-		}
-	if (ptype == 0)
-		return 1;	
-	if (ptype == V_ASN1_UNDEF)
-		{
-		if (alg->parameter)
-			{
-			ASN1_TYPE_free(alg->parameter);
-			alg->parameter = NULL;
-			}
-		}
-	else
-		ASN1_TYPE_set(alg->parameter, ptype, pval);
-	return 1;
-	}
+int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype,
+                    void *pval)
+{
+    if (!alg)
+        return 0;
+    if (ptype != V_ASN1_UNDEF) {
+        if (alg->parameter == NULL)
+            alg->parameter = ASN1_TYPE_new();
+        if (alg->parameter == NULL)
+            return 0;
+    }
+    if (alg) {
+        if (alg->algorithm)
+            ASN1_OBJECT_free(alg->algorithm);
+        alg->algorithm = (ASN1_OBJECT *)aobj;
+    }
+    if (ptype == 0)
+        return 1;
+    if (ptype == V_ASN1_UNDEF) {
+        if (alg->parameter) {
+            ASN1_TYPE_free(alg->parameter);
+            alg->parameter = NULL;
+        }
+    } else
+        ASN1_TYPE_set(alg->parameter, ptype, pval);
+    return 1;
+}
 
 void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
-						X509_ALGOR *algor)
-	{
-	if (paobj)
-		*paobj = algor->algorithm;
-	if (pptype)
-		{
-		if (algor->parameter == NULL)
-			{
-			*pptype = V_ASN1_UNDEF;
-			return;
-			}
-		else
-			*pptype = algor->parameter->type;
-		if (ppval)
-			*ppval = algor->parameter->value.ptr;
-		}
-	}
+                     X509_ALGOR *algor)
+{
+    if (paobj)
+        *paobj = algor->algorithm;
+    if (pptype) {
+        if (algor->parameter == NULL) {
+            *pptype = V_ASN1_UNDEF;
+            return;
+        } else
+            *pptype = algor->parameter->type;
+        if (ppval)
+            *ppval = algor->parameter->value.ptr;
+    }
+}
 
 /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
 
 void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
-	{
-	int param_type;
+{
+    int param_type;
 
-	if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT)
-		param_type = V_ASN1_UNDEF;
-	else
-		param_type = V_ASN1_NULL;
+    if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT)
+        param_type = V_ASN1_UNDEF;
+    else
+        param_type = V_ASN1_NULL;
 
-	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
 
-	}
+}
 
-/* X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. */
+/*
+ * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise.
+ */
 int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
-	{
-	int rv;
-	rv = OBJ_cmp(a->algorithm, b->algorithm);
-	if (rv)
-		return rv;
-	if (!a->parameter && !b->parameter)
-		return 0;
-	return ASN1_TYPE_cmp(a->parameter, b->parameter);
-	}
+{
+    int rv;
+    rv = OBJ_cmp(a->algorithm, b->algorithm);
+    if (rv)
+        return rv;
+    if (!a->parameter && !b->parameter)
+        return 0;
+    return ASN1_TYPE_cmp(a->parameter, b->parameter);
+}
diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c
index 62b3f40..c430a7d 100644
--- a/src/crypto/x509/x_all.c
+++ b/src/crypto/x509/x_all.c
@@ -63,435 +63,439 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
-
 int X509_verify(X509 *a, EVP_PKEY *r)
-	{
-	if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
-		return 0;
-	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
-		a->signature,a->cert_info,r));
-	}
+{
+    if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+        return 0;
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg,
+                             a->signature, a->cert_info, r));
+}
 
 int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
-	{
-	return( ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
-		a->sig_alg,a->signature,a->req_info,r));
-	}
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
+                             a->sig_alg, a->signature, a->req_info, r));
+}
 
 int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
-	{
-	x->cert_info->enc.modified = 1;
-	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
-		x->sig_alg, x->signature, x->cert_info,pkey,md));
-	}
+{
+    x->cert_info->enc.modified = 1;
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
+                           x->sig_alg, x->signature, x->cert_info, pkey, md));
+}
 
 int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
-	{
-	x->cert_info->enc.modified = 1;
-	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
-		x->cert_info->signature,
-		x->sig_alg, x->signature, x->cert_info, ctx);
-	}
+{
+    x->cert_info->enc.modified = 1;
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+                              x->cert_info->signature,
+                              x->sig_alg, x->signature, x->cert_info, ctx);
+}
 
 int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
-	{
-	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
-		x->signature, x->req_info,pkey,md));
-	}
+{
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
+                           x->signature, x->req_info, pkey, md));
+}
 
 int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
-	{
-	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
-		x->sig_alg, NULL, x->signature, x->req_info, ctx);
-	}
+{
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+                              x->sig_alg, NULL, x->signature, x->req_info,
+                              ctx);
+}
 
 int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
-	{
-	x->crl->enc.modified = 1;
-	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg,
-		x->sig_alg, x->signature, x->crl,pkey,md));
-	}
+{
+    x->crl->enc.modified = 1;
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
+                           x->sig_alg, x->signature, x->crl, pkey, md));
+}
 
 int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
-	{
-	x->crl->enc.modified = 1;
-	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
-		x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
-	}
+{
+    x->crl->enc.modified = 1;
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+                              x->crl->sig_alg, x->sig_alg, x->signature,
+                              x->crl, ctx);
+}
 
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
-	{
-	return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,
-		x->signature, x->spkac,pkey,md));
-	}
+{
+    return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL,
+                           x->signature, x->spkac, pkey, md));
+}
 
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
-	{
-	return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,
-		x->signature, x->spkac, pkey));
-	}
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,
+                             x->signature, x->spkac, pkey));
+}
 
 #ifndef OPENSSL_NO_FP_API
 X509 *d2i_X509_fp(FILE *fp, X509 **x509)
-	{
-	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
-	}
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
 
 int i2d_X509_fp(FILE *fp, X509 *x509)
-	{
-	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
-	}
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
 #endif
 
 X509 *d2i_X509_bio(BIO *bp, X509 **x509)
-	{
-	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
-	}
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
 
 int i2d_X509_bio(BIO *bp, X509 *x509)
-	{
-	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
-	}
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
 
 #ifndef OPENSSL_NO_FP_API
 X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
-	{
-	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
-	}
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
 
 int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
-	{
-	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
-	}
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
 #endif
 
 X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
-	{
-	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
-	}
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
 
 int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
-	{
-	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
-	}
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
 
 #ifndef OPENSSL_NO_FP_API
 X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
-	{
-	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
-	}
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
 
 int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
-	{
-	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
-	}
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
 #endif
 
 X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
-	{
-	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
-	}
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
 
 int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
-	{
-	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
-	}
-
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
 
 #ifndef OPENSSL_NO_FP_API
 RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
-	{
-	return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
-	}
+{
+    return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
+}
 
 int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
-	{
-	return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
-	}
+{
+    return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
+}
 
 RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
-	{
-	return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
-	}
+{
+    return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
+}
 
 RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
-	{
-	return ASN1_d2i_fp((void *(*)(void))
-			   RSA_new,(D2I_OF(void))d2i_RSA_PUBKEY, fp,
-			   (void **)rsa);
-	}
+{
+    return ASN1_d2i_fp((void *(*)(void))
+                       RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
+                       (void **)rsa);
+}
 
 int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
-	{
-	return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
-	}
+{
+    return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
+}
 
 int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
-	{
-	return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY,fp,rsa);
-	}
+{
+    return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, rsa);
+}
 #endif
 
 RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
-	{
-	return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
-	}
+{
+    return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
+}
 
 int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
-	{
-	return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
+}
 
 RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
-	{
-	return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
-	}
-
+{
+    return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
+}
 
 RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
-	{
-	return ASN1_d2i_bio_of(RSA,RSA_new,d2i_RSA_PUBKEY,bp,rsa);
-	}
+{
+    return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
+}
 
 int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
-	{
-	return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
+}
 
 int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
-	{
-	return ASN1_i2d_bio_of_const(RSA,i2d_RSA_PUBKEY,bp,rsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(RSA, i2d_RSA_PUBKEY, bp, rsa);
+}
 
 #ifndef OPENSSL_NO_DSA
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
-	{
-	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSAPrivateKey,fp,dsa);
-	}
+{
+    return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
+}
 
 int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
-	{
-	return ASN1_i2d_fp_of_const(DSA,i2d_DSAPrivateKey,fp,dsa);
-	}
+{
+    return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
+}
 
 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
-	{
-	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSA_PUBKEY,fp,dsa);
-	}
+{
+    return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
+}
 
 int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
-	{
-	return ASN1_i2d_fp_of_const(DSA,i2d_DSA_PUBKEY,fp,dsa);
-	}
-#endif
+{
+    return ASN1_i2d_fp_of_const(DSA, i2d_DSA_PUBKEY, fp, dsa);
+}
+# endif
 
 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
-	{
-	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAPrivateKey,bp,dsa
-);
-	}
+{
+    return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
+}
 
 int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
-	{
-	return ASN1_i2d_bio_of_const(DSA,i2d_DSAPrivateKey,bp,dsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
+}
 
 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
-	{
-	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSA_PUBKEY,bp,dsa);
-	}
+{
+    return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
+}
 
 int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
-	{
-	return ASN1_i2d_bio_of_const(DSA,i2d_DSA_PUBKEY,bp,dsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(DSA, i2d_DSA_PUBKEY, bp, dsa);
+}
 
 #endif
 
 #ifndef OPENSSL_NO_FP_API
 EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
-	{
-	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,fp,eckey);
-	}
-  
+{
+    return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
+}
+
 int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
-	{
-	return ASN1_i2d_fp_of_const(EC_KEY,i2d_EC_PUBKEY,fp,eckey);
-	}
+{
+    return ASN1_i2d_fp_of_const(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
+}
 
 EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
-	{
-	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,fp,eckey);
-	}
-  
+{
+    return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
+}
+
 int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
-	{
-	return ASN1_i2d_fp_of_const(EC_KEY,i2d_ECPrivateKey,fp,eckey);
-	}
+{
+    return ASN1_i2d_fp_of_const(EC_KEY, i2d_ECPrivateKey, fp, eckey);
+}
 #endif
 EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
-	{
-	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,bp,eckey);
-	}
-  
+{
+    return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
+}
+
 int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
-	{
-	return ASN1_i2d_bio_of_const(EC_KEY,i2d_EC_PUBKEY,bp,ecdsa);
-	}
+{
+    return ASN1_i2d_bio_of_const(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
+}
 
 EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
-	{
-	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,bp,eckey);
-	}
-  
+{
+    return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
+}
+
 int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
-	{
-	return ASN1_i2d_bio_of_const(EC_KEY,i2d_ECPrivateKey,bp,eckey);
-	}
+{
+    return ASN1_i2d_bio_of_const(EC_KEY, i2d_ECPrivateKey, bp, eckey);
+}
 
-
-int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
-	     unsigned int *len)
-	{
-	ASN1_BIT_STRING *key;
-	key = X509_get0_pubkey_bitstr(data);
-	if(!key) return 0;
-	return EVP_Digest(key->data, key->length, md, len, type, NULL);
-	}
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+                       unsigned char *md, unsigned int *len)
+{
+    ASN1_BIT_STRING *key;
+    key = X509_get0_pubkey_bitstr(data);
+    if (!key)
+        return 0;
+    return EVP_Digest(key->data, key->length, md, len, type, NULL);
+}
 
 int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
-	     unsigned int *len)
-	{
-	return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len));
-	}
+                unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
+}
 
-int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
-	     unsigned int *len)
-	{
-	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL),type,(char *)data,md,len));
-	}
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
+}
 
-int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
-	     unsigned int *len)
-	{
-	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ),type,(char *)data,md,len));
-	}
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
+}
 
-int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
-	     unsigned int *len)
-	{
-	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len));
-	}
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+                     unsigned char *md, unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
+}
 
 #ifndef OPENSSL_NO_FP_API
 X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
-	{
-	return ASN1_d2i_fp_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,fp,p8);
-	}
+{
+    return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
+}
 
 int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
-	{
-	return ASN1_i2d_fp_of(X509_SIG,i2d_X509_SIG,fp,p8);
-	}
+{
+    return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
+}
 #endif
 
 X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
-	{
-	return ASN1_d2i_bio_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,bp,p8);
-	}
+{
+    return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
+}
 
 int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
-	{
-	return ASN1_i2d_bio_of(X509_SIG,i2d_X509_SIG,bp,p8);
-	}
+{
+    return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
+}
 
 #ifndef OPENSSL_NO_FP_API
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
-						 PKCS8_PRIV_KEY_INFO **p8inf)
-	{
-	return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
-			      d2i_PKCS8_PRIV_KEY_INFO,fp,p8inf);
-	}
+                                                PKCS8_PRIV_KEY_INFO **p8inf)
+{
+    return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+                          d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
+}
 
 int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
-	{
-	return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,fp,
-			      p8inf);
-	}
+{
+    return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
+                          p8inf);
+}
 
 int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
-	{
-	PKCS8_PRIV_KEY_INFO *p8inf;
-	int ret;
-	p8inf = EVP_PKEY2PKCS8(key);
-	if(!p8inf) return 0;
-	ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
-	PKCS8_PRIV_KEY_INFO_free(p8inf);
-	return ret;
-	}
+{
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    int ret;
+    p8inf = EVP_PKEY2PKCS8(key);
+    if (!p8inf)
+        return 0;
+    ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    return ret;
+}
 
 int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
-	{
-	return ASN1_i2d_fp_of_const(EVP_PKEY,i2d_PrivateKey,fp,pkey);
-	}
+{
+    return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PrivateKey, fp, pkey);
+}
 
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
 {
-	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,fp,a);
+    return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
 }
 
 int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
-	{
-	return ASN1_i2d_fp_of_const(EVP_PKEY,i2d_PUBKEY,fp,pkey);
-	}
+{
+    return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PUBKEY, fp, pkey);
+}
 
 EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
 {
-	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,fp,a);
+    return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
 }
 
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
-						 PKCS8_PRIV_KEY_INFO **p8inf)
-	{
-	return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
-			    d2i_PKCS8_PRIV_KEY_INFO,bp,p8inf);
-	}
+                                                 PKCS8_PRIV_KEY_INFO **p8inf)
+{
+    return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+                           d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
+}
 
 int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
-	{
-	return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,bp,
-			       p8inf);
-	}
+{
+    return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
+                           p8inf);
+}
 
 int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
-	{
-	PKCS8_PRIV_KEY_INFO *p8inf;
-	int ret;
-	p8inf = EVP_PKEY2PKCS8(key);
-	if(!p8inf) return 0;
-	ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
-	PKCS8_PRIV_KEY_INFO_free(p8inf);
-	return ret;
-	}
+{
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    int ret;
+    p8inf = EVP_PKEY2PKCS8(key);
+    if (!p8inf)
+        return 0;
+    ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    return ret;
+}
 #endif
 
 int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
-	{
-	return ASN1_i2d_bio_of_const(EVP_PKEY,i2d_PrivateKey,bp,pkey);
-	}
+{
+    return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PrivateKey, bp, pkey);
+}
 
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
-	{
-	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,bp,a);
-	}
+{
+    return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
+}
 
 int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
-	{
-	return ASN1_i2d_bio_of_const(EVP_PKEY,i2d_PUBKEY,bp,pkey);
-	}
+{
+    return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PUBKEY, bp, pkey);
+}
 
 EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
-	{
-	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,bp,a);
-	}
+{
+    return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
+}
diff --git a/src/crypto/x509/x_attrib.c b/src/crypto/x509/x_attrib.c
index c460a70..de8c95c 100644
--- a/src/crypto/x509/x_attrib.c
+++ b/src/crypto/x509/x_attrib.c
@@ -59,59 +59,53 @@
 #include <openssl/x509.h>
 #include <openssl/obj.h>
 
-
-/* X509_ATTRIBUTE: this has the following form:
- *
- * typedef struct x509_attributes_st
- *	{
- *	ASN1_OBJECT *object;
- *	int single;
- *	union	{
- *		char		*ptr;
- * 		STACK_OF(ASN1_TYPE) *set;
- * 		ASN1_TYPE	*single;
- *		} value;
- *	} X509_ATTRIBUTE;
- *
- * this needs some extra thought because the CHOICE type is
- * merged with the main structure and because the value can
- * be anything at all we *must* try the SET OF first because
- * the ASN1_ANY type will swallow anything including the whole
- * SET OF structure.
+/*
+ * X509_ATTRIBUTE: this has the following form: typedef struct
+ * x509_attributes_st { ASN1_OBJECT *object; int single; union { char *ptr;
+ * STACK_OF(ASN1_TYPE) *set; ASN1_TYPE *single; } value; } X509_ATTRIBUTE;
+ * this needs some extra thought because the CHOICE type is merged with the
+ * main structure and because the value can be anything at all we *must* try
+ * the SET OF first because the ASN1_ANY type will swallow anything including
+ * the whole SET OF structure.
  */
 
 ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
-	ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
-	ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
+        ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
+        ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
 } ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
 
 ASN1_SEQUENCE(X509_ATTRIBUTE) = {
-	ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
-	/* CHOICE type merged with parent */
-	ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
+        ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+        /* CHOICE type merged with parent */
+        ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
 } ASN1_SEQUENCE_END(X509_ATTRIBUTE)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
 
 X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
-	{
-	X509_ATTRIBUTE *ret=NULL;
-	ASN1_TYPE *val=NULL;
+{
+    X509_ATTRIBUTE *ret = NULL;
+    ASN1_TYPE *val = NULL;
 
-	if ((ret=X509_ATTRIBUTE_new()) == NULL)
-		return(NULL);
-        /* TODO(fork): const correctness. */
-	ret->object=(ASN1_OBJECT*) OBJ_nid2obj(nid);
-	ret->single=0;
-	if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
-	if ((val=ASN1_TYPE_new()) == NULL) goto err;
-	if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
+    if ((ret = X509_ATTRIBUTE_new()) == NULL)
+        return (NULL);
+    /* TODO(fork): const correctness. */
+    ret->object = (ASN1_OBJECT *)OBJ_nid2obj(nid);
+    ret->single = 0;
+    if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
+        goto err;
+    if ((val = ASN1_TYPE_new()) == NULL)
+        goto err;
+    if (!sk_ASN1_TYPE_push(ret->value.set, val))
+        goto err;
 
-	ASN1_TYPE_set(val,atrtype,value);
-	return(ret);
-err:
-	if (ret != NULL) X509_ATTRIBUTE_free(ret);
-	if (val != NULL) ASN1_TYPE_free(val);
-	return(NULL);
-	}
+    ASN1_TYPE_set(val, atrtype, value);
+    return (ret);
+ err:
+    if (ret != NULL)
+        X509_ATTRIBUTE_free(ret);
+    if (val != NULL)
+        ASN1_TYPE_free(val);
+    return (NULL);
+}
diff --git a/src/crypto/x509/x_crl.c b/src/crypto/x509/x_crl.c
index d516872..cd64890 100644
--- a/src/crypto/x509/x_crl.c
+++ b/src/crypto/x509/x_crl.c
@@ -67,494 +67,473 @@
 
 #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.
- * This method allows general CRL operations to be redirected to more
- * efficient callbacks: for example a CRL entry database.
+/*
+ * 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. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
  */
 
-#define X509_CRL_METHOD_DYNAMIC		1
+#define X509_CRL_METHOD_DYNAMIC         1
 
-struct x509_crl_method_st
-	{
-	int flags;
-	int (*crl_init)(X509_CRL *crl);
-	int (*crl_free)(X509_CRL *crl);
-	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
-				ASN1_INTEGER *ser, X509_NAME *issuer);
-	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
-	};
+struct x509_crl_method_st {
+    int flags;
+    int (*crl_init) (X509_CRL *crl);
+    int (*crl_free) (X509_CRL *crl);
+    int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+                       ASN1_INTEGER *ser, X509_NAME *issuer);
+    int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
 
-static int X509_REVOKED_cmp(const X509_REVOKED **a,
-				const X509_REVOKED **b);
+static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b);
 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
 
 ASN1_SEQUENCE(X509_REVOKED) = {
-	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
-	ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
-	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
+        ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+        ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
 } ASN1_SEQUENCE_END(X509_REVOKED)
 
 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
 static int def_crl_lookup(X509_CRL *crl,
-		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
+                          X509_REVOKED **ret, ASN1_INTEGER *serial,
+                          X509_NAME *issuer);
 
-static const X509_CRL_METHOD int_crl_meth =
-	{
-	0,
-	0,0,
-	def_crl_lookup,
-	def_crl_verify
-	};
+static const X509_CRL_METHOD int_crl_meth = {
+    0,
+    0, 0,
+    def_crl_lookup,
+    def_crl_verify
+};
 
 static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
 
-/* The X509_CRL_INFO structure needs a bit of customisation.
- * Since we cache the original encoding the signature wont be affected by
- * reordering of the revoked field.
+/*
+ * The X509_CRL_INFO structure needs a bit of customisation. Since we cache
+ * the original encoding the signature wont be affected by reordering of the
+ * revoked field.
  */
 static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-								void *exarg)
+                      void *exarg)
 {
-	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+    X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
 
-	if(!a || !a->revoked) return 1;
-	switch(operation) {
-		/* Just set cmp function here. We don't sort because that
-		 * would affect the output of X509_CRL_print().
-		 */
-		case ASN1_OP_D2I_POST:
-		(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
-		break;
-	}
-	return 1;
+    if (!a || !a->revoked)
+        return 1;
+    switch (operation) {
+        /*
+         * Just set cmp function here. We don't sort because that would
+         * affect the output of X509_CRL_print().
+         */
+    case ASN1_OP_D2I_POST:
+        (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+        break;
+    }
+    return 1;
 }
 
 
 ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
-	ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
-	ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
-	ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
-	ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
-	ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
-	ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
-	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+        ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
+        ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+        ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+        ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+        ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+        ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
 
-/* Set CRL entry issuer according to CRL certificate issuer extension.
- * Check for unhandled critical CRL entry extensions.
+/*
+ * Set CRL entry issuer according to CRL certificate issuer extension. Check
+ * for unhandled critical CRL entry extensions.
  */
 
 static int crl_set_issuers(X509_CRL *crl)
-	{
+{
 
-	size_t i, k;
-	int j;
-	GENERAL_NAMES *gens, *gtmp;
-	STACK_OF(X509_REVOKED) *revoked;
+    size_t i, k;
+    int j;
+    GENERAL_NAMES *gens, *gtmp;
+    STACK_OF(X509_REVOKED) *revoked;
 
-	revoked = X509_CRL_get_REVOKED(crl);
+    revoked = X509_CRL_get_REVOKED(crl);
 
-	gens = NULL;
-	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
-		{
-		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
-		STACK_OF(X509_EXTENSION) *exts;
-		ASN1_ENUMERATED *reason;
-		X509_EXTENSION *ext;
-		gtmp = X509_REVOKED_get_ext_d2i(rev, 
-						NID_certificate_issuer,
-						&j, NULL);
-		if (!gtmp && (j != -1))
-			{
-			crl->flags |= EXFLAG_INVALID;
-			return 1;
-			}
+    gens = NULL;
+    for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+        X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+        STACK_OF(X509_EXTENSION) *exts;
+        ASN1_ENUMERATED *reason;
+        X509_EXTENSION *ext;
+        gtmp = X509_REVOKED_get_ext_d2i(rev,
+                                        NID_certificate_issuer, &j, NULL);
+        if (!gtmp && (j != -1)) {
+            crl->flags |= EXFLAG_INVALID;
+            return 1;
+        }
 
-		if (gtmp)
-			{
-			gens = gtmp;
-			if (!crl->issuers)
-				{
-				crl->issuers = sk_GENERAL_NAMES_new_null();
-				if (!crl->issuers)
-					return 0;
-				}
-			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
-				return 0;
-			}
-		rev->issuer = gens;
+        if (gtmp) {
+            gens = gtmp;
+            if (!crl->issuers) {
+                crl->issuers = sk_GENERAL_NAMES_new_null();
+                if (!crl->issuers)
+                    return 0;
+            }
+            if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+                return 0;
+        }
+        rev->issuer = gens;
 
-		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
-								&j, NULL);
-		if (!reason && (j != -1))
-			{
-			crl->flags |= EXFLAG_INVALID;
-			return 1;
-			}
+        reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
+        if (!reason && (j != -1)) {
+            crl->flags |= EXFLAG_INVALID;
+            return 1;
+        }
 
-		if (reason)
-			{
-			rev->reason = ASN1_ENUMERATED_get(reason);
-			ASN1_ENUMERATED_free(reason);
-			}
-		else
-			rev->reason = CRL_REASON_NONE;	
+        if (reason) {
+            rev->reason = ASN1_ENUMERATED_get(reason);
+            ASN1_ENUMERATED_free(reason);
+        } else
+            rev->reason = CRL_REASON_NONE;
 
-		/* Check for critical CRL entry extensions */
+        /* Check for critical CRL entry extensions */
 
-		exts = rev->extensions;
+        exts = rev->extensions;
 
-		for (k = 0; k < sk_X509_EXTENSION_num(exts); k++)
-			{
-			ext = sk_X509_EXTENSION_value(exts, k);
-			if (ext->critical > 0)
-				{
-				if (OBJ_obj2nid(ext->object) ==
-					NID_certificate_issuer)
-					continue;
-				crl->flags |= EXFLAG_CRITICAL;
-				break;
-				}
-			}
+        for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) {
+            ext = sk_X509_EXTENSION_value(exts, k);
+            if (ext->critical > 0) {
+                if (OBJ_obj2nid(ext->object) == NID_certificate_issuer)
+                    continue;
+                crl->flags |= EXFLAG_CRITICAL;
+                break;
+            }
+        }
 
+    }
 
-		}
+    return 1;
 
-	return 1;
+}
 
-	}
-
-/* The X509_CRL structure needs a bit of customisation. Cache some extensions
+/*
+ * The X509_CRL structure needs a bit of customisation. Cache some extensions
  * and hash of the whole CRL.
  */
 static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-								void *exarg)
-	{
-	X509_CRL *crl = (X509_CRL *)*pval;
-	STACK_OF(X509_EXTENSION) *exts;
-	X509_EXTENSION *ext;
-	size_t idx;
+                  void *exarg)
+{
+    X509_CRL *crl = (X509_CRL *)*pval;
+    STACK_OF(X509_EXTENSION) *exts;
+    X509_EXTENSION *ext;
+    size_t idx;
 
-	switch(operation)
-		{
-		case ASN1_OP_NEW_POST:
-		crl->idp = NULL;
-		crl->akid = NULL;
-		crl->flags = 0;
-		crl->idp_flags = 0;
-		crl->idp_reasons = CRLDP_ALL_REASONS;
-		crl->meth = default_crl_method;
-		crl->meth_data = NULL;
-		crl->issuers = NULL;
-		crl->crl_number = NULL;
-		crl->base_crl_number = NULL;
-		break;
+    switch (operation) {
+    case ASN1_OP_NEW_POST:
+        crl->idp = NULL;
+        crl->akid = NULL;
+        crl->flags = 0;
+        crl->idp_flags = 0;
+        crl->idp_reasons = CRLDP_ALL_REASONS;
+        crl->meth = default_crl_method;
+        crl->meth_data = NULL;
+        crl->issuers = NULL;
+        crl->crl_number = NULL;
+        crl->base_crl_number = NULL;
+        break;
 
-		case ASN1_OP_D2I_POST:
-		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
-		crl->idp = X509_CRL_get_ext_d2i(crl,
-				NID_issuing_distribution_point, NULL, NULL);
-		if (crl->idp)
-			setup_idp(crl, crl->idp);
+    case ASN1_OP_D2I_POST:
+        X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+        crl->idp = X509_CRL_get_ext_d2i(crl,
+                                        NID_issuing_distribution_point, NULL,
+                                        NULL);
+        if (crl->idp)
+            setup_idp(crl, crl->idp);
 
-		crl->akid = X509_CRL_get_ext_d2i(crl,
-				NID_authority_key_identifier, NULL, NULL);	
+        crl->akid = X509_CRL_get_ext_d2i(crl,
+                                         NID_authority_key_identifier, NULL,
+                                         NULL);
 
-		crl->crl_number = X509_CRL_get_ext_d2i(crl,
-				NID_crl_number, NULL, NULL);	
+        crl->crl_number = X509_CRL_get_ext_d2i(crl,
+                                               NID_crl_number, NULL, NULL);
 
-		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
-				NID_delta_crl, NULL, NULL);	
-		/* Delta CRLs must have CRL number */
-		if (crl->base_crl_number && !crl->crl_number)
-			crl->flags |= EXFLAG_INVALID;
+        crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+                                                    NID_delta_crl, NULL,
+                                                    NULL);
+        /* Delta CRLs must have CRL number */
+        if (crl->base_crl_number && !crl->crl_number)
+            crl->flags |= EXFLAG_INVALID;
 
-		/* See if we have any unhandled critical CRL extensions and 
-		 * indicate this in a flag. We only currently handle IDP so
-		 * anything else critical sets the flag.
-		 *
-		 * This code accesses the X509_CRL structure directly:
-		 * applications shouldn't do this.
-		 */
+        /*
+         * See if we have any unhandled critical CRL extensions and indicate
+         * this in a flag. We only currently handle IDP so anything else
+         * critical sets the flag. This code accesses the X509_CRL structure
+         * directly: applications shouldn't do this.
+         */
 
-		exts = crl->crl->extensions;
+        exts = crl->crl->extensions;
 
-		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
-			{
-			int nid;
-			ext = sk_X509_EXTENSION_value(exts, idx);
-			nid = OBJ_obj2nid(ext->object);
-			if (nid == NID_freshest_crl)
-				crl->flags |= EXFLAG_FRESHEST;
-			if (ext->critical > 0)
-				{
-				/* We handle IDP and deltas */
-				if ((nid == NID_issuing_distribution_point)
-					|| (nid == NID_authority_key_identifier)
-					|| (nid == NID_delta_crl))
-					break;;
-				crl->flags |= EXFLAG_CRITICAL;
-				break;
-				}
-			}
+        for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+            int nid;
+            ext = sk_X509_EXTENSION_value(exts, idx);
+            nid = OBJ_obj2nid(ext->object);
+            if (nid == NID_freshest_crl)
+                crl->flags |= EXFLAG_FRESHEST;
+            if (ext->critical > 0) {
+                /* We handle IDP and deltas */
+                if ((nid == NID_issuing_distribution_point)
+                    || (nid == NID_authority_key_identifier)
+                    || (nid == NID_delta_crl))
+                    break;;
+                crl->flags |= EXFLAG_CRITICAL;
+                break;
+            }
+        }
 
+        if (!crl_set_issuers(crl))
+            return 0;
 
-		if (!crl_set_issuers(crl))
-			return 0;
+        if (crl->meth->crl_init) {
+            if (crl->meth->crl_init(crl) == 0)
+                return 0;
+        }
+        break;
 
-		if (crl->meth->crl_init)
-			{
-			if (crl->meth->crl_init(crl) == 0)
-				return 0;
-			}
-		break;
-
-		case ASN1_OP_FREE_POST:
-		if (crl->meth->crl_free)
-			{
-			if (!crl->meth->crl_free(crl))
-				return 0;
-			}
-		if (crl->akid)
-			AUTHORITY_KEYID_free(crl->akid);
-		if (crl->idp)
-			ISSUING_DIST_POINT_free(crl->idp);
-		ASN1_INTEGER_free(crl->crl_number);
-		ASN1_INTEGER_free(crl->base_crl_number);
-		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
-		break;
-		}
-	return 1;
-	}
+    case ASN1_OP_FREE_POST:
+        if (crl->meth->crl_free) {
+            if (!crl->meth->crl_free(crl))
+                return 0;
+        }
+        if (crl->akid)
+            AUTHORITY_KEYID_free(crl->akid);
+        if (crl->idp)
+            ISSUING_DIST_POINT_free(crl->idp);
+        ASN1_INTEGER_free(crl->crl_number);
+        ASN1_INTEGER_free(crl->base_crl_number);
+        sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+        break;
+    }
+    return 1;
+}
 
 /* Convert IDP into a more convenient form */
 
 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
-	{
-	int idp_only = 0;
-	/* Set various flags according to IDP */
-	crl->idp_flags |= IDP_PRESENT;
-	if (idp->onlyuser > 0)
-		{
-		idp_only++;
-		crl->idp_flags |= IDP_ONLYUSER;
-		}
-	if (idp->onlyCA > 0)
-		{
-		idp_only++;
-		crl->idp_flags |= IDP_ONLYCA;
-		}
-	if (idp->onlyattr > 0)
-		{
-		idp_only++;
-		crl->idp_flags |= IDP_ONLYATTR;
-		}
+{
+    int idp_only = 0;
+    /* Set various flags according to IDP */
+    crl->idp_flags |= IDP_PRESENT;
+    if (idp->onlyuser > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYUSER;
+    }
+    if (idp->onlyCA > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYCA;
+    }
+    if (idp->onlyattr > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYATTR;
+    }
 
-	if (idp_only > 1)
-		crl->idp_flags |= IDP_INVALID;
+    if (idp_only > 1)
+        crl->idp_flags |= IDP_INVALID;
 
-	if (idp->indirectCRL > 0)
-		crl->idp_flags |= IDP_INDIRECT;
+    if (idp->indirectCRL > 0)
+        crl->idp_flags |= IDP_INDIRECT;
 
-	if (idp->onlysomereasons)
-		{
-		crl->idp_flags |= IDP_REASONS;
-		if (idp->onlysomereasons->length > 0)
-			crl->idp_reasons = idp->onlysomereasons->data[0];
-		if (idp->onlysomereasons->length > 1)
-			crl->idp_reasons |=
-				(idp->onlysomereasons->data[1] << 8);
-		crl->idp_reasons &= CRLDP_ALL_REASONS;
-		}
+    if (idp->onlysomereasons) {
+        crl->idp_flags |= IDP_REASONS;
+        if (idp->onlysomereasons->length > 0)
+            crl->idp_reasons = idp->onlysomereasons->data[0];
+        if (idp->onlysomereasons->length > 1)
+            crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
+        crl->idp_reasons &= CRLDP_ALL_REASONS;
+    }
 
-	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
-	}
+    DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(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)
+        ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
+        ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
+        ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
 
-static int X509_REVOKED_cmp(const X509_REVOKED **a,
-			const X509_REVOKED **b)
-	{
-	return(ASN1_STRING_cmp(
-		(ASN1_STRING *)(*a)->serialNumber,
-		(ASN1_STRING *)(*b)->serialNumber));
-	}
+static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b)
+{
+    return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber,
+                            (ASN1_STRING *)(*b)->serialNumber));
+}
 
 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
 {
-	X509_CRL_INFO *inf;
-	inf = crl->crl;
-	if(!inf->revoked)
-		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
-	if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	inf->enc.modified = 1;
-	return 1;
+    X509_CRL_INFO *inf;
+    inf = crl->crl;
+    if (!inf->revoked)
+        inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+    if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    inf->enc.modified = 1;
+    return 1;
 }
 
 int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
-	{
-	if (crl->meth->crl_verify)
-		return crl->meth->crl_verify(crl, r);
-	return 0;
-	}
+{
+    if (crl->meth->crl_verify)
+        return crl->meth->crl_verify(crl, r);
+    return 0;
+}
 
 int X509_CRL_get0_by_serial(X509_CRL *crl,
-		X509_REVOKED **ret, ASN1_INTEGER *serial)
-	{
-	if (crl->meth->crl_lookup)
-		return crl->meth->crl_lookup(crl, ret, serial, NULL);
-	return 0;
-	}
+                            X509_REVOKED **ret, ASN1_INTEGER *serial)
+{
+    if (crl->meth->crl_lookup)
+        return crl->meth->crl_lookup(crl, ret, serial, NULL);
+    return 0;
+}
 
 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
-	{
-	if (crl->meth->crl_lookup)
-		return crl->meth->crl_lookup(crl, ret,
-						X509_get_serialNumber(x),
-						X509_get_issuer_name(x));
-	return 0;
-	}
+{
+    if (crl->meth->crl_lookup)
+        return crl->meth->crl_lookup(crl, ret,
+                                     X509_get_serialNumber(x),
+                                     X509_get_issuer_name(x));
+    return 0;
+}
 
 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
-	{
-	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
-		crl->sig_alg, crl->signature,crl->crl,r));
-	}
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+                             crl->sig_alg, crl->signature, crl->crl, r));
+}
 
 static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
-						X509_REVOKED *rev)
-	{
-	size_t i;
+                                    X509_REVOKED *rev)
+{
+    size_t i;
 
-	if (!rev->issuer)
-		{
-		if (!nm)
-			return 1;
-		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
-			return 1;
-		return 0;
-		}
+    if (!rev->issuer) {
+        if (!nm)
+            return 1;
+        if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+            return 1;
+        return 0;
+    }
 
-	if (!nm)
-		nm = X509_CRL_get_issuer(crl);
+    if (!nm)
+        nm = X509_CRL_get_issuer(crl);
 
-	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
-		{
-		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
-		if (gen->type != GEN_DIRNAME)
-			continue;
-		if (!X509_NAME_cmp(nm, gen->d.directoryName))
-			return 1;
-		}
-	return 0;
+    for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+        if (gen->type != GEN_DIRNAME)
+            continue;
+        if (!X509_NAME_cmp(nm, gen->d.directoryName))
+            return 1;
+    }
+    return 0;
 
-	}
+}
 
 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)
-	{
-	X509_REVOKED rtmp, *rev;
-	size_t idx;
-	rtmp.serialNumber = serial;
-	/* Sort revoked into serial number order if not already sorted.
-	 * Do this under a lock to avoid race condition.
-	 */
+                          X509_REVOKED **ret, ASN1_INTEGER *serial,
+                          X509_NAME *issuer)
+{
+    X509_REVOKED rtmp, *rev;
+    size_t idx;
+    rtmp.serialNumber = serial;
+    /*
+     * Sort revoked into serial number order if not already sorted. Do this
+     * under a lock to avoid race condition.
+     */
 
-	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);
+    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_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 (!is_sorted) {
+        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 */
-	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
-		{
-		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
-		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
-			return 0;
-		if (crl_revoked_issuer_match(crl, issuer, rev))
-			{
-			if (ret)
-				*ret = rev;
-			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
-				return 2;
-			return 1;
-			}
-		}
-	return 0;
-	}
+    if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
+        return 0;
+    /* Need to look for matching name */
+    for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
+        rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+        if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+            return 0;
+        if (crl_revoked_issuer_match(crl, issuer, rev)) {
+            if (ret)
+                *ret = rev;
+            if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+                return 2;
+            return 1;
+        }
+    }
+    return 0;
+}
 
 void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
-	{
-	if (meth == NULL)
-		default_crl_method = &int_crl_meth;
-	else 
-		default_crl_method = meth;
-	}
+{
+    if (meth == NULL)
+        default_crl_method = &int_crl_meth;
+    else
+        default_crl_method = meth;
+}
 
-X509_CRL_METHOD *X509_CRL_METHOD_new(
-	int (*crl_init)(X509_CRL *crl),
-	int (*crl_free)(X509_CRL *crl),
-	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
-				ASN1_INTEGER *ser, X509_NAME *issuer),
-	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
-	{
-	X509_CRL_METHOD *m;
-	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
-	if (!m)
-		return NULL;
-	m->crl_init = crl_init;
-	m->crl_free = crl_free;
-	m->crl_lookup = crl_lookup;
-	m->crl_verify = crl_verify;
-	m->flags = X509_CRL_METHOD_DYNAMIC;
-	return m;
-	}
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+                                     int (*crl_free) (X509_CRL *crl),
+                                     int (*crl_lookup) (X509_CRL *crl,
+                                                        X509_REVOKED **ret,
+                                                        ASN1_INTEGER *ser,
+                                                        X509_NAME *issuer),
+                                     int (*crl_verify) (X509_CRL *crl,
+                                                        EVP_PKEY *pk))
+{
+    X509_CRL_METHOD *m;
+    m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
+    if (!m)
+        return NULL;
+    m->crl_init = crl_init;
+    m->crl_free = crl_free;
+    m->crl_lookup = crl_lookup;
+    m->crl_verify = crl_verify;
+    m->flags = X509_CRL_METHOD_DYNAMIC;
+    return m;
+}
 
 void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
-	{
-	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
-		return;
-	OPENSSL_free(m);
-	}
+{
+    if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+        return;
+    OPENSSL_free(m);
+}
 
 void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
-	{
-	crl->meth_data = dat;
-	}
+{
+    crl->meth_data = dat;
+}
 
 void *X509_CRL_get_meth_data(X509_CRL *crl)
-	{
-	return crl->meth_data;
-	}
+{
+    return crl->meth_data;
+}
 
 IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
+
 IMPLEMENT_ASN1_SET_OF(X509_CRL)
diff --git a/src/crypto/x509/x_exten.c b/src/crypto/x509/x_exten.c
index cf64c84..36403e4 100644
--- a/src/crypto/x509/x_exten.c
+++ b/src/crypto/x509/x_exten.c
@@ -61,13 +61,13 @@
 
 
 ASN1_SEQUENCE(X509_EXTENSION) = {
-	ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
-	ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
-	ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
+        ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+        ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+        ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
 } ASN1_SEQUENCE_END(X509_EXTENSION)
 
-ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
 ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
diff --git a/src/crypto/x509/x_info.c b/src/crypto/x509/x_info.c
index be579d7..177cd0e 100644
--- a/src/crypto/x509/x_info.c
+++ b/src/crypto/x509/x_info.c
@@ -61,35 +61,38 @@
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
-
 X509_INFO *X509_INFO_new(void)
-	{
-	X509_INFO *ret=NULL;
+{
+    X509_INFO *ret = NULL;
 
-	ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return(NULL);
-		}
- 
-        ret->enc_cipher.cipher=NULL;
-        ret->enc_len=0;
-        ret->enc_data=NULL;
- 
-	ret->x509=NULL;
-	ret->crl=NULL;
-	ret->x_pkey=NULL;
-	return(ret);
-	}
+    ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    ret->enc_cipher.cipher = NULL;
+    ret->enc_len = 0;
+    ret->enc_data = NULL;
+
+    ret->x509 = NULL;
+    ret->crl = NULL;
+    ret->x_pkey = NULL;
+    return (ret);
+}
 
 void X509_INFO_free(X509_INFO *x)
-	{
-	if (x == NULL) return;
+{
+    if (x == NULL)
+        return;
 
-	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);
-	if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
-	OPENSSL_free(x);
-	}
+    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);
+    if (x->enc_data != NULL)
+        OPENSSL_free(x->enc_data);
+    OPENSSL_free(x);
+}
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index a1dcd16..226e76d 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -68,471 +68,470 @@
 
 #include "../asn1/asn1_locl.h"
 
-
 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
-				const unsigned char **in, long len,
-				const ASN1_ITEM *it,
-				int tag, int aclass, char opt, ASN1_TLC *ctx);
+                            const unsigned char **in, long len,
+                            const ASN1_ITEM *it,
+                            int tag, int aclass, char opt, ASN1_TLC *ctx);
 
 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
-				const ASN1_ITEM *it, int tag, int aclass);
+                            const ASN1_ITEM *it, int tag, int aclass);
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
 
 static int x509_name_encode(X509_NAME *a);
 static int x509_name_canon(X509_NAME *a);
 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
-			  unsigned char **in);
-
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+                          unsigned char **in);
 
 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
-						int indent,
-						const char *fname, 
-						const ASN1_PCTX *pctx);
+                              int indent,
+                              const char *fname, const ASN1_PCTX *pctx);
 
 ASN1_SEQUENCE(X509_NAME_ENTRY) = {
-	ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
-	ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+        ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+        ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
 } ASN1_SEQUENCE_END(X509_NAME_ENTRY)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
 
-/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
- * so declare two template wrappers for this
+/*
+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
+ * declare two template wrappers for this
  */
 
 ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
 ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
 ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
 
-/* Normally that's where it would end: we'd have two nested STACK structures
+/*
+ * Normally that's where it would end: we'd have two nested STACK structures
  * representing the ASN1. Unfortunately X509_NAME uses a completely different
- * form and caches encodings so we have to process the internal form and convert
- * to the external form.
+ * form and caches encodings so we have to process the internal form and
+ * convert to the external form.
  */
 
 static const ASN1_EXTERN_FUNCS x509_name_ff = {
-	NULL,
-	x509_name_ex_new,
-	x509_name_ex_free,
-	0,	/* Default clear behaviour is OK */
-	x509_name_ex_d2i,
-	x509_name_ex_i2d,
-	x509_name_ex_print
+    NULL,
+    x509_name_ex_new,
+    x509_name_ex_free,
+    0,                          /* Default clear behaviour is OK */
+    x509_name_ex_d2i,
+    x509_name_ex_i2d,
+    x509_name_ex_print
 };
 
-IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
 
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
 {
-	X509_NAME *ret = NULL;
-	ret = OPENSSL_malloc(sizeof(X509_NAME));
-	if(!ret) goto memerr;
-	if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
-		goto memerr;
-	if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
-	ret->canon_enc = NULL;
-	ret->canon_enclen = 0;
-	ret->modified=1;
-	*val = (ASN1_VALUE *)ret;
-	return 1;
+    X509_NAME *ret = NULL;
+    ret = OPENSSL_malloc(sizeof(X509_NAME));
+    if (!ret)
+        goto memerr;
+    if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
+        goto memerr;
+    if ((ret->bytes = BUF_MEM_new()) == NULL)
+        goto memerr;
+    ret->canon_enc = NULL;
+    ret->canon_enclen = 0;
+    ret->modified = 1;
+    *val = (ASN1_VALUE *)ret;
+    return 1;
 
  memerr:
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	if (ret)
-		{
-		if (ret->entries)
-			sk_X509_NAME_ENTRY_free(ret->entries);
-		OPENSSL_free(ret);
-		}
-	return 0;
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    if (ret) {
+        if (ret->entries)
+            sk_X509_NAME_ENTRY_free(ret->entries);
+        OPENSSL_free(ret);
+    }
+    return 0;
 }
 
 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-	X509_NAME *a;
-	if(!pval || !*pval)
-	    return;
-	a = (X509_NAME *)*pval;
+    X509_NAME *a;
+    if (!pval || !*pval)
+        return;
+    a = (X509_NAME *)*pval;
 
-	BUF_MEM_free(a->bytes);
-	sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
-	if (a->canon_enc)
-		OPENSSL_free(a->canon_enc);
-	OPENSSL_free(a);
-	*pval = NULL;
+    BUF_MEM_free(a->bytes);
+    sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+    if (a->canon_enc)
+        OPENSSL_free(a->canon_enc);
+    OPENSSL_free(a);
+    *pval = NULL;
 }
 
 static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
 {
-	sk_X509_NAME_ENTRY_free(ne);
+    sk_X509_NAME_ENTRY_free(ne);
 }
 
 static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
 {
-	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
 }
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
-			const unsigned char **in, long len, const ASN1_ITEM *it,
-				int tag, int aclass, char opt, ASN1_TLC *ctx)
+                            const unsigned char **in, long len,
+                            const ASN1_ITEM *it, int tag, int aclass,
+                            char opt, ASN1_TLC *ctx)
 {
-	const unsigned char *p = *in, *q;
-	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
-		ASN1_VALUE *a; } intname = {NULL};
-	union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
-	size_t i, j;
-	int ret;
-	STACK_OF(X509_NAME_ENTRY) *entries;
-	X509_NAME_ENTRY *entry;
-	q = p;
+    const unsigned char *p = *in, *q;
+    union {
+        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+        ASN1_VALUE *a;
+    } intname = {
+        NULL
+    };
+    union {
+        X509_NAME *x;
+        ASN1_VALUE *a;
+    } nm = {
+        NULL
+    };
+    size_t i, j;
+    int ret;
+    STACK_OF(X509_NAME_ENTRY) *entries;
+    X509_NAME_ENTRY *entry;
+    q = p;
 
-	/* Get internal representation of Name */
-	ret = ASN1_item_ex_d2i(&intname.a,
-			       &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
-			       tag, aclass, opt, ctx);
-	
-	if(ret <= 0) return ret;
+    /* Get internal representation of Name */
+    ret = ASN1_item_ex_d2i(&intname.a,
+                           &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+                           tag, aclass, opt, ctx);
 
-	if(*val) x509_name_ex_free(val, NULL);
-	/* We've decoded it: now cache encoding */
-	if (!x509_name_ex_new(&nm.a, NULL) ||
-		!BUF_MEM_grow(nm.x->bytes, p - q))
-		{
-		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
-			local_sk_X509_NAME_ENTRY_pop_free);
-		goto err;
-		}
-	memcpy(nm.x->bytes->data, q, p - q);
+    if (ret <= 0)
+        return ret;
 
-	/* Convert internal representation to X509_NAME structure */
-	for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
-		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
-		for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
-			entry = sk_X509_NAME_ENTRY_value(entries, j);
-			entry->set = i;
-			if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
-				goto err;
-		}
-		sk_X509_NAME_ENTRY_free(entries);
-	}
-	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
-	ret = x509_name_canon(nm.x);
-	if (!ret)
-		goto err;
-	nm.x->modified = 0;
-	*val = nm.a;
-	*in = p;
-	return ret;
-err:
-        if (nm.x != NULL)
-		X509_NAME_free(nm.x);
-	OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
-	return 0;
+    if (*val)
+        x509_name_ex_free(val, NULL);
+    /* We've decoded it: now cache encoding */
+    if (!x509_name_ex_new(&nm.a, NULL) || !BUF_MEM_grow(nm.x->bytes, p - q)) {
+        sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                             local_sk_X509_NAME_ENTRY_pop_free);
+        goto err;
+    }
+    memcpy(nm.x->bytes->data, q, p - q);
+
+    /* Convert internal representation to X509_NAME structure */
+    for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+        entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+        for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+            entry = sk_X509_NAME_ENTRY_value(entries, j);
+            entry->set = i;
+            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+                goto err;
+        }
+        sk_X509_NAME_ENTRY_free(entries);
+    }
+    sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+    ret = x509_name_canon(nm.x);
+    if (!ret)
+        goto err;
+    nm.x->modified = 0;
+    *val = nm.a;
+    *in = p;
+    return ret;
+ err:
+    if (nm.x != NULL)
+        X509_NAME_free(nm.x);
+    OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+    return 0;
 }
 
-static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+                            const ASN1_ITEM *it, int tag, int aclass)
 {
-	int ret;
-	X509_NAME *a = (X509_NAME *)*val;
-	if(a->modified) {
-		ret = x509_name_encode(a);
-		if(ret < 0)
-			return ret;
-		ret = x509_name_canon(a);
-		if(ret < 0)
-			return ret;
-	}
-	ret = a->bytes->length;
-	if(out != NULL) {
-		memcpy(*out,a->bytes->data,ret);
-		*out+=ret;
-	}
-	return ret;
+    int ret;
+    X509_NAME *a = (X509_NAME *)*val;
+    if (a->modified) {
+        ret = x509_name_encode(a);
+        if (ret < 0)
+            return ret;
+        ret = x509_name_canon(a);
+        if (ret < 0)
+            return ret;
+    }
+    ret = a->bytes->length;
+    if (out != NULL) {
+        memcpy(*out, a->bytes->data, ret);
+        *out += ret;
+    }
+    return ret;
 }
 
 static int x509_name_encode(X509_NAME *a)
 {
-	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
-		ASN1_VALUE *a; } intname = {NULL};
-	int len;
-	unsigned char *p;
-	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
-	X509_NAME_ENTRY *entry;
-	int set = -1;
-	size_t i;
-	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
-	if(!intname.s) goto memerr;
-	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
-		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
-		if(entry->set != set) {
-			entries = sk_X509_NAME_ENTRY_new_null();
-			if(!entries) goto memerr;
-			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
-							     entries))
-				goto memerr;
-			set = entry->set;
-		}
-		if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
-	}
-	len = ASN1_item_ex_i2d(&intname.a, NULL,
-			       ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
-	if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
-	p=(unsigned char *)a->bytes->data;
-	ASN1_item_ex_i2d(&intname.a,
-			 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
-	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
-					     local_sk_X509_NAME_ENTRY_free);
-	a->modified = 0;
-	return len;
-memerr:
-	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
-					     local_sk_X509_NAME_ENTRY_free);
-	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-	return -1;
+    union {
+        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+        ASN1_VALUE *a;
+    } intname = {
+        NULL
+    };
+    int len;
+    unsigned char *p;
+    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+    X509_NAME_ENTRY *entry;
+    int set = -1;
+    size_t i;
+    intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+    if (!intname.s)
+        goto memerr;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+        if (entry->set != set) {
+            entries = sk_X509_NAME_ENTRY_new_null();
+            if (!entries)
+                goto memerr;
+            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
+                goto memerr;
+            set = entry->set;
+        }
+        if (!sk_X509_NAME_ENTRY_push(entries, entry))
+            goto memerr;
+    }
+    len = ASN1_item_ex_i2d(&intname.a, NULL,
+                           ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+    if (!BUF_MEM_grow(a->bytes, len))
+        goto memerr;
+    p = (unsigned char *)a->bytes->data;
+    ASN1_item_ex_i2d(&intname.a,
+                     &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_free);
+    a->modified = 0;
+    return len;
+ memerr:
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_free);
+    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+    return -1;
 }
 
 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
-						int indent,
-						const char *fname, 
-						const ASN1_PCTX *pctx)
-	{
-	if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
-					indent, pctx->nm_flags) <= 0)
-		return 0;
-	return 2;
-	}
+                              int indent,
+                              const char *fname, const ASN1_PCTX *pctx)
+{
+    if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
+                           indent, pctx->nm_flags) <= 0)
+        return 0;
+    return 2;
+}
 
-/* This function generates the canonical encoding of the Name structure.
- * In it all strings are converted to UTF8, leading, trailing and
- * multiple spaces collapsed, converted to lower case and the leading
- * SEQUENCE header removed.
- *
- * In future we could also normalize the UTF8 too.
- *
- * By doing this comparison of Name structures can be rapidly
- * perfomed by just using memcmp() of the canonical encoding.
- * By omitting the leading SEQUENCE name constraints of type
- * dirName can also be checked with a simple memcmp().
+/*
+ * This function generates the canonical encoding of the Name structure. In
+ * it all strings are converted to UTF8, leading, trailing and multiple
+ * spaces collapsed, converted to lower case and the leading SEQUENCE header
+ * removed. In future we could also normalize the UTF8 too. By doing this
+ * comparison of Name structures can be rapidly perfomed by just using
+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
+ * constraints of type dirName can also be checked with a simple memcmp().
  */
 
 static int x509_name_canon(X509_NAME *a)
-	{
-	unsigned char *p;
-	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
-	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
-	X509_NAME_ENTRY *entry, *tmpentry = NULL;
-	int set = -1, ret = 0;
-	size_t i;
+{
+    unsigned char *p;
+    STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+    X509_NAME_ENTRY *entry, *tmpentry = NULL;
+    int set = -1, ret = 0;
+    size_t i;
 
-	if (a->canon_enc)
-		{
-		OPENSSL_free(a->canon_enc);
-		a->canon_enc = NULL;
-		}
-	/* Special case: empty X509_NAME => null encoding */
-	if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
-		{
-		a->canon_enclen = 0;
-		return 1;
-		}
-	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
-	if(!intname)
-		goto err;
-	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
-		{
-		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
-		if(entry->set != set)
-			{
-			entries = sk_X509_NAME_ENTRY_new_null();
-			if(!entries)
-				goto err;
-			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
-				{
-				sk_X509_NAME_ENTRY_free(entries);
-				goto err;
-				}
-			set = entry->set;
-			}
-		tmpentry = X509_NAME_ENTRY_new();
-		if (tmpentry == NULL)
-			goto err;
-		tmpentry->object = OBJ_dup(entry->object);
-		if (!asn1_string_canon(tmpentry->value, entry->value))
-			goto err;
-		if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
-			goto err;
-		tmpentry = NULL;
-		}
+    if (a->canon_enc) {
+        OPENSSL_free(a->canon_enc);
+        a->canon_enc = NULL;
+    }
+    /* Special case: empty X509_NAME => null encoding */
+    if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+        a->canon_enclen = 0;
+        return 1;
+    }
+    intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+    if (!intname)
+        goto err;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+        if (entry->set != set) {
+            entries = sk_X509_NAME_ENTRY_new_null();
+            if (!entries)
+                goto err;
+            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
+                sk_X509_NAME_ENTRY_free(entries);
+                goto err;
+            }
+            set = entry->set;
+        }
+        tmpentry = X509_NAME_ENTRY_new();
+        if (tmpentry == NULL)
+            goto err;
+        tmpentry->object = OBJ_dup(entry->object);
+        if (!asn1_string_canon(tmpentry->value, entry->value))
+            goto err;
+        if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+            goto err;
+        tmpentry = NULL;
+    }
 
-	/* Finally generate encoding */
+    /* Finally generate encoding */
 
-	a->canon_enclen = i2d_name_canon(intname, NULL);
+    a->canon_enclen = i2d_name_canon(intname, NULL);
 
-	p = OPENSSL_malloc(a->canon_enclen);
+    p = OPENSSL_malloc(a->canon_enclen);
 
-	if (!p)
-		goto err;
+    if (!p)
+        goto err;
 
-	a->canon_enc = p;
+    a->canon_enc = p;
 
-	i2d_name_canon(intname, &p);
+    i2d_name_canon(intname, &p);
 
-	ret = 1;
+    ret = 1;
 
-	err:
+ err:
 
-	if (tmpentry)
-		X509_NAME_ENTRY_free(tmpentry);
-	if (intname)
-		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
-					local_sk_X509_NAME_ENTRY_pop_free);
-	return ret;
-	}
+    if (tmpentry)
+        X509_NAME_ENTRY_free(tmpentry);
+    if (intname)
+        sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+                                             local_sk_X509_NAME_ENTRY_pop_free);
+    return ret;
+}
 
 /* Bitmap of all the types of string that will be canonicalized. */
 
-#define ASN1_MASK_CANON	\
-	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
-	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
-	| B_ASN1_VISIBLESTRING)
-	
+#define ASN1_MASK_CANON \
+        (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+        | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+        | B_ASN1_VISIBLESTRING)
 
 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
-	{
-	unsigned char *to, *from;
-	int len, i;
+{
+    unsigned char *to, *from;
+    int len, i;
 
-	/* If type not in bitmask just copy string across */
-	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
-		{
-		if (!ASN1_STRING_copy(out, in))
-			return 0;
-		return 1;
-		}
+    /* If type not in bitmask just copy string across */
+    if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+        if (!ASN1_STRING_copy(out, in))
+            return 0;
+        return 1;
+    }
 
-	out->type = V_ASN1_UTF8STRING;
-	out->length = ASN1_STRING_to_UTF8(&out->data, in);
-	if (out->length == -1)
-		return 0;
+    out->type = V_ASN1_UTF8STRING;
+    out->length = ASN1_STRING_to_UTF8(&out->data, in);
+    if (out->length == -1)
+        return 0;
 
-	to = out->data;
-	from = to;
+    to = out->data;
+    from = to;
 
-	len = out->length;
+    len = out->length;
 
-	/* Convert string in place to canonical form.
-	 * Ultimately we may need to handle a wider range of characters
-	 * but for now ignore anything with MSB set and rely on the
-	 * isspace() and tolower() functions.
-	 */
+    /*
+     * Convert string in place to canonical form. Ultimately we may need to
+     * handle a wider range of characters but for now ignore anything with
+     * MSB set and rely on the isspace() and tolower() functions.
+     */
 
-	/* Ignore leading spaces */
-	while((len > 0) && !(*from & 0x80) && isspace(*from))
-		{
-		from++;
-		len--;
-		}
+    /* Ignore leading spaces */
+    while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
+        from++;
+        len--;
+    }
 
-	to = from + len - 1;
+    to = from + len - 1;
 
-	/* Ignore trailing spaces */
-	while ((len > 0) && !(*to & 0x80) && isspace(*to))
-		{
-		to--;
-		len--;
-		}
+    /* Ignore trailing spaces */
+    while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
+        to--;
+        len--;
+    }
 
-	to = out->data;
+    to = out->data;
 
-	i = 0;
-	while(i < len)
-		{
-		/* If MSB set just copy across */
-		if (*from & 0x80)
-			{
-			*to++ = *from++;
-			i++;
-			}
-		/* Collapse multiple spaces */
-		else if (isspace(*from))
-			{
-			/* Copy one space across */
-			*to++ = ' ';
-			/* Ignore subsequent spaces. Note: don't need to
-			 * check len here because we know the last 
-			 * character is a non-space so we can't overflow.
-			 */
-			do
-				{
-				from++;
-				i++;
-				}
-			while(!(*from & 0x80) && isspace(*from));
-			}
-		else
-			{
-			*to++ = tolower(*from);
-			from++;
-			i++;
-			}
-		}
+    i = 0;
+    while (i < len) {
+        /* If MSB set just copy across */
+        if (*from & 0x80) {
+            *to++ = *from++;
+            i++;
+        }
+        /* Collapse multiple spaces */
+        else if (isspace(*from)) {
+            /* Copy one space across */
+            *to++ = ' ';
+            /*
+             * Ignore subsequent spaces. Note: don't need to check len here
+             * because we know the last character is a non-space so we can't
+             * overflow.
+             */
+            do {
+                from++;
+                i++;
+            }
+            while (!(*from & 0x80) && isspace(*from));
+        } else {
+            *to++ = tolower(*from);
+            from++;
+            i++;
+        }
+    }
 
-	out->length = to - out->data;
+    out->length = to - out->data;
 
-	return 1;
+    return 1;
 
-	}
+}
 
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
-			  unsigned char **in)
-	{
-	int len, ltmp;
-	size_t i;
-	ASN1_VALUE *v;
-	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+                          unsigned char **in)
+{
+    int len, ltmp;
+    size_t i;
+    ASN1_VALUE *v;
+    STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
 
-	len = 0;
-	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
-		{
-		v = sk_ASN1_VALUE_value(intname, i);
-		ltmp = ASN1_item_ex_i2d(&v, in,
-			ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
-		if (ltmp < 0)
-			return ltmp;
-		len += ltmp;
-		}
-	return len;
-	}
+    len = 0;
+    for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+        v = sk_ASN1_VALUE_value(intname, i);
+        ltmp = ASN1_item_ex_i2d(&v, in,
+                                ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+        if (ltmp < 0)
+            return ltmp;
+        len += ltmp;
+    }
+    return len;
+}
 
 int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
-	{
-	X509_NAME *in;
+{
+    X509_NAME *in;
 
-	if (!xn || !name) return(0);
+    if (!xn || !name)
+        return (0);
 
-	if (*xn != name)
-		{
-		in=X509_NAME_dup(name);
-		if (in != NULL)
-			{
-			X509_NAME_free(*xn);
-			*xn=in;
-			}
-		}
-	return(*xn != NULL);
-	}
-	
+    if (*xn != name) {
+        in = X509_NAME_dup(name);
+        if (in != NULL) {
+            X509_NAME_free(*xn);
+            *xn = in;
+        }
+    }
+    return (*xn != NULL);
+}
+
 IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
diff --git a/src/crypto/x509/x_pkey.c b/src/crypto/x509/x_pkey.c
index f5e98b8..fc44595 100644
--- a/src/crypto/x509/x_pkey.c
+++ b/src/crypto/x509/x_pkey.c
@@ -63,38 +63,41 @@
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
-
 X509_PKEY *X509_PKEY_new(void)
-	{
-	X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
-	if (ret == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	memset(ret, 0, sizeof(X509_PKEY));
+{
+    X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
+    if (ret == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    memset(ret, 0, sizeof(X509_PKEY));
 
-	ret->enc_algor = X509_ALGOR_new();
-	if (ret->enc_algor == NULL)
-		goto err;
-	ret->enc_pkey = M_ASN1_OCTET_STRING_new();
-	if (ret->enc_pkey == NULL)
-		goto err;
-	return ret;
+    ret->enc_algor = X509_ALGOR_new();
+    if (ret->enc_algor == NULL)
+        goto err;
+    ret->enc_pkey = M_ASN1_OCTET_STRING_new();
+    if (ret->enc_pkey == NULL)
+        goto err;
+    return ret;
 
-err:
-	if (ret != NULL)
-		X509_PKEY_free(ret);
-	return NULL;
-	}
+ err:
+    if (ret != NULL)
+        X509_PKEY_free(ret);
+    return NULL;
+}
 
 void X509_PKEY_free(X509_PKEY *x)
-	{
-	if (x == NULL) return;
+{
+    if (x == NULL)
+        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);
-	if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
-	OPENSSL_free(x);
-	}
+    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);
+    if ((x->key_data != NULL) && (x->key_free))
+        OPENSSL_free(x->key_data);
+    OPENSSL_free(x);
+}
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c
index a16edca..1549195 100644
--- a/src/crypto/x509/x_pubkey.c
+++ b/src/crypto/x509/x_pubkey.c
@@ -54,78 +54,75 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
+#include <openssl/x509.h>
+
+#include <limits.h>
+
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 #include <openssl/thread.h>
-#include <openssl/x509.h>
 
-#include "../evp/internal.h"
 #include "../internal.h"
 
-
 /* Minor tweak to operation: free up EVP_PKEY */
 static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-			void *exarg)
-	{
-	if (operation == ASN1_OP_FREE_POST)
-		{
-		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
-		EVP_PKEY_free(pubkey->pkey);
-		}
-	return 1;
-	}
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+        EVP_PKEY_free(pubkey->pkey);
+    }
+    return 1;
+}
 
 ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
-	ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
-	ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+        ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+        ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
 
 int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
-	{
-	X509_PUBKEY *pk=NULL;
+{
+    X509_PUBKEY *pk = NULL;
+    uint8_t *spki = NULL;
+    size_t spki_len;
 
-	if (x == NULL) return(0);
+    if (x == NULL)
+        return (0);
 
-	if ((pk=X509_PUBKEY_new()) == NULL) goto error;
+    CBB cbb;
+    if (!CBB_init(&cbb, 0) ||
+        !EVP_marshal_public_key(&cbb, pkey) ||
+        !CBB_finish(&cbb, &spki, &spki_len) ||
+        spki_len > LONG_MAX) {
+        CBB_cleanup(&cbb);
+        OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
+        goto error;
+    }
 
-	if (pkey->ameth)
-		{
-		if (pkey->ameth->pub_encode)
-			{
-			if (!pkey->ameth->pub_encode(pk, pkey))
-				{
-				OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
-				goto error;
-				}
-			}
-		else
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
-			goto error;
-			}
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
-		goto error;
-		}
+    const uint8_t *p = spki;
+    pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len);
+    if (pk == NULL || p != spki + spki_len) {
+        OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
+        goto error;
+    }
 
-	if (*x != NULL)
-		X509_PUBKEY_free(*x);
+    OPENSSL_free(spki);
+    X509_PUBKEY_free(*x);
+    *x = pk;
 
-	*x=pk;
-
-	return 1;
-error:
-	if (pk != NULL) X509_PUBKEY_free(pk);
-	return 0;
-	}
+    return 1;
+ error:
+    X509_PUBKEY_free(pk);
+    OPENSSL_free(spki);
+    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|
@@ -134,251 +131,236 @@
 static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT;
 
 EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
-	{
-	EVP_PKEY *ret=NULL;
+{
+    EVP_PKEY *ret = NULL;
+    uint8_t *spki = NULL;
 
-	if (key == NULL) goto error;
+    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);
+    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;
+    /* Re-encode the |X509_PUBKEY| to DER and parse it. */
+    int spki_len = i2d_X509_PUBKEY(key, &spki);
+    if (spki_len < 0) {
+        goto error;
+    }
+    CBS cbs;
+    CBS_init(&cbs, spki, (size_t)spki_len);
+    ret = EVP_parse_public_key(&cbs);
+    if (ret == NULL || CBS_len(&cbs) != 0) {
+        OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
+        goto error;
+    }
 
-	if ((ret = EVP_PKEY_new()) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		goto error;
-		}
+    /* Check to see if another thread set key->pkey first */
+    CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
+    if (key->pkey) {
+        CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+        EVP_PKEY_free(ret);
+        ret = key->pkey;
+    } else {
+        key->pkey = ret;
+        CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+    }
 
-	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
-		goto error;
-		}
+    OPENSSL_free(spki);
+    return EVP_PKEY_up_ref(ret);
 
-	if (ret->ameth->pub_decode)
-		{
-		if (!ret->ameth->pub_decode(ret, key))
-			{
-			OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
-			goto error;
-			}
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
-		goto error;
-		}
+ error:
+    OPENSSL_free(spki);
+    EVP_PKEY_free(ret);
+    return NULL;
+}
 
-	/* Check to see if another thread set key->pkey first */
-	CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
-	if (key->pkey)
-		{
-		CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
-		EVP_PKEY_free(ret);
-		ret = key->pkey;
-		}
-	else
-		{
-		key->pkey = ret;
-		CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
-		}
-
-	return EVP_PKEY_up_ref(ret);
-
-	error:
-	if (ret != NULL)
-		EVP_PKEY_free(ret);
-	return(NULL);
-	}
-
-/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
- * and encode or decode as X509_PUBKEY
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
  */
 
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
-	     long length)
-	{
-	X509_PUBKEY *xpk;
-	EVP_PKEY *pktmp;
-	xpk = d2i_X509_PUBKEY(NULL, pp, length);
-	if(!xpk) return NULL;
-	pktmp = X509_PUBKEY_get(xpk);
-	X509_PUBKEY_free(xpk);
-	if(!pktmp) return NULL;
-	if(a)
-		{
-		EVP_PKEY_free(*a);
-		*a = pktmp;
-		}
-	return pktmp;
-	}
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+    X509_PUBKEY *xpk;
+    EVP_PKEY *pktmp;
+    xpk = d2i_X509_PUBKEY(NULL, pp, length);
+    if (!xpk)
+        return NULL;
+    pktmp = X509_PUBKEY_get(xpk);
+    X509_PUBKEY_free(xpk);
+    if (!pktmp)
+        return NULL;
+    if (a) {
+        EVP_PKEY_free(*a);
+        *a = pktmp;
+    }
+    return pktmp;
+}
 
 int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
-	{
-	X509_PUBKEY *xpk=NULL;
-	int ret;
-	if(!a) return 0;
-	if(!X509_PUBKEY_set(&xpk, (EVP_PKEY*) a)) return 0;
-	ret = i2d_X509_PUBKEY(xpk, pp);
-	X509_PUBKEY_free(xpk);
-	return ret;
-	}
+{
+    X509_PUBKEY *xpk = NULL;
+    int ret;
+    if (!a)
+        return 0;
+    if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)a))
+        return 0;
+    ret = i2d_X509_PUBKEY(xpk, pp);
+    X509_PUBKEY_free(xpk);
+    return ret;
+}
 
-/* The following are equivalents but which return RSA and DSA
- * keys
+/*
+ * The following are equivalents but which return RSA and DSA keys
  */
-RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
-	     long length)
-	{
-	EVP_PKEY *pkey;
-	RSA *key;
-	const unsigned char *q;
-	q = *pp;
-	pkey = d2i_PUBKEY(NULL, &q, length);
-	if (!pkey) return NULL;
-	key = EVP_PKEY_get1_RSA(pkey);
-	EVP_PKEY_free(pkey);
-	if (!key) return NULL;
-	*pp = q;
-	if (a)
-		{
-		RSA_free(*a);
-		*a = key;
-		}
-	return key;
-	}
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+    EVP_PKEY *pkey;
+    RSA *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return NULL;
+    key = EVP_PKEY_get1_RSA(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return NULL;
+    *pp = q;
+    if (a) {
+        RSA_free(*a);
+        *a = key;
+    }
+    return key;
+}
 
 int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
-	{
-	EVP_PKEY *pktmp;
-	int ret;
-	if (!a) return 0;
-	pktmp = EVP_PKEY_new();
-	if (!pktmp)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	EVP_PKEY_set1_RSA(pktmp, (RSA*) a);
-	ret = i2d_PUBKEY(pktmp, pp);
-	EVP_PKEY_free(pktmp);
-	return ret;
-	}
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return 0;
+    pktmp = EVP_PKEY_new();
+    if (!pktmp) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    EVP_PKEY_set1_RSA(pktmp, (RSA *)a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return ret;
+}
 
 #ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
-	     long length)
-	{
-	EVP_PKEY *pkey;
-	DSA *key;
-	const unsigned char *q;
-	q = *pp;
-	pkey = d2i_PUBKEY(NULL, &q, length);
-	if (!pkey) return NULL;
-	key = EVP_PKEY_get1_DSA(pkey);
-	EVP_PKEY_free(pkey);
-	if (!key) return NULL;
-	*pp = q;
-	if (a)
-		{
-		DSA_free(*a);
-		*a = key;
-		}
-	return key;
-	}
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+    EVP_PKEY *pkey;
+    DSA *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return NULL;
+    key = EVP_PKEY_get1_DSA(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return NULL;
+    *pp = q;
+    if (a) {
+        DSA_free(*a);
+        *a = key;
+    }
+    return key;
+}
 
 int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
-	{
-	EVP_PKEY *pktmp;
-	int ret;
-	if(!a) return 0;
-	pktmp = EVP_PKEY_new();
-	if(!pktmp)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return 0;
-		}
-	EVP_PKEY_set1_DSA(pktmp, (DSA*) a);
-	ret = i2d_PUBKEY(pktmp, pp);
-	EVP_PKEY_free(pktmp);
-	return ret;
-	}
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return 0;
+    pktmp = EVP_PKEY_new();
+    if (!pktmp) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    EVP_PKEY_set1_DSA(pktmp, (DSA *)a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return ret;
+}
 #endif
 
 EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
-	{
-	EVP_PKEY *pkey;
-	EC_KEY *key;
-	const unsigned char *q;
-	q = *pp;
-	pkey = d2i_PUBKEY(NULL, &q, length);
-	if (!pkey) return(NULL);
-	key = EVP_PKEY_get1_EC_KEY(pkey);
-	EVP_PKEY_free(pkey);
-	if (!key)  return(NULL);
-	*pp = q;
-	if (a)
-		{
-		EC_KEY_free(*a);
-		*a = key;
-		}
-	return(key);
-	}
+{
+    EVP_PKEY *pkey;
+    EC_KEY *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return (NULL);
+    key = EVP_PKEY_get1_EC_KEY(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return (NULL);
+    *pp = q;
+    if (a) {
+        EC_KEY_free(*a);
+        *a = key;
+    }
+    return (key);
+}
 
 int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
-	{
-	EVP_PKEY *pktmp;
-	int ret;
-	if (!a)	return(0);
-	if ((pktmp = EVP_PKEY_new()) == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY*) a);
-	ret = i2d_PUBKEY(pktmp, pp);
-	EVP_PKEY_free(pktmp);
-	return(ret);
-	}
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return (0);
+    if ((pktmp = EVP_PKEY_new()) == NULL) {
+        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return (ret);
+}
 
 int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj,
-					int ptype, void *pval,
-					unsigned char *penc, int penclen)
-	{
-	if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
-		return 0;
-	if (penc)
-		{
-		if (pub->public_key->data)
-			OPENSSL_free(pub->public_key->data);
-		pub->public_key->data = penc;
-		pub->public_key->length = penclen;
-  		/* Set number of unused bits to zero */
-		pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
-		pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
-		}
-	return 1;
-	}
+                           int ptype, void *pval,
+                           unsigned char *penc, int penclen)
+{
+    if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+        return 0;
+    if (penc) {
+        if (pub->public_key->data)
+            OPENSSL_free(pub->public_key->data);
+        pub->public_key->data = penc;
+        pub->public_key->length = penclen;
+        /* Set number of unused bits to zero */
+        pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    }
+    return 1;
+}
 
 int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
-		const unsigned char **pk, int *ppklen,
-		X509_ALGOR **pa,
-		X509_PUBKEY *pub)
-	{
-	if (ppkalg)
-		*ppkalg = pub->algor->algorithm;
-	if (pk)
-		{
-		*pk = pub->public_key->data;
-		*ppklen = pub->public_key->length;
-		}
-	if (pa)
-		*pa = pub->algor;
-	return 1;
-	}
+                           const unsigned char **pk, int *ppklen,
+                           X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+    if (ppkalg)
+        *ppkalg = pub->algor->algorithm;
+    if (pk) {
+        *pk = pub->public_key->data;
+        *ppklen = pub->public_key->length;
+    }
+    if (pa)
+        *pa = pub->algor;
+    return 1;
+}
diff --git a/src/crypto/x509/x_req.c b/src/crypto/x509/x_req.c
index 3d30129..5dfe19e 100644
--- a/src/crypto/x509/x_req.c
+++ b/src/crypto/x509/x_req.c
@@ -60,53 +60,50 @@
 #include <openssl/thread.h>
 #include <openssl/x509.h>
 
-/* X509_REQ_INFO is handled in an unusual way to get round
- * invalid encodings. Some broken certificate requests don't
- * encode the attributes field if it is empty. This is in
- * violation of PKCS#10 but we need to tolerate it. We do
- * this by making the attributes field OPTIONAL then using
- * the callback to initialise it to an empty STACK. 
- *
- * This means that the field will be correctly encoded unless
- * we NULL out the field.
- *
- * As a result we no longer need the req_kludge field because
- * the information is now contained in the attributes field:
- * 1. If it is NULL then it's the invalid omission.
- * 2. If it is empty it is the correct encoding.
- * 3. If it is not empty then some attributes are present.
- *
+/*
+ * X509_REQ_INFO is handled in an unusual way to get round invalid encodings.
+ * Some broken certificate requests don't encode the attributes field if it
+ * is empty. This is in violation of PKCS#10 but we need to tolerate it. We
+ * do this by making the attributes field OPTIONAL then using the callback to
+ * initialise it to an empty STACK. This means that the field will be
+ * correctly encoded unless we NULL out the field. As a result we no longer
+ * need the req_kludge field because the information is now contained in the
+ * attributes field: 1. If it is NULL then it's the invalid omission. 2. If
+ * it is empty it is the correct encoding. 3. If it is not empty then some
+ * attributes are present.
  */
 
 static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-							void *exarg)
+                   void *exarg)
 {
-	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+    X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
 
-	if(operation == ASN1_OP_NEW_POST) {
-		rinf->attributes = sk_X509_ATTRIBUTE_new_null();
-		if(!rinf->attributes) return 0;
-	}
-	return 1;
+    if (operation == ASN1_OP_NEW_POST) {
+        rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+        if (!rinf->attributes)
+            return 0;
+    }
+    return 1;
 }
 
 ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
-	ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
-	ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
-	ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
-	/* This isn't really OPTIONAL but it gets round invalid
-	 * encodings
-	 */
-	ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+        ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+        ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+        /* This isn't really OPTIONAL but it gets round invalid
+         * encodings
+         */
+        ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
 } ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
 
 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)
+        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)
 } ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/src/crypto/x509/x_sig.c b/src/crypto/x509/x_sig.c
index fabdb67..e18024a 100644
--- a/src/crypto/x509/x_sig.c
+++ b/src/crypto/x509/x_sig.c
@@ -62,8 +62,8 @@
 
 
 ASN1_SEQUENCE(X509_SIG) = {
-	ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
-	ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+        ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+        ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
 } ASN1_SEQUENCE_END(X509_SIG)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
diff --git a/src/crypto/x509/x_spki.c b/src/crypto/x509/x_spki.c
index 35bf246..86da6dd 100644
--- a/src/crypto/x509/x_spki.c
+++ b/src/crypto/x509/x_spki.c
@@ -55,24 +55,26 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
- /* This module was send to me my Pat Richards <patr@x509.com> who
-  * wrote it.  It is under my Copyright with his permission. */
+ /*
+  * This module was send to me my Pat Richards <patr@x509.com> who wrote it.
+  * It is under my Copyright with his permission.
+  */
 
 #include <openssl/x509.h>
 #include <openssl/asn1t.h>
 
 
 ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
-	ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
-	ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+        ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+        ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
 } ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
 
 IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
 
 ASN1_SEQUENCE(NETSCAPE_SPKI) = {
-	ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
-	ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
-	ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+        ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+        ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+        ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END(NETSCAPE_SPKI)
 
 IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
diff --git a/src/crypto/x509/x_val.c b/src/crypto/x509/x_val.c
index 26200ee..ad4f7e1 100644
--- a/src/crypto/x509/x_val.c
+++ b/src/crypto/x509/x_val.c
@@ -62,8 +62,8 @@
 
 
 ASN1_SEQUENCE(X509_VAL) = {
-	ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
-	ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+        ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+        ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
 } ASN1_SEQUENCE_END(X509_VAL)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index 7bbe4f3..f12140f 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -67,20 +67,19 @@
 
 #include "../internal.h"
 
-
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
-	ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
-	ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
-	ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
-	ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
-	ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
-	ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
-	ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
-	ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
-	ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
-	ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+        ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+        ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
+        ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+        ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
+        ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+        ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+        ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+        ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+        ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
 } ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
@@ -89,139 +88,149 @@
 extern void policy_cache_free(X509_POLICY_CACHE *cache);
 
 static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-								void *exarg)
+                   void *exarg)
 {
-	X509 *ret = (X509 *)*pval;
+    X509 *ret = (X509 *)*pval;
 
-	switch(operation) {
+    switch (operation) {
 
-		case ASN1_OP_NEW_POST:
-		ret->valid=0;
-		ret->name = NULL;
-		ret->ex_flags = 0;
-		ret->ex_pathlen = -1;
-		ret->skid = NULL;
-		ret->akid = NULL;
-		ret->aux = NULL;
-		ret->crldp = NULL;
-		CRYPTO_new_ex_data(&ret->ex_data);
-		break;
+    case ASN1_OP_NEW_POST:
+        ret->valid = 0;
+        ret->name = NULL;
+        ret->ex_flags = 0;
+        ret->ex_pathlen = -1;
+        ret->skid = NULL;
+        ret->akid = NULL;
+        ret->aux = NULL;
+        ret->crldp = NULL;
+        CRYPTO_new_ex_data(&ret->ex_data);
+        break;
 
-		case ASN1_OP_D2I_POST:
-		if (ret->name != NULL) OPENSSL_free(ret->name);
-		ret->name=X509_NAME_oneline(ret->cert_info->subject,NULL,0);
-		break;
+    case ASN1_OP_D2I_POST:
+        if (ret->name != NULL)
+            OPENSSL_free(ret->name);
+        ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
+        break;
 
-		case ASN1_OP_FREE_POST:
-		CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
-		X509_CERT_AUX_free(ret->aux);
-		ASN1_OCTET_STRING_free(ret->skid);
-		AUTHORITY_KEYID_free(ret->akid);
-		CRL_DIST_POINTS_free(ret->crldp);
-		policy_cache_free(ret->policy_cache);
-		GENERAL_NAMES_free(ret->altname);
-		NAME_CONSTRAINTS_free(ret->nc);
+    case ASN1_OP_FREE_POST:
+        CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
+        X509_CERT_AUX_free(ret->aux);
+        ASN1_OCTET_STRING_free(ret->skid);
+        AUTHORITY_KEYID_free(ret->akid);
+        CRL_DIST_POINTS_free(ret->crldp);
+        policy_cache_free(ret->policy_cache);
+        GENERAL_NAMES_free(ret->altname);
+        NAME_CONSTRAINTS_free(ret->nc);
 
-		if (ret->name != NULL) OPENSSL_free(ret->name);
-		break;
+        if (ret->name != NULL)
+            OPENSSL_free(ret->name);
+        break;
 
-	}
+    }
 
-	return 1;
+    return 1;
 
 }
 
 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)
+        ASN1_SIMPLE(X509, cert_info, X509_CINF),
+        ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
+        ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END_ref(X509, X509)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509)
+
 IMPLEMENT_ASN1_DUP_FUNCTION(X509)
 
 X509 *X509_up_ref(X509 *x)
-	{
-	CRYPTO_refcount_inc(&x->references);
-	return x;
-	}
+{
+    CRYPTO_refcount_inc(&x->references);
+    return x;
+}
 
-int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
-        {
-	int index;
-	if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-			dup_func, free_func))
-		{
-		return -1;
-		}
-	return index;
-        }
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused,
+                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+    int index;
+    if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
+                                 dup_func, free_func)) {
+        return -1;
+    }
+    return index;
+}
 
 int X509_set_ex_data(X509 *r, int idx, void *arg)
-	{
-	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
-	}
+{
+    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
 
 void *X509_get_ex_data(X509 *r, int idx)
-	{
-	return(CRYPTO_get_ex_data(&r->ex_data,idx));
-	}
+{
+    return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
 
-/* X509_AUX ASN1 routines. X509_AUX is the name given to
- * a certificate with extra info tagged on the end. Since these
- * functions set how a certificate is trusted they should only
- * be used when the certificate comes from a reliable source
- * such as local storage.
- *
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
  */
 
 X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
 {
-	const unsigned char *q = *pp;
-	X509 *ret;
-	int freeret = 0;
+    const unsigned char *q = *pp;
+    X509 *ret;
+    int freeret = 0;
 
-	if (!a || *a == NULL)
-		freeret = 1;
-	ret = d2i_X509(a, &q, length);
-	/* If certificate unreadable then forget it */
-	if(!ret) return NULL;
-	/* update length */
-	length -= q - *pp;
-	/* Parse auxiliary information if there is any. */
-	if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
-		goto err;
-	*pp = q;
-	return ret;
-	err:
-	if (freeret)
-		{
-		X509_free(ret);
-		if (a)
-			*a = NULL;
-		}
-	return NULL;
+    if (!a || *a == NULL)
+        freeret = 1;
+    ret = d2i_X509(a, &q, length);
+    /* If certificate unreadable then forget it */
+    if (!ret)
+        return NULL;
+    /* update length */
+    length -= q - *pp;
+    /* Parse auxiliary information if there is any. */
+    if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+        goto err;
+    *pp = q;
+    return ret;
+ err:
+    if (freeret) {
+        X509_free(ret);
+        if (a)
+            *a = NULL;
+    }
+    return NULL;
 }
 
 int i2d_X509_AUX(X509 *a, unsigned char **pp)
 {
-	int length;
-	length = i2d_X509(a, pp);
-	if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
-	return length;
+    int length, tmplen;
+    length = i2d_X509(a, pp);
+    if (length < 0 || a == NULL) {
+        return length;
+    }
+
+    tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+    if (tmplen < 0) {
+        return tmplen;
+    }
+    length += tmplen;
+
+    return length;
 }
 
 void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
-				const X509 *x)
-	{
-	if (psig)
-		*psig = x->signature;
-	if (palg)
-		*palg = x->sig_alg;
-	}
+                         const X509 *x)
+{
+    if (psig)
+        *psig = x->signature;
+    if (palg)
+        *palg = x->sig_alg;
+}
 
 int X509_get_signature_nid(const X509 *x)
-	{
-	return OBJ_obj2nid(x->sig_alg->algorithm);
-	}
+{
+    return OBJ_obj2nid(x->sig_alg->algorithm);
+}
diff --git a/src/crypto/x509/x_x509a.c b/src/crypto/x509/x_x509a.c
index fb7172b..a63ee42 100644
--- a/src/crypto/x509/x_x509a.c
+++ b/src/crypto/x509/x_x509a.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -59,139 +61,145 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
-
-/* X509_CERT_AUX routines. These are used to encode additional
- * user modifiable data about a certificate. This data is
- * appended to the X509 encoding when the *_X509_AUX routines
- * are used. This means that the "traditional" X509 routines
- * will simply ignore the extra data. */
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
 
 static X509_CERT_AUX *aux_get(X509 *x);
 
 ASN1_SEQUENCE(X509_CERT_AUX) = {
-	ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
-	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
-	ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
-	ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
-	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+        ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+        ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+        ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+        ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+        ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
 } ASN1_SEQUENCE_END(X509_CERT_AUX)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
 
 static X509_CERT_AUX *aux_get(X509 *x)
 {
-	if(!x) return NULL;
-	if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
-	return x->aux;
+    if (!x)
+        return NULL;
+    if (!x->aux && !(x->aux = X509_CERT_AUX_new()))
+        return NULL;
+    return x->aux;
 }
 
 int X509_alias_set1(X509 *x, unsigned char *name, int len)
 {
-	X509_CERT_AUX *aux;
-	if (!name)
-		{
-		if (!x || !x->aux || !x->aux->alias)
-			return 1;
-		ASN1_UTF8STRING_free(x->aux->alias);
-		x->aux->alias = NULL;
-		return 1;
-		}
-	if(!(aux = aux_get(x))) return 0;
-	if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
-	return ASN1_STRING_set(aux->alias, name, len);
+    X509_CERT_AUX *aux;
+    if (!name) {
+        if (!x || !x->aux || !x->aux->alias)
+            return 1;
+        ASN1_UTF8STRING_free(x->aux->alias);
+        x->aux->alias = NULL;
+        return 1;
+    }
+    if (!(aux = aux_get(x)))
+        return 0;
+    if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new()))
+        return 0;
+    return ASN1_STRING_set(aux->alias, name, len);
 }
 
 int X509_keyid_set1(X509 *x, unsigned char *id, int len)
 {
-	X509_CERT_AUX *aux;
-	if (!id)
-		{
-		if (!x || !x->aux || !x->aux->keyid)
-			return 1;
-		ASN1_OCTET_STRING_free(x->aux->keyid);
-		x->aux->keyid = NULL;
-		return 1;
-		}
-	if(!(aux = aux_get(x))) return 0;
-	if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
-	return ASN1_STRING_set(aux->keyid, id, len);
+    X509_CERT_AUX *aux;
+    if (!id) {
+        if (!x || !x->aux || !x->aux->keyid)
+            return 1;
+        ASN1_OCTET_STRING_free(x->aux->keyid);
+        x->aux->keyid = NULL;
+        return 1;
+    }
+    if (!(aux = aux_get(x)))
+        return 0;
+    if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new()))
+        return 0;
+    return ASN1_STRING_set(aux->keyid, id, len);
 }
 
 unsigned char *X509_alias_get0(X509 *x, int *len)
 {
-	if(!x->aux || !x->aux->alias) return NULL;
-	if(len) *len = x->aux->alias->length;
-	return x->aux->alias->data;
+    if (!x->aux || !x->aux->alias)
+        return NULL;
+    if (len)
+        *len = x->aux->alias->length;
+    return x->aux->alias->data;
 }
 
 unsigned char *X509_keyid_get0(X509 *x, int *len)
 {
-	if(!x->aux || !x->aux->keyid) return NULL;
-	if(len) *len = x->aux->keyid->length;
-	return x->aux->keyid->data;
+    if (!x->aux || !x->aux->keyid)
+        return NULL;
+    if (len)
+        *len = x->aux->keyid->length;
+    return x->aux->keyid->data;
 }
 
 int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
 {
-	ASN1_OBJECT *objtmp = OBJ_dup(obj);
-	if (objtmp == NULL)
-		goto err;
-	X509_CERT_AUX *aux = aux_get(x);
-	if (aux->trust == NULL)
-		{
-		aux->trust = sk_ASN1_OBJECT_new_null();
-		if (aux->trust == NULL)
-			goto err;
-		}
-	if (!sk_ASN1_OBJECT_push(aux->trust, objtmp))
-		goto err;
-	return 1;
+    ASN1_OBJECT *objtmp = OBJ_dup(obj);
+    if (objtmp == NULL)
+        goto err;
+    X509_CERT_AUX *aux = aux_get(x);
+    if (aux->trust == NULL) {
+        aux->trust = sk_ASN1_OBJECT_new_null();
+        if (aux->trust == NULL)
+            goto err;
+    }
+    if (!sk_ASN1_OBJECT_push(aux->trust, objtmp))
+        goto err;
+    return 1;
 
-err:
-	ASN1_OBJECT_free(objtmp);
-	return 0;
+ err:
+    ASN1_OBJECT_free(objtmp);
+    return 0;
 }
 
 int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
 {
-	ASN1_OBJECT *objtmp = OBJ_dup(obj);
-	if (objtmp == NULL)
-		goto err;
-	X509_CERT_AUX *aux = aux_get(x);
-	if (aux->reject == NULL)
-		{
-		aux->reject = sk_ASN1_OBJECT_new_null();
-		if (aux->reject == NULL)
-			goto err;
-		}
-	if (!sk_ASN1_OBJECT_push(aux->reject, objtmp))
-		goto err;
-	return 1;
+    ASN1_OBJECT *objtmp = OBJ_dup(obj);
+    if (objtmp == NULL)
+        goto err;
+    X509_CERT_AUX *aux = aux_get(x);
+    if (aux->reject == NULL) {
+        aux->reject = sk_ASN1_OBJECT_new_null();
+        if (aux->reject == NULL)
+            goto err;
+    }
+    if (!sk_ASN1_OBJECT_push(aux->reject, objtmp))
+        goto err;
+    return 1;
 
-err:
-	ASN1_OBJECT_free(objtmp);
-	return 0;
+ err:
+    ASN1_OBJECT_free(objtmp);
+    return 0;
 }
 
 void X509_trust_clear(X509 *x)
 {
-	if(x->aux && x->aux->trust) {
-		sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
-		x->aux->trust = NULL;
-	}
+    if (x->aux && x->aux->trust) {
+        sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+        x->aux->trust = NULL;
+    }
 }
 
 void X509_reject_clear(X509 *x)
 {
-	if(x->aux && x->aux->reject) {
-		sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
-		x->aux->reject = NULL;
-	}
+    if (x->aux && x->aux->reject) {
+        sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+        x->aux->reject = NULL;
+    }
 }
 
 ASN1_SEQUENCE(X509_CERT_PAIR) = {
-	ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
-	ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
+        ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
+        ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
 } ASN1_SEQUENCE_END(X509_CERT_PAIR)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)
diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h
index f1fb8ef..9ece19c 100644
--- a/src/crypto/x509v3/ext_dat.h
+++ b/src/crypto/x509v3/ext_dat.h
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
@@ -9,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -56,74 +57,79 @@
 /* This file contains a table of "standard" extensions */
 
 extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
-extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
-extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
+extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info,
+    v3_sinfo;
+extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id,
+    v3_akey_id;
 extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
-extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
-extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
-extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
+extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld,
+    v3_freshest_crl;
+extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp,
+    v3_ocsp_acutoff;
+extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck,
+    v3_ocsp_serviceloc;
 extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci;
 extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
 extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
 extern const X509V3_EXT_METHOD v3_addr, v3_asid;
 
-/* This table will be searched using OBJ_bsearch so it *must* kept in
- * order of the ext_nid values.
+/*
+ * This table will be searched using OBJ_bsearch so it *must* kept in order
+ * of the ext_nid values.
  */
 
 /* TODO(fork): OCSP support */
 #define OPENSSL_NO_OCSP
 
 static const X509V3_EXT_METHOD *const standard_exts[] = {
-&v3_nscert,
-&v3_ns_ia5_list[0],
-&v3_ns_ia5_list[1],
-&v3_ns_ia5_list[2],
-&v3_ns_ia5_list[3],
-&v3_ns_ia5_list[4],
-&v3_ns_ia5_list[5],
-&v3_ns_ia5_list[6],
-&v3_skey_id,
-&v3_key_usage,
-&v3_pkey_usage_period,
-&v3_alt[0],
-&v3_alt[1],
-&v3_bcons,
-&v3_crl_num,
-&v3_cpols,
-&v3_akey_id,
-&v3_crld,
-&v3_ext_ku,
-&v3_delta_crl,
-&v3_crl_reason,
+    &v3_nscert,
+    &v3_ns_ia5_list[0],
+    &v3_ns_ia5_list[1],
+    &v3_ns_ia5_list[2],
+    &v3_ns_ia5_list[3],
+    &v3_ns_ia5_list[4],
+    &v3_ns_ia5_list[5],
+    &v3_ns_ia5_list[6],
+    &v3_skey_id,
+    &v3_key_usage,
+    &v3_pkey_usage_period,
+    &v3_alt[0],
+    &v3_alt[1],
+    &v3_bcons,
+    &v3_crl_num,
+    &v3_cpols,
+    &v3_akey_id,
+    &v3_crld,
+    &v3_ext_ku,
+    &v3_delta_crl,
+    &v3_crl_reason,
 #ifndef OPENSSL_NO_OCSP
-&v3_crl_invdate,
+    &v3_crl_invdate,
 #endif
-&v3_sxnet,
-&v3_info,
+    &v3_sxnet,
+    &v3_info,
 #ifndef OPENSSL_NO_OCSP
-&v3_ocsp_nonce,
-&v3_ocsp_crlid,
-&v3_ocsp_accresp,
-&v3_ocsp_nocheck,
-&v3_ocsp_acutoff,
-&v3_ocsp_serviceloc,
+    &v3_ocsp_nonce,
+    &v3_ocsp_crlid,
+    &v3_ocsp_accresp,
+    &v3_ocsp_nocheck,
+    &v3_ocsp_acutoff,
+    &v3_ocsp_serviceloc,
 #endif
-&v3_sinfo,
-&v3_policy_constraints,
+    &v3_sinfo,
+    &v3_policy_constraints,
 #ifndef OPENSSL_NO_OCSP
-&v3_crl_hold,
+    &v3_crl_hold,
 #endif
-&v3_pci,
-&v3_name_constraints,
-&v3_policy_mappings,
-&v3_inhibit_anyp,
-&v3_idp,
-&v3_alt[2],
-&v3_freshest_crl,
+    &v3_pci,
+    &v3_name_constraints,
+    &v3_policy_mappings,
+    &v3_inhibit_anyp,
+    &v3_idp,
+    &v3_alt[2],
+    &v3_freshest_crl,
 };
 
 /* Number of standard extensions */
 
 #define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
-
diff --git a/src/crypto/x509v3/pcy_cache.c b/src/crypto/x509v3/pcy_cache.c
index 08f20aa..f1e512e 100644
--- a/src/crypto/x509v3/pcy_cache.c
+++ b/src/crypto/x509v3/pcy_cache.c
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -9,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -62,238 +63,222 @@
 #include "pcy_int.h"
 #include "../internal.h"
 
-
 static int policy_data_cmp(const X509_POLICY_DATA **a,
-				const X509_POLICY_DATA **b);
+                           const X509_POLICY_DATA **b);
 static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
 
-/* Set cache entry according to CertificatePolicies extension.
- * Note: this destroys the passed CERTIFICATEPOLICIES structure.
+/*
+ * Set cache entry according to CertificatePolicies extension. Note: this
+ * destroys the passed CERTIFICATEPOLICIES structure.
  */
 
 static int policy_cache_create(X509 *x,
-			CERTIFICATEPOLICIES *policies, int crit)
-	{
-	size_t i;
-	int ret = 0;
-	X509_POLICY_CACHE *cache = x->policy_cache;
-	X509_POLICY_DATA *data = NULL;
-	POLICYINFO *policy;
-	if (sk_POLICYINFO_num(policies) == 0)
-		goto bad_policy;
-	cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
-	if (!cache->data)
-		goto bad_policy;
-	for (i = 0; i < sk_POLICYINFO_num(policies); i++)
-		{
-		policy = sk_POLICYINFO_value(policies, i);
-		data = policy_data_new(policy, NULL, crit);
-		if (!data)
-			goto bad_policy;
-		/* Duplicate policy OIDs are illegal: reject if matches
-		 * found.
-		 */
-		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
-			{
-			if (cache->anyPolicy)
-				{
-				ret = -1;
-				goto bad_policy;
-				}
-			cache->anyPolicy = data;
-			}
-		else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data))
-			{
-			ret = -1;
-			goto bad_policy;
-			}
-		else if (!sk_X509_POLICY_DATA_push(cache->data, data))
-			goto bad_policy;
-		data = NULL;
-		}
-	ret = 1;
-	bad_policy:
-	if (ret == -1)
-		x->ex_flags |= EXFLAG_INVALID_POLICY;
-	if (data)
-		policy_data_free(data);
-	sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
-	if (ret <= 0)
-		{
-		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
-		cache->data = NULL;
-		}
-	return ret;
-	}
+                               CERTIFICATEPOLICIES *policies, int crit)
+{
+    size_t i;
+    int ret = 0;
+    X509_POLICY_CACHE *cache = x->policy_cache;
+    X509_POLICY_DATA *data = NULL;
+    POLICYINFO *policy;
+    if (sk_POLICYINFO_num(policies) == 0)
+        goto bad_policy;
+    cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
+    if (!cache->data)
+        goto bad_policy;
+    for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
+        policy = sk_POLICYINFO_value(policies, i);
+        data = policy_data_new(policy, NULL, crit);
+        if (!data)
+            goto bad_policy;
+        /*
+         * Duplicate policy OIDs are illegal: reject if matches found.
+         */
+        if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+            if (cache->anyPolicy) {
+                ret = -1;
+                goto bad_policy;
+            }
+            cache->anyPolicy = data;
+        } else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data)) {
+            ret = -1;
+            goto bad_policy;
+        } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+            goto bad_policy;
+        data = NULL;
+    }
+    ret = 1;
+ bad_policy:
+    if (ret == -1)
+        x->ex_flags |= EXFLAG_INVALID_POLICY;
+    if (data)
+        policy_data_free(data);
+    sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+    if (ret <= 0) {
+        sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+        cache->data = NULL;
+    }
+    return ret;
+}
 
-	
 static int policy_cache_new(X509 *x)
-	{
-	X509_POLICY_CACHE *cache;
-	ASN1_INTEGER *ext_any = NULL;
-	POLICY_CONSTRAINTS *ext_pcons = NULL;
-	CERTIFICATEPOLICIES *ext_cpols = NULL;
-	POLICY_MAPPINGS *ext_pmaps = NULL;
-	int i;
-	cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
-	if (!cache)
-		return 0;
-	cache->anyPolicy = NULL;
-	cache->data = NULL;
-	cache->any_skip = -1;
-	cache->explicit_skip = -1;
-	cache->map_skip = -1;
+{
+    X509_POLICY_CACHE *cache;
+    ASN1_INTEGER *ext_any = NULL;
+    POLICY_CONSTRAINTS *ext_pcons = NULL;
+    CERTIFICATEPOLICIES *ext_cpols = NULL;
+    POLICY_MAPPINGS *ext_pmaps = NULL;
+    int i;
+    cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
+    if (!cache)
+        return 0;
+    cache->anyPolicy = NULL;
+    cache->data = NULL;
+    cache->any_skip = -1;
+    cache->explicit_skip = -1;
+    cache->map_skip = -1;
 
-	x->policy_cache = cache;
+    x->policy_cache = cache;
 
-	/* Handle requireExplicitPolicy *first*. Need to process this
-	 * even if we don't have any policies.
-	 */
-	ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
+    /*
+     * Handle requireExplicitPolicy *first*. Need to process this even if we
+     * don't have any policies.
+     */
+    ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
 
-	if (!ext_pcons)
-		{
-		if (i != -1)
-			goto bad_cache;
-		}
-	else
-		{
-		if (!ext_pcons->requireExplicitPolicy
-			&& !ext_pcons->inhibitPolicyMapping)
-			goto bad_cache;
-		if (!policy_cache_set_int(&cache->explicit_skip,
-			ext_pcons->requireExplicitPolicy))
-			goto bad_cache;
-		if (!policy_cache_set_int(&cache->map_skip,
-			ext_pcons->inhibitPolicyMapping))
-			goto bad_cache;
-		}
+    if (!ext_pcons) {
+        if (i != -1)
+            goto bad_cache;
+    } else {
+        if (!ext_pcons->requireExplicitPolicy
+            && !ext_pcons->inhibitPolicyMapping)
+            goto bad_cache;
+        if (!policy_cache_set_int(&cache->explicit_skip,
+                                  ext_pcons->requireExplicitPolicy))
+            goto bad_cache;
+        if (!policy_cache_set_int(&cache->map_skip,
+                                  ext_pcons->inhibitPolicyMapping))
+            goto bad_cache;
+    }
 
-	/* Process CertificatePolicies */
+    /* Process CertificatePolicies */
 
-	ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
-	/* If no CertificatePolicies extension or problem decoding then
-	 * there is no point continuing because the valid policies will be
-	 * NULL.
-	 */
-	if (!ext_cpols)
-		{
-		/* If not absent some problem with extension */
-		if (i != -1)
-			goto bad_cache;
-		return 1;
-		}
+    ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
+    /*
+     * If no CertificatePolicies extension or problem decoding then there is
+     * no point continuing because the valid policies will be NULL.
+     */
+    if (!ext_cpols) {
+        /* If not absent some problem with extension */
+        if (i != -1)
+            goto bad_cache;
+        return 1;
+    }
 
-	i = policy_cache_create(x, ext_cpols, i);
+    i = policy_cache_create(x, ext_cpols, i);
 
-	/* NB: ext_cpols freed by policy_cache_set_policies */
+    /* NB: ext_cpols freed by policy_cache_set_policies */
 
-	if (i <= 0)
-		return i;
+    if (i <= 0)
+        return i;
 
-	ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+    ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
 
-	if (!ext_pmaps)
-		{
-		/* If not absent some problem with extension */
-		if (i != -1)
-			goto bad_cache;
-		}
-	else
-		{
-		i = policy_cache_set_mapping(x, ext_pmaps);
-		if (i <= 0)
-			goto bad_cache;
-		}
+    if (!ext_pmaps) {
+        /* If not absent some problem with extension */
+        if (i != -1)
+            goto bad_cache;
+    } else {
+        i = policy_cache_set_mapping(x, ext_pmaps);
+        if (i <= 0)
+            goto bad_cache;
+    }
 
-	ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
+    ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
 
-	if (!ext_any)
-		{
-		if (i != -1)
-			goto bad_cache;
-		}
-	else if (!policy_cache_set_int(&cache->any_skip, ext_any))
-			goto bad_cache;
+    if (!ext_any) {
+        if (i != -1)
+            goto bad_cache;
+    } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+        goto bad_cache;
 
-	if (0)
-		{
-		bad_cache:
-		x->ex_flags |= EXFLAG_INVALID_POLICY;
-		}
+    if (0) {
+ bad_cache:
+        x->ex_flags |= EXFLAG_INVALID_POLICY;
+    }
 
-	if(ext_pcons)
-		POLICY_CONSTRAINTS_free(ext_pcons);
+    if (ext_pcons)
+        POLICY_CONSTRAINTS_free(ext_pcons);
 
-	if (ext_any)
-		ASN1_INTEGER_free(ext_any);
+    if (ext_any)
+        ASN1_INTEGER_free(ext_any);
 
-	return 1;
+    return 1;
 
-	
 }
 
 void policy_cache_free(X509_POLICY_CACHE *cache)
-	{
-	if (!cache)
-		return;
-	if (cache->anyPolicy)
-		policy_data_free(cache->anyPolicy);
-	if (cache->data)
-		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
-	OPENSSL_free(cache);
-	}
+{
+    if (!cache)
+        return;
+    if (cache->anyPolicy)
+        policy_data_free(cache->anyPolicy);
+    if (cache->data)
+        sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+    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. */
+/*
+ * 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;
+{
+    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);
+    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;
+    if (cache != NULL)
+        return cache;
 
-	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
-	if (x->policy_cache == NULL)
-		policy_cache_new(x);
-	cache = x->policy_cache;
-	CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+    CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
+    if (x->policy_cache == NULL)
+        policy_cache_new(x);
+    cache = x->policy_cache;
+    CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
 
-	return cache;
-	}
+    return cache;
+}
 
 X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
-						const ASN1_OBJECT *id)
-	{
-	size_t idx;
-	X509_POLICY_DATA tmp;
+                                         const ASN1_OBJECT *id)
+{
+    size_t idx;
+    X509_POLICY_DATA tmp;
 
-	tmp.valid_policy = (ASN1_OBJECT *)id;
-	if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
-		return NULL;
-	return sk_X509_POLICY_DATA_value(cache->data, idx);
-	}
+    tmp.valid_policy = (ASN1_OBJECT *)id;
+    if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
+        return NULL;
+    return sk_X509_POLICY_DATA_value(cache->data, idx);
+}
 
 static int policy_data_cmp(const X509_POLICY_DATA **a,
-				const X509_POLICY_DATA **b)
-	{
-	return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
-	}
+                           const X509_POLICY_DATA **b)
+{
+    return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
+}
 
 static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
-	{
-	if (value == NULL)
-		return 1;
-	if (value->type == V_ASN1_NEG_INTEGER)
-		return 0;
-	*out = ASN1_INTEGER_get(value);
-	return 1;
-	}
+{
+    if (value == NULL)
+        return 1;
+    if (value->type == V_ASN1_NEG_INTEGER)
+        return 0;
+    *out = ASN1_INTEGER_get(value);
+    return 1;
+}
diff --git a/src/crypto/x509v3/pcy_data.c b/src/crypto/x509v3/pcy_data.c
index cd45dca..498de4d 100644
--- a/src/crypto/x509v3/pcy_data.c
+++ b/src/crypto/x509v3/pcy_data.c
@@ -1,6 +1,7 @@
 /* pcy_data.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -63,75 +64,67 @@
 
 #include "pcy_int.h"
 
-
 /* Policy Node routines */
 
 void policy_data_free(X509_POLICY_DATA *data)
-	{
-	ASN1_OBJECT_free(data->valid_policy);
-	/* Don't free qualifiers if shared */
-	if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
-		sk_POLICYQUALINFO_pop_free(data->qualifier_set,
-					POLICYQUALINFO_free);
-	sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
-	OPENSSL_free(data);
-	}
+{
+    ASN1_OBJECT_free(data->valid_policy);
+    /* Don't free qualifiers if shared */
+    if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
+        sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free);
+    sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
+    OPENSSL_free(data);
+}
 
-/* Create a data based on an existing policy. If 'id' is NULL use the
- * oid in the policy, otherwise use 'id'. This behaviour covers the two
- * types of data in RFC3280: data with from a CertificatePolcies extension
- * and additional data with just the qualifiers of anyPolicy and ID from
- * another source.
+/*
+ * Create a data based on an existing policy. If 'id' is NULL use the oid in
+ * the policy, otherwise use 'id'. This behaviour covers the two types of
+ * data in RFC3280: data with from a CertificatePolcies extension and
+ * additional data with just the qualifiers of anyPolicy and ID from another
+ * source.
  */
 
 X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
-					const ASN1_OBJECT *cid, int crit)
-	{
-	X509_POLICY_DATA *ret;
-	ASN1_OBJECT *id;
-	if (!policy && !cid)
-		return NULL;
-	if (cid)
-		{
-		id = OBJ_dup(cid);
-		if (!id)
-			return NULL;
-		}
-	else
-		id = NULL;
-	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
-	if (!ret)
-		return NULL;
-	ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
-	if (!ret->expected_policy_set)
-		{
-		OPENSSL_free(ret);
-		if (id)
-			ASN1_OBJECT_free(id);
-		return NULL;
-		}
+                                  const ASN1_OBJECT *cid, int crit)
+{
+    X509_POLICY_DATA *ret;
+    ASN1_OBJECT *id;
+    if (!policy && !cid)
+        return NULL;
+    if (cid) {
+        id = OBJ_dup(cid);
+        if (!id)
+            return NULL;
+    } else
+        id = NULL;
+    ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
+    if (!ret)
+        return NULL;
+    ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
+    if (!ret->expected_policy_set) {
+        OPENSSL_free(ret);
+        if (id)
+            ASN1_OBJECT_free(id);
+        return NULL;
+    }
 
-	if (crit)
-		ret->flags = POLICY_DATA_FLAG_CRITICAL;
-	else
-		ret->flags = 0;
+    if (crit)
+        ret->flags = POLICY_DATA_FLAG_CRITICAL;
+    else
+        ret->flags = 0;
 
-	if (id)
-		ret->valid_policy = id;
-	else
-		{
-		ret->valid_policy = policy->policyid;
-		policy->policyid = NULL;
-		}
+    if (id)
+        ret->valid_policy = id;
+    else {
+        ret->valid_policy = policy->policyid;
+        policy->policyid = NULL;
+    }
 
-	if (policy)
-		{
-		ret->qualifier_set = policy->qualifiers;
-		policy->qualifiers = NULL;
-		}
-	else
-		ret->qualifier_set = NULL;
+    if (policy) {
+        ret->qualifier_set = policy->qualifiers;
+        policy->qualifiers = NULL;
+    } else
+        ret->qualifier_set = NULL;
 
-	return ret;
-	}
-
+    return ret;
+}
diff --git a/src/crypto/x509v3/pcy_int.h b/src/crypto/x509v3/pcy_int.h
index ccff928..b5075f9 100644
--- a/src/crypto/x509v3/pcy_int.h
+++ b/src/crypto/x509v3/pcy_int.h
@@ -1,6 +1,7 @@
 /* pcy_int.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -56,121 +57,126 @@
  *
  */
 
-
 typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
 
 DECLARE_STACK_OF(X509_POLICY_DATA)
 
 /* Internal structures */
 
-/* This structure and the field names correspond to the Policy 'node' of
- * RFC3280. NB this structure contains no pointers to parent or child
- * data: X509_POLICY_NODE contains that. This means that the main policy data
- * can be kept static and cached with the certificate.
+/*
+ * This structure and the field names correspond to the Policy 'node' of
+ * RFC3280. NB this structure contains no pointers to parent or child data:
+ * X509_POLICY_NODE contains that. This means that the main policy data can
+ * be kept static and cached with the certificate.
  */
 
-struct X509_POLICY_DATA_st
-	{
-	unsigned int flags;
-	/* Policy OID and qualifiers for this data */
-	ASN1_OBJECT *valid_policy;
-	STACK_OF(POLICYQUALINFO) *qualifier_set;
-	STACK_OF(ASN1_OBJECT) *expected_policy_set;
-	};
+struct X509_POLICY_DATA_st {
+    unsigned int flags;
+    /* Policy OID and qualifiers for this data */
+    ASN1_OBJECT *valid_policy;
+    STACK_OF(POLICYQUALINFO) *qualifier_set;
+    STACK_OF(ASN1_OBJECT) *expected_policy_set;
+};
 
 /* X509_POLICY_DATA flags values */
 
-/* This flag indicates the structure has been mapped using a policy mapping
- * extension. If policy mapping is not active its references get deleted. 
+/*
+ * This flag indicates the structure has been mapped using a policy mapping
+ * extension. If policy mapping is not active its references get deleted.
  */
 
-#define POLICY_DATA_FLAG_MAPPED			0x1
+#define POLICY_DATA_FLAG_MAPPED                 0x1
 
-/* This flag indicates the data doesn't correspond to a policy in Certificate
+/*
+ * This flag indicates the data doesn't correspond to a policy in Certificate
  * Policies: it has been mapped to any policy.
  */
 
-#define POLICY_DATA_FLAG_MAPPED_ANY		0x2
+#define POLICY_DATA_FLAG_MAPPED_ANY             0x2
 
 /* AND with flags to see if any mapping has occurred */
 
-#define POLICY_DATA_FLAG_MAP_MASK		0x3
+#define POLICY_DATA_FLAG_MAP_MASK               0x3
 
 /* qualifiers are shared and shouldn't be freed */
 
-#define POLICY_DATA_FLAG_SHARED_QUALIFIERS	0x4
+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS      0x4
 
 /* Parent node is an extra node and should be freed */
 
-#define POLICY_DATA_FLAG_EXTRA_NODE		0x8
+#define POLICY_DATA_FLAG_EXTRA_NODE             0x8
 
 /* Corresponding CertificatePolicies is critical */
 
-#define POLICY_DATA_FLAG_CRITICAL		0x10
+#define POLICY_DATA_FLAG_CRITICAL               0x10
 
 /* This structure is cached with a certificate */
 
 struct X509_POLICY_CACHE_st {
-	/* anyPolicy data or NULL if no anyPolicy */
-	X509_POLICY_DATA *anyPolicy;
-	/* other policy data */
-	STACK_OF(X509_POLICY_DATA) *data;
-	/* If InhibitAnyPolicy present this is its value or -1 if absent. */
-	long any_skip;
-	/* If policyConstraints and requireExplicitPolicy present this is its
-	 * value or -1 if absent.
-	 */
-	long explicit_skip;
-	/* If policyConstraints and policyMapping present this is its
-	 * value or -1 if absent.
-         */
-	long map_skip;
-	};
+    /* anyPolicy data or NULL if no anyPolicy */
+    X509_POLICY_DATA *anyPolicy;
+    /* other policy data */
+    STACK_OF(X509_POLICY_DATA) *data;
+    /* If InhibitAnyPolicy present this is its value or -1 if absent. */
+    long any_skip;
+    /*
+     * If policyConstraints and requireExplicitPolicy present this is its
+     * value or -1 if absent.
+     */
+    long explicit_skip;
+    /*
+     * If policyConstraints and policyMapping present this is its value or -1
+     * if absent.
+     */
+    long map_skip;
+};
 
-/*#define POLICY_CACHE_FLAG_CRITICAL		POLICY_DATA_FLAG_CRITICAL*/
+/*
+ * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
+ */
 
 /* This structure represents the relationship between nodes */
 
-struct X509_POLICY_NODE_st
-	{
-	/* node data this refers to */
-	const X509_POLICY_DATA *data;
-	/* Parent node */
-	X509_POLICY_NODE *parent;
-	/* Number of child nodes */
-	int nchild;
-	};
+struct X509_POLICY_NODE_st {
+    /* node data this refers to */
+    const X509_POLICY_DATA *data;
+    /* Parent node */
+    X509_POLICY_NODE *parent;
+    /* Number of child nodes */
+    int nchild;
+};
 
-struct X509_POLICY_LEVEL_st
-	{
-	/* Cert for this level */
-	X509 *cert;
-	/* nodes at this level */
-	STACK_OF(X509_POLICY_NODE) *nodes;
-	/* anyPolicy node */
-	X509_POLICY_NODE *anyPolicy;
-	/* Extra data */
-	/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
-	unsigned int flags;
-	};
+struct X509_POLICY_LEVEL_st {
+    /* Cert for this level */
+    X509 *cert;
+    /* nodes at this level */
+    STACK_OF(X509_POLICY_NODE) *nodes;
+    /* anyPolicy node */
+    X509_POLICY_NODE *anyPolicy;
+    /* Extra data */
+    /*
+     * STACK_OF(X509_POLICY_DATA) *extra_data;
+     */
+    unsigned int flags;
+};
 
-struct X509_POLICY_TREE_st
-	{
-	/* This is the tree 'level' data */
-	X509_POLICY_LEVEL *levels;
-	int nlevel;
-	/* Extra policy data when additional nodes (not from the certificate)
-	 * are required.
-	 */
-	STACK_OF(X509_POLICY_DATA) *extra_data;
-	/* This is the authority constained policy set */
-	STACK_OF(X509_POLICY_NODE) *auth_policies;
-	STACK_OF(X509_POLICY_NODE) *user_policies;
-	unsigned int flags;
-	};
+struct X509_POLICY_TREE_st {
+    /* This is the tree 'level' data */
+    X509_POLICY_LEVEL *levels;
+    int nlevel;
+    /*
+     * Extra policy data when additional nodes (not from the certificate) are
+     * required.
+     */
+    STACK_OF(X509_POLICY_DATA) *extra_data;
+    /* This is the authority constained policy set */
+    STACK_OF(X509_POLICY_NODE) *auth_policies;
+    STACK_OF(X509_POLICY_NODE) *user_policies;
+    unsigned int flags;
+};
 
 /* Set if anyPolicy present in user policies */
-#define POLICY_FLAG_ANY_POLICY		0x2
+#define POLICY_FLAG_ANY_POLICY          0x2
 
 /* Useful macros */
 
@@ -180,14 +186,13 @@
 /* Internal functions */
 
 X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
-								int crit);
+                                  int crit);
 void policy_data_free(X509_POLICY_DATA *data);
 
 X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
-							const ASN1_OBJECT *id);
+                                         const ASN1_OBJECT *id);
 int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
 
-
 STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
 
 void policy_cache_init(void);
@@ -195,18 +200,18 @@
 void policy_cache_free(X509_POLICY_CACHE *cache);
 
 X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
-					const X509_POLICY_NODE *parent,	
-					const ASN1_OBJECT *id);
+                                  const X509_POLICY_NODE *parent,
+                                  const ASN1_OBJECT *id);
 
 X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
-						const ASN1_OBJECT *id);
+                               const ASN1_OBJECT *id);
 
 X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
-			const X509_POLICY_DATA *data,
-			X509_POLICY_NODE *parent,
-			X509_POLICY_TREE *tree);
+                                 const X509_POLICY_DATA *data,
+                                 X509_POLICY_NODE *parent,
+                                 X509_POLICY_TREE *tree);
 void policy_node_free(X509_POLICY_NODE *node);
 int policy_node_match(const X509_POLICY_LEVEL *lvl,
-		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+                      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
 
 const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/src/crypto/x509v3/pcy_lib.c b/src/crypto/x509v3/pcy_lib.c
index 16be2f0..764f38f 100644
--- a/src/crypto/x509v3/pcy_lib.c
+++ b/src/crypto/x509v3/pcy_lib.c
@@ -1,6 +1,7 @@
 /* pcy_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,112 +55,110 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
 #include "pcy_int.h"
 
-
 /* accessor functions */
 
 /* X509_POLICY_TREE stuff */
 
 int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
-	{
-	if (!tree)
-		return 0;
-	return tree->nlevel;
-	}
+{
+    if (!tree)
+        return 0;
+    return tree->nlevel;
+}
 
-X509_POLICY_LEVEL *
-	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
-	{
-	if (!tree || (i < 0) || (i >= tree->nlevel))
-		return NULL;
-	return tree->levels + i;
-	}
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+                                               int i)
+{
+    if (!tree || (i < 0) || (i >= tree->nlevel))
+        return NULL;
+    return tree->levels + i;
+}
 
-STACK_OF(X509_POLICY_NODE) *
-		X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
-	{
-	if (!tree)
-		return NULL;
-	return tree->auth_policies;
-	}
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+                                                           X509_POLICY_TREE
+                                                           *tree)
+{
+    if (!tree)
+        return NULL;
+    return tree->auth_policies;
+}
 
-STACK_OF(X509_POLICY_NODE) *
-	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
-	{
-	if (!tree)
-		return NULL;
-	if (tree->flags & POLICY_FLAG_ANY_POLICY)
-		return tree->auth_policies;
-	else
-		return tree->user_policies;
-	}
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+                                                                X509_POLICY_TREE
+                                                                *tree)
+{
+    if (!tree)
+        return NULL;
+    if (tree->flags & POLICY_FLAG_ANY_POLICY)
+        return tree->auth_policies;
+    else
+        return tree->user_policies;
+}
 
 /* X509_POLICY_LEVEL stuff */
 
 int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
-	{
-	int n;
-	if (!level)
-		return 0;
-	if (level->anyPolicy)
-		n = 1;
-	else
-		n = 0;
-	if (level->nodes)
-		n += sk_X509_POLICY_NODE_num(level->nodes);
-	return n;
-	}
+{
+    int n;
+    if (!level)
+        return 0;
+    if (level->anyPolicy)
+        n = 1;
+    else
+        n = 0;
+    if (level->nodes)
+        n += sk_X509_POLICY_NODE_num(level->nodes);
+    return n;
+}
 
 X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
-	{
-	if (!level)
-		return NULL;
-	if (level->anyPolicy)
-		{
-		if (i == 0)
-			return level->anyPolicy;
-		i--;
-		}
-	return sk_X509_POLICY_NODE_value(level->nodes, i);
-	}
+{
+    if (!level)
+        return NULL;
+    if (level->anyPolicy) {
+        if (i == 0)
+            return level->anyPolicy;
+        i--;
+    }
+    return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
 
 /* X509_POLICY_NODE stuff */
 
 const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
-	{
-	if (!node)
-		return NULL;
-	return node->data->valid_policy;
-	}
+{
+    if (!node)
+        return NULL;
+    return node->data->valid_policy;
+}
 
 #if 0
 int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
-	{
-	if (node_critical(node))
-		return 1;
-	return 0;
-	}
+{
+    if (node_critical(node))
+        return 1;
+    return 0;
+}
 #endif
 
-STACK_OF(POLICYQUALINFO) *
-		X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
-	{
-	if (!node)
-		return NULL;
-	return node->data->qualifier_set;
-	}
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+                                                           X509_POLICY_NODE
+                                                           *node)
+{
+    if (!node)
+        return NULL;
+    return node->data->qualifier_set;
+}
 
-const X509_POLICY_NODE *
-		X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
-	{
-	if (!node)
-		return NULL;
-	return node->parent;
-	}
-
-
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+                                                     *node)
+{
+    if (!node)
+        return NULL;
+    return node->parent;
+}
diff --git a/src/crypto/x509v3/pcy_map.c b/src/crypto/x509v3/pcy_map.c
index 2b8307b..7263c69 100644
--- a/src/crypto/x509v3/pcy_map.c
+++ b/src/crypto/x509v3/pcy_map.c
@@ -1,6 +1,7 @@
 /* pcy_map.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -62,72 +63,68 @@
 
 #include "pcy_int.h"
 
-
-/* Set policy mapping entries in cache.
- * Note: this modifies the passed POLICY_MAPPINGS structure
+/*
+ * Set policy mapping entries in cache. Note: this modifies the passed
+ * POLICY_MAPPINGS structure
  */
 
 int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
-	{
-	POLICY_MAPPING *map;
-	X509_POLICY_DATA *data;
-	X509_POLICY_CACHE *cache = x->policy_cache;
-	size_t i;
-	int ret = 0;
-	if (sk_POLICY_MAPPING_num(maps) == 0)
-		{
-		ret = -1;
-		goto bad_mapping;
-		}
-	for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
-		{
-		map = sk_POLICY_MAPPING_value(maps, i);
-		/* Reject if map to or from anyPolicy */
-		if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
-		   || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
-			{
-			ret = -1;
-			goto bad_mapping;
-			}
+{
+    POLICY_MAPPING *map;
+    X509_POLICY_DATA *data;
+    X509_POLICY_CACHE *cache = x->policy_cache;
+    size_t i;
+    int ret = 0;
+    if (sk_POLICY_MAPPING_num(maps) == 0) {
+        ret = -1;
+        goto bad_mapping;
+    }
+    for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
+        map = sk_POLICY_MAPPING_value(maps, i);
+        /* Reject if map to or from anyPolicy */
+        if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
+            || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
+            ret = -1;
+            goto bad_mapping;
+        }
 
-		/* Attempt to find matching policy data */
-		data = policy_cache_find_data(cache, map->issuerDomainPolicy);
-		/* If we don't have anyPolicy can't map */
-		if (!data && !cache->anyPolicy)
-			continue;
+        /* Attempt to find matching policy data */
+        data = policy_cache_find_data(cache, map->issuerDomainPolicy);
+        /* If we don't have anyPolicy can't map */
+        if (!data && !cache->anyPolicy)
+            continue;
 
-		/* Create a NODE from anyPolicy */
-		if (!data)
-			{
-			data = policy_data_new(NULL, map->issuerDomainPolicy,
-					cache->anyPolicy->flags
-						& POLICY_DATA_FLAG_CRITICAL);
-			if (!data)
-				goto bad_mapping;
-			data->qualifier_set = cache->anyPolicy->qualifier_set;
-			/*map->issuerDomainPolicy = NULL;*/
-			data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
-			data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
-			if (!sk_X509_POLICY_DATA_push(cache->data, data))
-				{
-				policy_data_free(data);
-				goto bad_mapping;
-				}
-			}
-		else
-			data->flags |= POLICY_DATA_FLAG_MAPPED;
-		if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 
-						map->subjectDomainPolicy))
-			goto bad_mapping;
-		map->subjectDomainPolicy = NULL;
+        /* Create a NODE from anyPolicy */
+        if (!data) {
+            data = policy_data_new(NULL, map->issuerDomainPolicy,
+                                   cache->anyPolicy->flags
+                                   & POLICY_DATA_FLAG_CRITICAL);
+            if (!data)
+                goto bad_mapping;
+            data->qualifier_set = cache->anyPolicy->qualifier_set;
+            /*
+             * map->issuerDomainPolicy = NULL;
+             */
+            data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
+            data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+            if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
+                policy_data_free(data);
+                goto bad_mapping;
+            }
+        } else
+            data->flags |= POLICY_DATA_FLAG_MAPPED;
+        if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+                                 map->subjectDomainPolicy))
+            goto bad_mapping;
+        map->subjectDomainPolicy = NULL;
 
-		}
+    }
 
-	ret = 1;
-	bad_mapping:
-	if (ret == -1)
-		x->ex_flags |= EXFLAG_INVALID_POLICY;
-	sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
-	return ret;
+    ret = 1;
+ bad_mapping:
+    if (ret == -1)
+        x->ex_flags |= EXFLAG_INVALID_POLICY;
+    sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
+    return ret;
 
-	}
+}
diff --git a/src/crypto/x509v3/pcy_node.c b/src/crypto/x509v3/pcy_node.c
index 55cc203..cf4e79d 100644
--- a/src/crypto/x509v3/pcy_node.c
+++ b/src/crypto/x509v3/pcy_node.c
@@ -1,6 +1,7 @@
 /* pcy_node.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -62,136 +63,126 @@
 
 #include "pcy_int.h"
 
-
-static int node_cmp(const X509_POLICY_NODE **a,
-			const X509_POLICY_NODE **b)
-	{
-	return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
-	}
+static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **b)
+{
+    return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
+}
 
 STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
-	{
-	return sk_X509_POLICY_NODE_new(node_cmp);
-	}
+{
+    return sk_X509_POLICY_NODE_new(node_cmp);
+}
 
 X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
-					const ASN1_OBJECT *id)
-	{
-	X509_POLICY_DATA n;
-	X509_POLICY_NODE l;
-	size_t idx;
+                               const ASN1_OBJECT *id)
+{
+    X509_POLICY_DATA n;
+    X509_POLICY_NODE l;
+    size_t idx;
 
-	n.valid_policy = (ASN1_OBJECT *)id;
-	l.data = &n;
+    n.valid_policy = (ASN1_OBJECT *)id;
+    l.data = &n;
 
-	if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
-		return NULL;
+    if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
+        return NULL;
 
-	return sk_X509_POLICY_NODE_value(nodes, idx);
+    return sk_X509_POLICY_NODE_value(nodes, idx);
 
-	}
+}
 
 X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
-					const X509_POLICY_NODE *parent,	
-					const ASN1_OBJECT *id)
-	{
-	X509_POLICY_NODE *node;
-	size_t i;
-	for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
-		{
-		node = sk_X509_POLICY_NODE_value(level->nodes, i);
-		if (node->parent == parent)
-			{
-			if (!OBJ_cmp(node->data->valid_policy, id))
-				return node;
-			}
-		}
-	return NULL;
-	}
+                                  const X509_POLICY_NODE *parent,
+                                  const ASN1_OBJECT *id)
+{
+    X509_POLICY_NODE *node;
+    size_t i;
+    for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
+        node = sk_X509_POLICY_NODE_value(level->nodes, i);
+        if (node->parent == parent) {
+            if (!OBJ_cmp(node->data->valid_policy, id))
+                return node;
+        }
+    }
+    return NULL;
+}
 
 X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
-			const X509_POLICY_DATA *data,
-			X509_POLICY_NODE *parent,
-			X509_POLICY_TREE *tree)
-	{
-	X509_POLICY_NODE *node;
-	node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
-	if (!node)
-		return NULL;
-	node->data = data;
-	node->parent = parent;
-	node->nchild = 0;
-	if (level)
-		{
-		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
-			{
-			if (level->anyPolicy)
-				goto node_error;
-			level->anyPolicy = node;
-			}
-		else
-			{
+                                 const X509_POLICY_DATA *data,
+                                 X509_POLICY_NODE *parent,
+                                 X509_POLICY_TREE *tree)
+{
+    X509_POLICY_NODE *node;
+    node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
+    if (!node)
+        return NULL;
+    node->data = data;
+    node->parent = parent;
+    node->nchild = 0;
+    if (level) {
+        if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+            if (level->anyPolicy)
+                goto node_error;
+            level->anyPolicy = node;
+        } else {
 
-			if (!level->nodes)
-				level->nodes = policy_node_cmp_new();
-			if (!level->nodes)
-				goto node_error;
-			if (!sk_X509_POLICY_NODE_push(level->nodes, node))
-				goto node_error;
-			}
-		}
+            if (!level->nodes)
+                level->nodes = policy_node_cmp_new();
+            if (!level->nodes)
+                goto node_error;
+            if (!sk_X509_POLICY_NODE_push(level->nodes, node))
+                goto node_error;
+        }
+    }
 
-	if (tree)
-		{
-		if (!tree->extra_data)
-			 tree->extra_data = sk_X509_POLICY_DATA_new_null();
-		if (!tree->extra_data)
-			goto node_error;
-		if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
-			goto node_error;
-		}
+    if (tree) {
+        if (!tree->extra_data)
+            tree->extra_data = sk_X509_POLICY_DATA_new_null();
+        if (!tree->extra_data)
+            goto node_error;
+        if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
+            goto node_error;
+    }
 
-	if (parent)
-		parent->nchild++;
+    if (parent)
+        parent->nchild++;
 
-	return node;
+    return node;
 
-	node_error:
-	policy_node_free(node);
-	return 0;
+ node_error:
+    policy_node_free(node);
+    return 0;
 
-	}
+}
 
 void policy_node_free(X509_POLICY_NODE *node)
-	{
-	OPENSSL_free(node);
-	}
+{
+    OPENSSL_free(node);
+}
 
-/* See if a policy node matches a policy OID. If mapping enabled look through
+/*
+ * See if a policy node matches a policy OID. If mapping enabled look through
  * expected policy set otherwise just valid policy.
  */
 
 int policy_node_match(const X509_POLICY_LEVEL *lvl,
-		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
-	{
-	size_t i;
-	ASN1_OBJECT *policy_oid;
-	const X509_POLICY_DATA *x = node->data;
+                      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
+{
+    size_t i;
+    ASN1_OBJECT *policy_oid;
+    const X509_POLICY_DATA *x = node->data;
 
-	if (	    (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
-		|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
-		{
-		if (!OBJ_cmp(x->valid_policy, oid))
-			return 1;
-		return 0;
-		}
+    if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
+        if (!OBJ_cmp(x->valid_policy, oid))
+            return 1;
+        return 0;
+    }
 
-	for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
-		{
-		policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
-		if (!OBJ_cmp(policy_oid, oid))
-			return 1;
-		}
-	return 0;
+    for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
+        policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
+        if (!OBJ_cmp(policy_oid, oid))
+            return 1;
+    }
+    return 0;
 
-	}
+}
diff --git a/src/crypto/x509v3/pcy_tree.c b/src/crypto/x509v3/pcy_tree.c
index 8e9ef25..e7484e5 100644
--- a/src/crypto/x509v3/pcy_tree.c
+++ b/src/crypto/x509v3/pcy_tree.c
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
  */
 /* ====================================================================
  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
@@ -9,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -66,811 +67,762 @@
 
 #include "pcy_int.h"
 
-
-/* Enable this to print out the complete policy tree at various point during
+/*
+ * Enable this to print out the complete policy tree at various point during
  * evaluation.
  */
 
-/*#define OPENSSL_POLICY_DEBUG*/
+/*
+ * #define OPENSSL_POLICY_DEBUG
+ */
 
 #ifdef OPENSSL_POLICY_DEBUG
 
 static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
-				X509_POLICY_NODE *node, int indent)
-	{
-	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
-		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
-		BIO_puts(err, "  Not Mapped\n");
-	else
-		{
-		int i;
-		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
-		ASN1_OBJECT *oid;
-		BIO_puts(err, "  Expected: ");
-		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
-			{
-			oid = sk_ASN1_OBJECT_value(pset, i);
-			if (i)
-				BIO_puts(err, ", ");
-			i2a_ASN1_OBJECT(err, oid);
-			}
-		BIO_puts(err, "\n");
-		}
-	}
+                           X509_POLICY_NODE *node, int indent)
+{
+    if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+        BIO_puts(err, "  Not Mapped\n");
+    else {
+        int i;
+        STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
+        ASN1_OBJECT *oid;
+        BIO_puts(err, "  Expected: ");
+        for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
+            oid = sk_ASN1_OBJECT_value(pset, i);
+            if (i)
+                BIO_puts(err, ", ");
+            i2a_ASN1_OBJECT(err, oid);
+        }
+        BIO_puts(err, "\n");
+    }
+}
 
 static void tree_print(char *str, X509_POLICY_TREE *tree,
-			X509_POLICY_LEVEL *curr)
-	{
-	X509_POLICY_LEVEL *plev;
-	X509_POLICY_NODE *node;
-	int i;
-	BIO *err;
-	err = BIO_new_fp(stderr, BIO_NOCLOSE);
-	if (!curr)
-		curr = tree->levels + tree->nlevel;
-	else
-		curr++;
-	BIO_printf(err, "Level print after %s\n", str);
-	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
-	for (plev = tree->levels; plev != curr; plev++)
-		{
-		BIO_printf(err, "Level %ld, flags = %x\n",
-				plev - tree->levels, plev->flags);
-		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
-			{
-			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
-			X509_POLICY_NODE_print(err, node, 2);
-			expected_print(err, plev, node, 2);
-			BIO_printf(err, "  Flags: %x\n", node->data->flags);
-			}
-		if (plev->anyPolicy)
-			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
-		}
+                       X509_POLICY_LEVEL *curr)
+{
+    X509_POLICY_LEVEL *plev;
+    X509_POLICY_NODE *node;
+    int i;
+    BIO *err;
+    err = BIO_new_fp(stderr, BIO_NOCLOSE);
+    if (!curr)
+        curr = tree->levels + tree->nlevel;
+    else
+        curr++;
+    BIO_printf(err, "Level print after %s\n", str);
+    BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
+    for (plev = tree->levels; plev != curr; plev++) {
+        BIO_printf(err, "Level %ld, flags = %x\n",
+                   plev - tree->levels, plev->flags);
+        for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
+            node = sk_X509_POLICY_NODE_value(plev->nodes, i);
+            X509_POLICY_NODE_print(err, node, 2);
+            expected_print(err, plev, node, 2);
+            BIO_printf(err, "  Flags: %x\n", node->data->flags);
+        }
+        if (plev->anyPolicy)
+            X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
+    }
 
-	BIO_free(err);
+    BIO_free(err);
 
-	}
+}
 #else
 
-#define tree_print(a,b,c) /* */
+# define tree_print(a,b,c)      /* */
 
 #endif
 
-/* Initialize policy tree. Return values:
- *  0 Some internal error occured.
- * -1 Inconsistent or invalid extensions in certificates.
- *  1 Tree initialized OK.
- *  2 Policy tree is empty.
- *  5 Tree OK and requireExplicitPolicy true.
- *  6 Tree empty and requireExplicitPolicy true.
+/*
+ * Initialize policy tree. Return values: 0 Some internal error occured. -1
+ * Inconsistent or invalid extensions in certificates.  1 Tree initialized
+ * OK.  2 Policy tree is empty.  5 Tree OK and requireExplicitPolicy true.  6
+ * Tree empty and requireExplicitPolicy true.
  */
 
 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
-			unsigned int flags)
-	{
-	X509_POLICY_TREE *tree;
-	X509_POLICY_LEVEL *level;
-	const X509_POLICY_CACHE *cache;
-	X509_POLICY_DATA *data = NULL;
-	X509 *x;
-	int ret = 1;
-	int i, n;
-	int explicit_policy;
-	int any_skip;
-	int map_skip;
-	*ptree = NULL;
-	n = sk_X509_num(certs);
+                     unsigned int flags)
+{
+    X509_POLICY_TREE *tree;
+    X509_POLICY_LEVEL *level;
+    const X509_POLICY_CACHE *cache;
+    X509_POLICY_DATA *data = NULL;
+    X509 *x;
+    int ret = 1;
+    int i, n;
+    int explicit_policy;
+    int any_skip;
+    int map_skip;
+    *ptree = NULL;
+    n = sk_X509_num(certs);
 
 #if 0
-	/* Disable policy mapping for now... */
-	flags |= X509_V_FLAG_INHIBIT_MAP;
+    /* Disable policy mapping for now... */
+    flags |= X509_V_FLAG_INHIBIT_MAP;
 #endif
 
-	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
-		explicit_policy = 0;
-	else
-		explicit_policy = n + 1;
+    if (flags & X509_V_FLAG_EXPLICIT_POLICY)
+        explicit_policy = 0;
+    else
+        explicit_policy = n + 1;
 
-	if (flags & X509_V_FLAG_INHIBIT_ANY)
-		any_skip = 0;
-	else
-		any_skip = n + 1;
+    if (flags & X509_V_FLAG_INHIBIT_ANY)
+        any_skip = 0;
+    else
+        any_skip = n + 1;
 
-	if (flags & X509_V_FLAG_INHIBIT_MAP)
-		map_skip = 0;
-	else
-		map_skip = n + 1;
+    if (flags & X509_V_FLAG_INHIBIT_MAP)
+        map_skip = 0;
+    else
+        map_skip = n + 1;
 
-	/* Can't do anything with just a trust anchor */
-	if (n == 1)
-		return 1;
-	/* First setup policy cache in all certificates apart from the
-	 * trust anchor. Note any bad cache results on the way. Also can
-	 * calculate explicit_policy value at this point.
-	 */
-	for (i = n - 2; i >= 0; i--)
-		{
-		x = sk_X509_value(certs, i);
-		X509_check_purpose(x, -1, -1);
-		cache = policy_cache_set(x);
-		/* If cache NULL something bad happened: return immediately */
-		if (cache == NULL)
-			return 0;
-		/* If inconsistent extensions keep a note of it but continue */
-		if (x->ex_flags & EXFLAG_INVALID_POLICY)
-			ret = -1;
-		/* Otherwise if we have no data (hence no CertificatePolicies)
-		 * and haven't already set an inconsistent code note it.
-		 */
-		else if ((ret == 1) && !cache->data)
-			ret = 2;
-		if (explicit_policy > 0)
-			{
-			if (!(x->ex_flags & EXFLAG_SI))
-				explicit_policy--;
-			if ((cache->explicit_skip != -1)
-				&& (cache->explicit_skip < explicit_policy))
-				explicit_policy = cache->explicit_skip;
-			}
-		}
+    /* Can't do anything with just a trust anchor */
+    if (n == 1)
+        return 1;
+    /*
+     * First setup policy cache in all certificates apart from the trust
+     * anchor. Note any bad cache results on the way. Also can calculate
+     * explicit_policy value at this point.
+     */
+    for (i = n - 2; i >= 0; i--) {
+        x = sk_X509_value(certs, i);
+        X509_check_purpose(x, -1, -1);
+        cache = policy_cache_set(x);
+        /* If cache NULL something bad happened: return immediately */
+        if (cache == NULL)
+            return 0;
+        /*
+         * If inconsistent extensions keep a note of it but continue
+         */
+        if (x->ex_flags & EXFLAG_INVALID_POLICY)
+            ret = -1;
+        /*
+         * Otherwise if we have no data (hence no CertificatePolicies) and
+         * haven't already set an inconsistent code note it.
+         */
+        else if ((ret == 1) && !cache->data)
+            ret = 2;
+        if (explicit_policy > 0) {
+            if (!(x->ex_flags & EXFLAG_SI))
+                explicit_policy--;
+            if ((cache->explicit_skip != -1)
+                && (cache->explicit_skip < explicit_policy))
+                explicit_policy = cache->explicit_skip;
+        }
+    }
 
-	if (ret != 1)
-		{
-		if (ret == 2 && !explicit_policy)
-			return 6;
-		return ret;
-		}
+    if (ret != 1) {
+        if (ret == 2 && !explicit_policy)
+            return 6;
+        return ret;
+    }
 
+    /* If we get this far initialize the tree */
 
-	/* If we get this far initialize the tree */
+    tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
 
-	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
+    if (!tree)
+        return 0;
 
-	if (!tree)
-		return 0;
+    tree->flags = 0;
+    tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
+    tree->nlevel = 0;
+    tree->extra_data = NULL;
+    tree->auth_policies = NULL;
+    tree->user_policies = NULL;
 
-	tree->flags = 0;
-	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
-	tree->nlevel = 0;
-	tree->extra_data = NULL;
-	tree->auth_policies = NULL;
-	tree->user_policies = NULL;
+    if (!tree->levels) {
+        OPENSSL_free(tree);
+        return 0;
+    }
 
-	if (!tree->levels)
-		{
-		OPENSSL_free(tree);
-		return 0;
-		}
+    memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
 
-	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
+    tree->nlevel = n;
 
-	tree->nlevel = n;
+    level = tree->levels;
 
-	level = tree->levels;
+    /* Root data: initialize to anyPolicy */
 
-	/* Root data: initialize to anyPolicy */
+    data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
 
-	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
+    if (!data || !level_add_node(level, data, NULL, tree))
+        goto bad_tree;
 
-	if (!data || !level_add_node(level, data, NULL, tree))
-		goto bad_tree;
+    for (i = n - 2; i >= 0; i--) {
+        level++;
+        x = sk_X509_value(certs, i);
+        cache = policy_cache_set(x);
+        level->cert = X509_up_ref(x);
 
-	for (i = n - 2; i >= 0; i--)
-		{
-		level++;
-		x = sk_X509_value(certs, i);
-		cache = policy_cache_set(x);
-		level->cert = X509_up_ref(x);
+        if (!cache->anyPolicy)
+            level->flags |= X509_V_FLAG_INHIBIT_ANY;
 
-		if (!cache->anyPolicy)
-				level->flags |= X509_V_FLAG_INHIBIT_ANY;
+        /* Determine inhibit any and inhibit map flags */
+        if (any_skip == 0) {
+            /*
+             * Any matching allowed if certificate is self issued and not the
+             * last in the chain.
+             */
+            if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
+                level->flags |= X509_V_FLAG_INHIBIT_ANY;
+        } else {
+            if (!(x->ex_flags & EXFLAG_SI))
+                any_skip--;
+            if ((cache->any_skip >= 0)
+                && (cache->any_skip < any_skip))
+                any_skip = cache->any_skip;
+        }
 
-		/* Determine inhibit any and inhibit map flags */
-		if (any_skip == 0)
-			{
-			/* Any matching allowed if certificate is self
-			 * issued and not the last in the chain.
-			 */
-			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
-				level->flags |= X509_V_FLAG_INHIBIT_ANY;
-			}
-		else
-			{
-			if (!(x->ex_flags & EXFLAG_SI))
-				any_skip--;
-			if ((cache->any_skip >= 0)
-				&& (cache->any_skip < any_skip))
-				any_skip = cache->any_skip;
-			}
+        if (map_skip == 0)
+            level->flags |= X509_V_FLAG_INHIBIT_MAP;
+        else {
+            if (!(x->ex_flags & EXFLAG_SI))
+                map_skip--;
+            if ((cache->map_skip >= 0)
+                && (cache->map_skip < map_skip))
+                map_skip = cache->map_skip;
+        }
 
-		if (map_skip == 0)
-			level->flags |= X509_V_FLAG_INHIBIT_MAP;
-		else
-			{
-			if (!(x->ex_flags & EXFLAG_SI))
-				map_skip--;
-			if ((cache->map_skip >= 0)
-				&& (cache->map_skip < map_skip))
-				map_skip = cache->map_skip;
-			}
+    }
 
-		}
+    *ptree = tree;
 
-	*ptree = tree;
+    if (explicit_policy)
+        return 1;
+    else
+        return 5;
 
-	if (explicit_policy)
-		return 1;
-	else
-		return 5;
+ bad_tree:
 
-	bad_tree:
+    X509_policy_tree_free(tree);
 
-	X509_policy_tree_free(tree);
+    return 0;
 
-	return 0;
-
-	}
+}
 
 static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
-				const X509_POLICY_DATA *data)
-	{
-	X509_POLICY_LEVEL *last = curr - 1;
-	X509_POLICY_NODE *node;
-	int matched = 0;
-	size_t i;
-	/* Iterate through all in nodes linking matches */
-	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
-		{
-		node = sk_X509_POLICY_NODE_value(last->nodes, i);
-		if (policy_node_match(last, node, data->valid_policy))
-			{
-			if (!level_add_node(curr, data, node, NULL))
-				return 0;
-			matched = 1;
-			}
-		}
-	if (!matched && last->anyPolicy)
-		{
-		if (!level_add_node(curr, data, last->anyPolicy, NULL))
-			return 0;
-		}
-	return 1;
-	}
+                                    const X509_POLICY_DATA *data)
+{
+    X509_POLICY_LEVEL *last = curr - 1;
+    X509_POLICY_NODE *node;
+    int matched = 0;
+    size_t i;
+    /* Iterate through all in nodes linking matches */
+    for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+        node = sk_X509_POLICY_NODE_value(last->nodes, i);
+        if (policy_node_match(last, node, data->valid_policy)) {
+            if (!level_add_node(curr, data, node, NULL))
+                return 0;
+            matched = 1;
+        }
+    }
+    if (!matched && last->anyPolicy) {
+        if (!level_add_node(curr, data, last->anyPolicy, NULL))
+            return 0;
+    }
+    return 1;
+}
 
-/* This corresponds to RFC3280 6.1.3(d)(1):
- * link any data from CertificatePolicies onto matching parent
- * or anyPolicy if no match.
+/*
+ * This corresponds to RFC3280 6.1.3(d)(1): link any data from
+ * CertificatePolicies onto matching parent or anyPolicy if no match.
  */
 
 static int tree_link_nodes(X509_POLICY_LEVEL *curr,
-				const X509_POLICY_CACHE *cache)
-	{
-	size_t i;
-	X509_POLICY_DATA *data;
+                           const X509_POLICY_CACHE *cache)
+{
+    size_t i;
+    X509_POLICY_DATA *data;
 
-	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
-		{
-		data = sk_X509_POLICY_DATA_value(cache->data, i);
-		/* If a node is mapped any it doesn't have a corresponding
-		 * CertificatePolicies entry. 
-		 * However such an identical node would be created
-		 * if anyPolicy matching is enabled because there would be
-		 * no match with the parent valid_policy_set. So we create
-		 * link because then it will have the mapping flags
-		 * right and we can prune it later.
-		 */
+    for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
+        data = sk_X509_POLICY_DATA_value(cache->data, i);
+        /*
+         * If a node is mapped any it doesn't have a corresponding
+         * CertificatePolicies entry. However such an identical node would
+         * be created if anyPolicy matching is enabled because there would be
+         * no match with the parent valid_policy_set. So we create link
+         * because then it will have the mapping flags right and we can prune
+         * it later.
+         */
 #if 0
-		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
-			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
-			continue;
+        if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
+            && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
+            continue;
 #endif
-		/* Look for matching nodes in previous level */
-		if (!tree_link_matching_nodes(curr, data))
-				return 0;
-		}
-	return 1;
-	}
+        /* Look for matching nodes in previous level */
+        if (!tree_link_matching_nodes(curr, data))
+            return 0;
+    }
+    return 1;
+}
 
-/* This corresponds to RFC3280 6.1.3(d)(2):
- * Create new data for any unmatched policies in the parent and link
- * to anyPolicy.
+/*
+ * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched
+ * policies in the parent and link to anyPolicy.
  */
 
 static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
-			const X509_POLICY_CACHE *cache,
-			const ASN1_OBJECT *id,
-			X509_POLICY_NODE *node,
-			X509_POLICY_TREE *tree)
-	{
-	X509_POLICY_DATA *data;
-	if (id == NULL)
-		id = node->data->valid_policy;
-	/* Create a new node with qualifiers from anyPolicy and
-	 * id from unmatched node.
-	 */
-	data = policy_data_new(NULL, id, node_critical(node));
+                              const X509_POLICY_CACHE *cache,
+                              const ASN1_OBJECT *id,
+                              X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+    X509_POLICY_DATA *data;
+    if (id == NULL)
+        id = node->data->valid_policy;
+    /*
+     * Create a new node with qualifiers from anyPolicy and id from unmatched
+     * node.
+     */
+    data = policy_data_new(NULL, id, node_critical(node));
 
-	if (data == NULL)
-		return 0;
-	/* Curr may not have anyPolicy */
-	data->qualifier_set = cache->anyPolicy->qualifier_set;
-	data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
-	if (!level_add_node(curr, data, node, tree))
-		{
-		policy_data_free(data);
-		return 0;
-		}
+    if (data == NULL)
+        return 0;
+    /* Curr may not have anyPolicy */
+    data->qualifier_set = cache->anyPolicy->qualifier_set;
+    data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+    if (!level_add_node(curr, data, node, tree)) {
+        policy_data_free(data);
+        return 0;
+    }
 
-	return 1;
-	}
+    return 1;
+}
 
 static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
-			const X509_POLICY_CACHE *cache,
-			X509_POLICY_NODE *node,
-			X509_POLICY_TREE *tree)
-	{
-	const X509_POLICY_LEVEL *last = curr - 1;
-	size_t i;
+                               const X509_POLICY_CACHE *cache,
+                               X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+    const X509_POLICY_LEVEL *last = curr - 1;
+    size_t i;
 
-	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
-		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
-		{
-		/* If no policy mapping: matched if one child present */
-		if (node->nchild)
-			return 1;
-		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
-			return 0;
-		/* Add it */
-		}
-	else
-		{
-		/* If mapping: matched if one child per expected policy set */
-		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
-		if ((size_t) node->nchild == sk_ASN1_OBJECT_num(expset))
-			return 1;
-		/* Locate unmatched nodes */
-		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
-			{
-			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
-			if (level_find_node(curr, node, oid))
-				continue;
-			if (!tree_add_unmatched(curr, cache, oid, node, tree))
-				return 0;
-			}
+    if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
+        /* If no policy mapping: matched if one child present */
+        if (node->nchild)
+            return 1;
+        if (!tree_add_unmatched(curr, cache, NULL, node, tree))
+            return 0;
+        /* Add it */
+    } else {
+        /* If mapping: matched if one child per expected policy set */
+        STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
+        if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset))
+            return 1;
+        /* Locate unmatched nodes */
+        for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
+            ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
+            if (level_find_node(curr, node, oid))
+                continue;
+            if (!tree_add_unmatched(curr, cache, oid, node, tree))
+                return 0;
+        }
 
-		}
+    }
 
-	return 1;
+    return 1;
 
-	}
+}
 
 static int tree_link_any(X509_POLICY_LEVEL *curr,
-			const X509_POLICY_CACHE *cache,
-			X509_POLICY_TREE *tree)
-	{
-	size_t i;
-	/*X509_POLICY_DATA *data;*/
-	X509_POLICY_NODE *node;
-	X509_POLICY_LEVEL *last = curr - 1;
+                         const X509_POLICY_CACHE *cache,
+                         X509_POLICY_TREE *tree)
+{
+    size_t i;
+    /*
+     * X509_POLICY_DATA *data;
+     */
+    X509_POLICY_NODE *node;
+    X509_POLICY_LEVEL *last = curr - 1;
 
-	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
-		{
-		node = sk_X509_POLICY_NODE_value(last->nodes, i);
+    for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+        node = sk_X509_POLICY_NODE_value(last->nodes, i);
 
-		if (!tree_link_unmatched(curr, cache, node, tree))
-			return 0;
+        if (!tree_link_unmatched(curr, cache, node, tree))
+            return 0;
 
 #if 0
 
-		/* Skip any node with any children: we only want unmathced
-		 * nodes.
-		 *
-		 * Note: need something better for policy mapping
-		 * because each node may have multiple children 
-		 */
-		if (node->nchild)
-			continue;
+        /*
+         * Skip any node with any children: we only want unmathced nodes.
+         * Note: need something better for policy mapping because each node
+         * may have multiple children
+         */
+        if (node->nchild)
+            continue;
 
-		/* Create a new node with qualifiers from anyPolicy and
-		 * id from unmatched node.
-		 */
-		data = policy_data_new(NULL, node->data->valid_policy, 
-						node_critical(node));
+        /*
+         * Create a new node with qualifiers from anyPolicy and id from
+         * unmatched node.
+         */
+        data = policy_data_new(NULL, node->data->valid_policy,
+                               node_critical(node));
 
-		if (data == NULL)
-			return 0;
-		/* Curr may not have anyPolicy */
-		data->qualifier_set = cache->anyPolicy->qualifier_set;
-		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
-		if (!level_add_node(curr, data, node, tree))
-			{
-			policy_data_free(data);
-			return 0;
-			}
-
+        if (data == NULL)
+            return 0;
+        /* Curr may not have anyPolicy */
+        data->qualifier_set = cache->anyPolicy->qualifier_set;
+        data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+        if (!level_add_node(curr, data, node, tree)) {
+            policy_data_free(data);
+            return 0;
+        }
 #endif
 
-		}
-	/* Finally add link to anyPolicy */
-	if (last->anyPolicy)
-		{
-		if (!level_add_node(curr, cache->anyPolicy,
-						last->anyPolicy, NULL))
-			return 0;
-		}
-	return 1;
-	}
+    }
+    /* Finally add link to anyPolicy */
+    if (last->anyPolicy) {
+        if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
+            return 0;
+    }
+    return 1;
+}
 
-/* Prune the tree: delete any child mapped child data on the current level
+/*
+ * Prune the tree: delete any child mapped child data on the current level
  * then proceed up the tree deleting any data with no children. If we ever
  * have no data on a level we can halt because the tree will be empty.
  */
 
 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
-	{
-	STACK_OF(X509_POLICY_NODE) *nodes;
-	X509_POLICY_NODE *node;
-	int i;
-	nodes = curr->nodes;
-	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
-		{
-		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
-			{
-			node = sk_X509_POLICY_NODE_value(nodes, i);
-			/* Delete any mapped data: see RFC3280 XXXX */
-			if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
-				{
-				node->parent->nchild--;
-				OPENSSL_free(node);
-				(void)sk_X509_POLICY_NODE_delete(nodes,i);
-				}
-			}
-		}
+{
+    STACK_OF(X509_POLICY_NODE) *nodes;
+    X509_POLICY_NODE *node;
+    int i;
+    nodes = curr->nodes;
+    if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+        for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+            node = sk_X509_POLICY_NODE_value(nodes, i);
+            /* Delete any mapped data: see RFC3280 XXXX */
+            if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
+                node->parent->nchild--;
+                OPENSSL_free(node);
+                (void)sk_X509_POLICY_NODE_delete(nodes, i);
+            }
+        }
+    }
 
-	for(;;)	{
-		--curr;
-		nodes = curr->nodes;
-		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
-			{
-			node = sk_X509_POLICY_NODE_value(nodes, i);
-			if (node->nchild == 0)
-				{
-				node->parent->nchild--;
-				OPENSSL_free(node);
-				(void)sk_X509_POLICY_NODE_delete(nodes, i);
-				}
-			}
-		if (curr->anyPolicy && !curr->anyPolicy->nchild)
-			{
-			if (curr->anyPolicy->parent)
-				curr->anyPolicy->parent->nchild--;
-			OPENSSL_free(curr->anyPolicy);
-			curr->anyPolicy = NULL;
-			}
-		if (curr == tree->levels)
-			{
-			/* If we zapped anyPolicy at top then tree is empty */
-			if (!curr->anyPolicy)
-					return 2;
-			return 1;
-			}
-		}
+    for (;;) {
+        --curr;
+        nodes = curr->nodes;
+        for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+            node = sk_X509_POLICY_NODE_value(nodes, i);
+            if (node->nchild == 0) {
+                node->parent->nchild--;
+                OPENSSL_free(node);
+                (void)sk_X509_POLICY_NODE_delete(nodes, i);
+            }
+        }
+        if (curr->anyPolicy && !curr->anyPolicy->nchild) {
+            if (curr->anyPolicy->parent)
+                curr->anyPolicy->parent->nchild--;
+            OPENSSL_free(curr->anyPolicy);
+            curr->anyPolicy = NULL;
+        }
+        if (curr == tree->levels) {
+            /* If we zapped anyPolicy at top then tree is empty */
+            if (!curr->anyPolicy)
+                return 2;
+            return 1;
+        }
+    }
 
-	}
+}
 
 static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
-						 X509_POLICY_NODE *pcy)
-	{
-	if (!*pnodes)
-		{
-		*pnodes = policy_node_cmp_new();
-		if (!*pnodes)
-			return 0;
-		}
-	else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
-		return 1;
+                              X509_POLICY_NODE *pcy)
+{
+    if (!*pnodes) {
+        *pnodes = policy_node_cmp_new();
+        if (!*pnodes)
+            return 0;
+    } else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
+        return 1;
 
-	if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
-		return 0;
+    if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
+        return 0;
 
-	return 1;
+    return 1;
 
-	}
+}
 
-/* Calculate the authority set based on policy tree.
- * The 'pnodes' parameter is used as a store for the set of policy nodes
- * used to calculate the user set. If the authority set is not anyPolicy
- * then pnodes will just point to the authority set. If however the authority
- * set is anyPolicy then the set of valid policies (other than anyPolicy)
- * is store in pnodes. The return value of '2' is used in this case to indicate
- * that pnodes should be freed.
+/*
+ * Calculate the authority set based on policy tree. The 'pnodes' parameter
+ * is used as a store for the set of policy nodes used to calculate the user
+ * set. If the authority set is not anyPolicy then pnodes will just point to
+ * the authority set. If however the authority set is anyPolicy then the set
+ * of valid policies (other than anyPolicy) is store in pnodes. The return
+ * value of '2' is used in this case to indicate that pnodes should be freed.
  */
 
 static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
-					STACK_OF(X509_POLICY_NODE) **pnodes)
-	{
-	X509_POLICY_LEVEL *curr;
-	X509_POLICY_NODE *node, *anyptr;
-	STACK_OF(X509_POLICY_NODE) **addnodes;
-	int i;
-	size_t j;
-	curr = tree->levels + tree->nlevel - 1;
+                                        STACK_OF(X509_POLICY_NODE) **pnodes)
+{
+    X509_POLICY_LEVEL *curr;
+    X509_POLICY_NODE *node, *anyptr;
+    STACK_OF(X509_POLICY_NODE) **addnodes;
+    int i;
+    size_t j;
+    curr = tree->levels + tree->nlevel - 1;
 
-	/* If last level contains anyPolicy set is anyPolicy */
-	if (curr->anyPolicy)
-		{
-		if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
-			return 0;
-		addnodes = pnodes;
-		}
-	else
-		/* Add policies to authority set */
-		addnodes = &tree->auth_policies;
+    /* If last level contains anyPolicy set is anyPolicy */
+    if (curr->anyPolicy) {
+        if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
+            return 0;
+        addnodes = pnodes;
+    } else
+        /* Add policies to authority set */
+        addnodes = &tree->auth_policies;
 
-	curr = tree->levels;
-	for (i = 1; i < tree->nlevel; i++)
-		{
-		/* If no anyPolicy node on this this level it can't
-		 * appear on lower levels so end search.
-		 */
-		if (!(anyptr = curr->anyPolicy))
-			break;
-		curr++;
-		for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
-			{
-			node = sk_X509_POLICY_NODE_value(curr->nodes, j);
-			if ((node->parent == anyptr)
-				&& !tree_add_auth_node(addnodes, node))
-					return 0;
-			}
-		}
+    curr = tree->levels;
+    for (i = 1; i < tree->nlevel; i++) {
+        /*
+         * If no anyPolicy node on this this level it can't appear on lower
+         * levels so end search.
+         */
+        if (!(anyptr = curr->anyPolicy))
+            break;
+        curr++;
+        for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
+            node = sk_X509_POLICY_NODE_value(curr->nodes, j);
+            if ((node->parent == anyptr)
+                && !tree_add_auth_node(addnodes, node))
+                return 0;
+        }
+    }
 
-	if (addnodes == pnodes)
-		return 2;
+    if (addnodes == pnodes)
+        return 2;
 
-	*pnodes = tree->auth_policies;
+    *pnodes = tree->auth_policies;
 
-	return 1;
-	}
+    return 1;
+}
 
 static int tree_calculate_user_set(X509_POLICY_TREE *tree,
-				STACK_OF(ASN1_OBJECT) *policy_oids,
-				STACK_OF(X509_POLICY_NODE) *auth_nodes)
-	{
-	size_t i;
-	X509_POLICY_NODE *node;
-	ASN1_OBJECT *oid;
+                                   STACK_OF(ASN1_OBJECT) *policy_oids,
+                                   STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
+    size_t i;
+    X509_POLICY_NODE *node;
+    ASN1_OBJECT *oid;
 
-	X509_POLICY_NODE *anyPolicy;
-	X509_POLICY_DATA *extra;
+    X509_POLICY_NODE *anyPolicy;
+    X509_POLICY_DATA *extra;
 
-	/* Check if anyPolicy present in authority constrained policy set:
-	 * this will happen if it is a leaf node.
-	 */
+    /*
+     * Check if anyPolicy present in authority constrained policy set: this
+     * will happen if it is a leaf node.
+     */
 
-	if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
-		return 1;
+    if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
+        return 1;
 
-	anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
+    anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
 
-	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
-		{
-		oid = sk_ASN1_OBJECT_value(policy_oids, i);
-		if (OBJ_obj2nid(oid) == NID_any_policy)
-			{
-			tree->flags |= POLICY_FLAG_ANY_POLICY;
-			return 1;
-			}
-		}
+    for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+        oid = sk_ASN1_OBJECT_value(policy_oids, i);
+        if (OBJ_obj2nid(oid) == NID_any_policy) {
+            tree->flags |= POLICY_FLAG_ANY_POLICY;
+            return 1;
+        }
+    }
 
-	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
-		{
-		oid = sk_ASN1_OBJECT_value(policy_oids, i);
-		node = tree_find_sk(auth_nodes, oid);
-		if (!node)
-			{
-			if (!anyPolicy)
-				continue;
-			/* Create a new node with policy ID from user set
-			 * and qualifiers from anyPolicy.
-			 */
-			extra = policy_data_new(NULL, oid,
-						node_critical(anyPolicy));
-			if (!extra)
-				return 0;
-			extra->qualifier_set = anyPolicy->data->qualifier_set;
-			extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
-						| POLICY_DATA_FLAG_EXTRA_NODE;
-			node = level_add_node(NULL, extra, anyPolicy->parent,
-						tree);
-			}
-		if (!tree->user_policies)
-			{
-			tree->user_policies = sk_X509_POLICY_NODE_new_null();
-			if (!tree->user_policies)
-				return 1;
-			}
-		if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
-			return 0;
-		}
-	return 1;
+    for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+        oid = sk_ASN1_OBJECT_value(policy_oids, i);
+        node = tree_find_sk(auth_nodes, oid);
+        if (!node) {
+            if (!anyPolicy)
+                continue;
+            /*
+             * Create a new node with policy ID from user set and qualifiers
+             * from anyPolicy.
+             */
+            extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
+            if (!extra)
+                return 0;
+            extra->qualifier_set = anyPolicy->data->qualifier_set;
+            extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+                | POLICY_DATA_FLAG_EXTRA_NODE;
+            node = level_add_node(NULL, extra, anyPolicy->parent, tree);
+        }
+        if (!tree->user_policies) {
+            tree->user_policies = sk_X509_POLICY_NODE_new_null();
+            if (!tree->user_policies)
+                return 1;
+        }
+        if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
+            return 0;
+    }
+    return 1;
 
-	}
+}
 
 static int tree_evaluate(X509_POLICY_TREE *tree)
-	{
-	int ret, i;
-	X509_POLICY_LEVEL *curr = tree->levels + 1;
-	const X509_POLICY_CACHE *cache;
+{
+    int ret, i;
+    X509_POLICY_LEVEL *curr = tree->levels + 1;
+    const X509_POLICY_CACHE *cache;
 
-	for(i = 1; i < tree->nlevel; i++, curr++)
-		{
-		cache = policy_cache_set(curr->cert);
-		if (!tree_link_nodes(curr, cache))
-			return 0;
+    for (i = 1; i < tree->nlevel; i++, curr++) {
+        cache = policy_cache_set(curr->cert);
+        if (!tree_link_nodes(curr, cache))
+            return 0;
 
-		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
-			&& !tree_link_any(curr, cache, tree))
-			return 0;
-	tree_print("before tree_prune()", tree, curr);
-		ret = tree_prune(tree, curr);
-		if (ret != 1)
-			return ret;
-		}
+        if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
+            && !tree_link_any(curr, cache, tree))
+            return 0;
+        tree_print("before tree_prune()", tree, curr);
+        ret = tree_prune(tree, curr);
+        if (ret != 1)
+            return ret;
+    }
 
-	return 1;
+    return 1;
 
-	}
+}
 
 static void exnode_free(X509_POLICY_NODE *node)
-	{
-	if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
-		OPENSSL_free(node);
-	}
-
+{
+    if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
+        OPENSSL_free(node);
+}
 
 void X509_policy_tree_free(X509_POLICY_TREE *tree)
-	{
-	X509_POLICY_LEVEL *curr;
-	int i;
+{
+    X509_POLICY_LEVEL *curr;
+    int i;
 
-	if (!tree)
-		return;
+    if (!tree)
+        return;
 
-	sk_X509_POLICY_NODE_free(tree->auth_policies);
-	sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
+    sk_X509_POLICY_NODE_free(tree->auth_policies);
+    sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
 
-	for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
-		{
-		if (curr->cert)
-			X509_free(curr->cert);
-		if (curr->nodes)
-			sk_X509_POLICY_NODE_pop_free(curr->nodes,
-						policy_node_free);
-		if (curr->anyPolicy)
-			policy_node_free(curr->anyPolicy);
-		}
+    for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
+        if (curr->cert)
+            X509_free(curr->cert);
+        if (curr->nodes)
+            sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
+        if (curr->anyPolicy)
+            policy_node_free(curr->anyPolicy);
+    }
 
-	if (tree->extra_data)
-		sk_X509_POLICY_DATA_pop_free(tree->extra_data,
-						policy_data_free);
+    if (tree->extra_data)
+        sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
 
-	OPENSSL_free(tree->levels);
-	OPENSSL_free(tree);
+    OPENSSL_free(tree->levels);
+    OPENSSL_free(tree);
 
-	}
+}
 
-/* Application policy checking function.
- * Return codes:
- *  0 	Internal Error.
- *  1   Successful.
- * -1   One or more certificates contain invalid or inconsistent extensions
- * -2	User constrained policy set empty and requireExplicit true.
+/*
+ * Application policy checking function. Return codes: 0 Internal Error.  1
+ * Successful. -1 One or more certificates contain invalid or inconsistent
+ * extensions -2 User constrained policy set empty and requireExplicit true.
  */
 
 int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
-			STACK_OF(X509) *certs,
-			STACK_OF(ASN1_OBJECT) *policy_oids,
-			unsigned int flags)
-	{
-	int ret;
-	X509_POLICY_TREE *tree = NULL;
-	STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
-	*ptree = NULL;
+                      STACK_OF(X509) *certs,
+                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
+{
+    int ret;
+    X509_POLICY_TREE *tree = NULL;
+    STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
+    *ptree = NULL;
 
-	*pexplicit_policy = 0;
-	ret = tree_init(&tree, certs, flags);
+    *pexplicit_policy = 0;
+    ret = tree_init(&tree, certs, flags);
 
-	switch (ret)
-		{
+    switch (ret) {
 
-		/* Tree empty requireExplicit False: OK */
-		case 2:
-		return 1;
+        /* Tree empty requireExplicit False: OK */
+    case 2:
+        return 1;
 
-		/* Some internal error */
-		case -1:
-		return -1;
+        /* Some internal error */
+    case -1:
+        return -1;
 
-		/* Some internal error */
-		case 0:
-		return 0;
+        /* Some internal error */
+    case 0:
+        return 0;
 
-		/* Tree empty requireExplicit True: Error */
+        /* Tree empty requireExplicit True: Error */
 
-		case 6:
-		*pexplicit_policy = 1;
-		return -2;
+    case 6:
+        *pexplicit_policy = 1;
+        return -2;
 
-		/* Tree OK requireExplicit True: OK and continue */
-		case 5:
-		*pexplicit_policy = 1;
-		break;
+        /* Tree OK requireExplicit True: OK and continue */
+    case 5:
+        *pexplicit_policy = 1;
+        break;
 
-		/* Tree OK: continue */
+        /* Tree OK: continue */
 
-		case 1:
-		if (!tree)
-			/*
-			 * tree_init() returns success and a null tree
-			 * if it's just looking at a trust anchor.
-			 * I'm not sure that returning success here is
-			 * correct, but I'm sure that reporting this
-			 * as an internal error which our caller
-			 * interprets as a malloc failure is wrong.
-			 */
-			return 1;
-		break;
-		}
+    case 1:
+        if (!tree)
+            /*
+             * tree_init() returns success and a null tree
+             * if it's just looking at a trust anchor.
+             * I'm not sure that returning success here is
+             * correct, but I'm sure that reporting this
+             * as an internal error which our caller
+             * interprets as a malloc failure is wrong.
+             */
+            return 1;
+        break;
+    }
 
-	if (!tree) goto error;
-	ret = tree_evaluate(tree);
+    if (!tree)
+        goto error;
+    ret = tree_evaluate(tree);
 
-	tree_print("tree_evaluate()", tree, NULL);
+    tree_print("tree_evaluate()", tree, NULL);
 
-	if (ret <= 0)
-		goto error;
+    if (ret <= 0)
+        goto error;
 
-	/* Return value 2 means tree empty */
-	if (ret == 2)
-		{
-		X509_policy_tree_free(tree);
-		if (*pexplicit_policy)
-			return -2;
-		else
-			return 1;
-		}
+    /* Return value 2 means tree empty */
+    if (ret == 2) {
+        X509_policy_tree_free(tree);
+        if (*pexplicit_policy)
+            return -2;
+        else
+            return 1;
+    }
 
-	/* Tree is not empty: continue */
+    /* Tree is not empty: continue */
 
-	ret = tree_calculate_authority_set(tree, &auth_nodes);
+    ret = tree_calculate_authority_set(tree, &auth_nodes);
 
-	if (!ret)
-		goto error;
+    if (!ret)
+        goto error;
 
-	if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
-		goto error;
-	
-	if (ret == 2)
-		sk_X509_POLICY_NODE_free(auth_nodes);
+    if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
+        goto error;
 
-	if (tree)
-		*ptree = tree;
+    if (ret == 2)
+        sk_X509_POLICY_NODE_free(auth_nodes);
 
-	if (*pexplicit_policy)
-		{
-		nodes = X509_policy_tree_get0_user_policies(tree);
-		if (sk_X509_POLICY_NODE_num(nodes) <= 0)
-			return -2;
-		}
+    if (tree)
+        *ptree = tree;
 
-	return 1;
+    if (*pexplicit_policy) {
+        nodes = X509_policy_tree_get0_user_policies(tree);
+        if (sk_X509_POLICY_NODE_num(nodes) <= 0)
+            return -2;
+    }
 
-	error:
+    return 1;
 
-	X509_policy_tree_free(tree);
+ error:
 
-	return 0;
+    X509_policy_tree_free(tree);
 
-	}
+    return 0;
 
+}
diff --git a/src/crypto/x509v3/tab_test.c b/src/crypto/x509v3/tab_test.c
index c0e0cb6..1900547 100644
--- a/src/crypto/x509v3/tab_test.c
+++ b/src/crypto/x509v3/tab_test.c
@@ -1,6 +1,7 @@
 /* tabtest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -56,49 +57,52 @@
  *
  */
 
-/* Simple program to check the ext_dat.h is correct and print out
- * problems if it is not.
+/*
+ * Simple program to check the ext_dat.h is correct and print out problems if
+ * it is not.
  */
 
 #include <stdio.h>
 
 #include <openssl/base.h>
 #include <openssl/crypto.h>
+#include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
 #if !defined(BORINGSSL_SHARED_LIBRARY)
-#include "ext_dat.h"
+# include "ext_dat.h"
 #endif
 
 int main(void)
 {
 #if !defined(BORINGSSL_SHARED_LIBRARY)
-	unsigned i;
-	int prev = -1, bad = 0;
-	const X509V3_EXT_METHOD *const *tmp;
-        CRYPTO_library_init();
-	i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
-	if(i != STANDARD_EXTENSION_COUNT)
-		fprintf(stderr, "Extension number invalid expecting %d\n", i);
-	tmp = standard_exts;
-	for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
-		if((*tmp)->ext_nid < prev) bad = 1;
-		prev = (*tmp)->ext_nid;
-		
-	}
-	if(bad) {
-		tmp = standard_exts;
-		fprintf(stderr, "Extensions out of order!\n");
-		for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
-			printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
-		return 1;
-	} else {
-		printf("PASS\n");
-		return 0;
-	}
+    unsigned i;
+    int prev = -1, bad = 0;
+    const X509V3_EXT_METHOD *const *tmp;
+    CRYPTO_library_init();
+    i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
+    if (i != STANDARD_EXTENSION_COUNT)
+        fprintf(stderr, "Extension number invalid expecting %d\n", i);
+    tmp = standard_exts;
+    for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
+        if ((*tmp)->ext_nid < prev)
+            bad = 1;
+        prev = (*tmp)->ext_nid;
+
+    }
+    if (bad) {
+        tmp = standard_exts;
+        fprintf(stderr, "Extensions out of order!\n");
+        for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
+            printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
+        return 1;
+    } else {
+        printf("PASS\n");
+        return 0;
+    }
 #else
-	/* TODO(davidben): Fix this test in the shared library build. */
-	printf("PASS\n");
-	return 0;
+    /* TODO(davidben): Fix this test in the shared library build. */
+    printf("PASS\n");
+    return 0;
 #endif
 }
diff --git a/src/crypto/x509v3/v3_akey.c b/src/crypto/x509v3/v3_akey.c
index 9578a57..4503e61 100644
--- a/src/crypto/x509v3/v3_akey.c
+++ b/src/crypto/x509v3/v3_akey.c
@@ -1,6 +1,7 @@
 /* v3_akey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -65,148 +66,139 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
-			AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
+                                                 AUTHORITY_KEYID *akeyid,
+                                                 STACK_OF(CONF_VALUE)
+                                                 *extlist);
 static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
-			X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+                                            X509V3_CTX *ctx,
+                                            STACK_OF(CONF_VALUE) *values);
 
-const X509V3_EXT_METHOD v3_akey_id =
-	{
-	NID_authority_key_identifier,
-	X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
-	0,0,0,0,
-	0,0,
-	(X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
-	(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
-	0,0,
-	NULL
-	};
+const X509V3_EXT_METHOD v3_akey_id = {
+    NID_authority_key_identifier,
+    X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+    0, 0,
+    NULL
+};
 
 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
-	     AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist)
+                                                 AUTHORITY_KEYID *akeyid,
+                                                 STACK_OF(CONF_VALUE)
+                                                 *extlist)
 {
-	char *tmp;
-	if(akeyid->keyid) {
-		tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
-		X509V3_add_value("keyid", tmp, &extlist);
-		OPENSSL_free(tmp);
-	}
-	if(akeyid->issuer) 
-		extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
-	if(akeyid->serial) {
-		tmp = hex_to_string(akeyid->serial->data,
-						 akeyid->serial->length);
-		X509V3_add_value("serial", tmp, &extlist);
-		OPENSSL_free(tmp);
-	}
-	return extlist;
+    char *tmp;
+    if (akeyid->keyid) {
+        tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
+        X509V3_add_value("keyid", tmp, &extlist);
+        OPENSSL_free(tmp);
+    }
+    if (akeyid->issuer)
+        extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+    if (akeyid->serial) {
+        tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length);
+        X509V3_add_value("serial", tmp, &extlist);
+        OPENSSL_free(tmp);
+    }
+    return extlist;
 }
 
-/* Currently two options:
- * keyid: use the issuers subject keyid, the value 'always' means its is
- * an error if the issuer certificate doesn't have a key id.
- * issuer: use the issuers cert issuer and serial number. The default is
- * to only use this if keyid is not present. With the option 'always'
- * this is always included.
+/*
+ * Currently two options: keyid: use the issuers subject keyid, the value
+ * 'always' means its is an error if the issuer certificate doesn't have a
+ * key id. issuer: use the issuers cert issuer and serial number. The default
+ * is to only use this if keyid is not present. With the option 'always' this
+ * is always included.
  */
 
 static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
-	{
-	char keyid=0, issuer=0;
-	size_t i;
-	int j;
-	CONF_VALUE *cnf;
-	ASN1_OCTET_STRING *ikeyid = NULL;
-	X509_NAME *isname = NULL;
-	GENERAL_NAMES * gens = NULL;
-	GENERAL_NAME *gen = NULL;
-	ASN1_INTEGER *serial = NULL;
-	X509_EXTENSION *ext;
-	X509 *cert;
-	AUTHORITY_KEYID *akeyid;
+                                            X509V3_CTX *ctx,
+                                            STACK_OF(CONF_VALUE) *values)
+{
+    char keyid = 0, issuer = 0;
+    size_t i;
+    int j;
+    CONF_VALUE *cnf;
+    ASN1_OCTET_STRING *ikeyid = NULL;
+    X509_NAME *isname = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    ASN1_INTEGER *serial = NULL;
+    X509_EXTENSION *ext;
+    X509 *cert;
+    AUTHORITY_KEYID *akeyid;
 
-	for(i = 0; i < sk_CONF_VALUE_num(values); i++)
-		{
-		cnf = sk_CONF_VALUE_value(values, i);
-		if(!strcmp(cnf->name, "keyid"))
-			{
-			keyid = 1;
-			if(cnf->value && !strcmp(cnf->value, "always"))
-				keyid = 2;
-			}
-		else if(!strcmp(cnf->name, "issuer"))
-			{
-			issuer = 1;
-			if(cnf->value && !strcmp(cnf->value, "always"))
-				issuer = 2;
-			}
-		else
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
-			ERR_add_error_data(2, "name=", cnf->name);
-			return NULL;
-			}
-		}
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        cnf = sk_CONF_VALUE_value(values, i);
+        if (!strcmp(cnf->name, "keyid")) {
+            keyid = 1;
+            if (cnf->value && !strcmp(cnf->value, "always"))
+                keyid = 2;
+        } else if (!strcmp(cnf->name, "issuer")) {
+            issuer = 1;
+            if (cnf->value && !strcmp(cnf->value, "always"))
+                issuer = 2;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
+            ERR_add_error_data(2, "name=", cnf->name);
+            return NULL;
+        }
+    }
 
-	if(!ctx || !ctx->issuer_cert)
-		{
-		if(ctx && (ctx->flags==CTX_TEST))
-			return AUTHORITY_KEYID_new();
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
-		return NULL;
-		}
+    if (!ctx || !ctx->issuer_cert) {
+        if (ctx && (ctx->flags == CTX_TEST))
+            return AUTHORITY_KEYID_new();
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
+        return NULL;
+    }
 
-	cert = ctx->issuer_cert;
+    cert = ctx->issuer_cert;
 
-	if(keyid)
-		{
-		j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
-		if((j >= 0)  && (ext = X509_get_ext(cert, j)))
-			ikeyid = X509V3_EXT_d2i(ext);
-		if(keyid==2 && !ikeyid)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
-			return NULL;
-			}
-		}
+    if (keyid) {
+        j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+        if ((j >= 0) && (ext = X509_get_ext(cert, j)))
+            ikeyid = X509V3_EXT_d2i(ext);
+        if (keyid == 2 && !ikeyid) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+            return NULL;
+        }
+    }
 
-	if((issuer && !ikeyid) || (issuer == 2))
-		{
-		isname = X509_NAME_dup(X509_get_issuer_name(cert));
-		serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
-		if(!isname || !serial)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
-			goto err;
-			}
-		}
+    if ((issuer && !ikeyid) || (issuer == 2)) {
+        isname = X509_NAME_dup(X509_get_issuer_name(cert));
+        serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+        if (!isname || !serial) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+            goto err;
+        }
+    }
 
-	if(!(akeyid = AUTHORITY_KEYID_new())) goto err;
+    if (!(akeyid = AUTHORITY_KEYID_new()))
+        goto err;
 
-	if(isname)
-		{
-		if(!(gens = sk_GENERAL_NAME_new_null())
-			|| !(gen = GENERAL_NAME_new())
-			|| !sk_GENERAL_NAME_push(gens, gen))
-			{
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		gen->type = GEN_DIRNAME;
-		gen->d.dirn = isname;
-		}
+    if (isname) {
+        if (!(gens = sk_GENERAL_NAME_new_null())
+            || !(gen = GENERAL_NAME_new())
+            || !sk_GENERAL_NAME_push(gens, gen)) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen->type = GEN_DIRNAME;
+        gen->d.dirn = isname;
+    }
 
-	akeyid->issuer = gens;
-	akeyid->serial = serial;
-	akeyid->keyid = ikeyid;
+    akeyid->issuer = gens;
+    akeyid->serial = serial;
+    akeyid->keyid = ikeyid;
 
-	return akeyid;
+    return akeyid;
 
  err:
-	X509_NAME_free(isname);
-	M_ASN1_INTEGER_free(serial);
-	M_ASN1_OCTET_STRING_free(ikeyid);
-	return NULL;
-	}
+    X509_NAME_free(isname);
+    M_ASN1_INTEGER_free(serial);
+    M_ASN1_OCTET_STRING_free(ikeyid);
+    return NULL;
+}
diff --git a/src/crypto/x509v3/v3_akeya.c b/src/crypto/x509v3/v3_akeya.c
index 8b72cca..844dee5 100644
--- a/src/crypto/x509v3/v3_akeya.c
+++ b/src/crypto/x509v3/v3_akeya.c
@@ -1,6 +1,7 @@
 /* v3_akey_asn1.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -63,9 +64,9 @@
 
 
 ASN1_SEQUENCE(AUTHORITY_KEYID) = {
-	ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
-	ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
-	ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
+        ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
+        ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
+        ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
 } ASN1_SEQUENCE_END(AUTHORITY_KEYID)
 
 IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index cfc1348..152bd79 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -1,5 +1,6 @@
 /* v3_alt.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -63,560 +64,551 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval);
 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 
 const X509V3_EXT_METHOD v3_alt[] = {
-{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_subject_alt,
-NULL, NULL, NULL},
+    {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     (X509V3_EXT_V2I)v2i_subject_alt,
+     NULL, NULL, NULL},
 
-{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_issuer_alt,
-NULL, NULL, NULL},
+    {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     (X509V3_EXT_V2I)v2i_issuer_alt,
+     NULL, NULL, NULL},
 
-{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-NULL, NULL, NULL, NULL},
+    {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     NULL, NULL, NULL, NULL},
 };
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
-		GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret)
+                                        GENERAL_NAMES *gens,
+                                        STACK_OF(CONF_VALUE) *ret)
 {
-	size_t i;
-	GENERAL_NAME *gen;
-	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
-		gen = sk_GENERAL_NAME_value(gens, i);
-		ret = i2v_GENERAL_NAME(method, gen, ret);
-	}
-	if(!ret) return sk_CONF_VALUE_new_null();
-	return ret;
+    size_t i;
+    GENERAL_NAME *gen;
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        gen = sk_GENERAL_NAME_value(gens, i);
+        ret = i2v_GENERAL_NAME(method, gen, ret);
+    }
+    if (!ret)
+        return sk_CONF_VALUE_new_null();
+    return ret;
 }
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
-				GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
+                                       GENERAL_NAME *gen,
+                                       STACK_OF(CONF_VALUE) *ret)
 {
-	unsigned char *p;
-	char oline[256], htmp[5];
-	int i;
-	switch (gen->type)
-	{
-		case GEN_OTHERNAME:
-		X509V3_add_value("othername","<unsupported>", &ret);
-		break;
+    unsigned char *p;
+    char oline[256], htmp[5];
+    int i;
+    switch (gen->type) {
+    case GEN_OTHERNAME:
+        X509V3_add_value("othername", "<unsupported>", &ret);
+        break;
 
-		case GEN_X400:
-		X509V3_add_value("X400Name","<unsupported>", &ret);
-		break;
+    case GEN_X400:
+        X509V3_add_value("X400Name", "<unsupported>", &ret);
+        break;
 
-		case GEN_EDIPARTY:
-		X509V3_add_value("EdiPartyName","<unsupported>", &ret);
-		break;
+    case GEN_EDIPARTY:
+        X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
+        break;
 
-		case GEN_EMAIL:
-		X509V3_add_value_uchar("email",gen->d.ia5->data, &ret);
-		break;
+    case GEN_EMAIL:
+        X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
+        break;
 
-		case GEN_DNS:
-		X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret);
-		break;
+    case GEN_DNS:
+        X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
+        break;
 
-		case GEN_URI:
-		X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret);
-		break;
+    case GEN_URI:
+        X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
+        break;
 
-		case GEN_DIRNAME:
-		X509_NAME_oneline(gen->d.dirn, oline, 256);
-		X509V3_add_value("DirName",oline, &ret);
-		break;
+    case GEN_DIRNAME:
+        X509_NAME_oneline(gen->d.dirn, oline, 256);
+        X509V3_add_value("DirName", oline, &ret);
+        break;
 
-		case GEN_IPADD:
-		p = gen->d.ip->data;
-		if(gen->d.ip->length == 4)
-			BIO_snprintf(oline, sizeof oline,
-				     "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-		else if(gen->d.ip->length == 16)
-			{
-			oline[0] = 0;
-			for (i = 0; i < 8; i++)
-				{
-				BIO_snprintf(htmp, sizeof htmp,
-					     "%X", p[0] << 8 | p[1]);
-				p += 2;
-				strcat(oline, htmp);
-				if (i != 7)
-					strcat(oline, ":");
-				}
-			}
-		else
-			{
-			X509V3_add_value("IP Address","<invalid>", &ret);
-			break;
-			}
-		X509V3_add_value("IP Address",oline, &ret);
-		break;
+    case GEN_IPADD:
+        p = gen->d.ip->data;
+        if (gen->d.ip->length == 4)
+            BIO_snprintf(oline, sizeof oline,
+                         "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+        else if (gen->d.ip->length == 16) {
+            oline[0] = 0;
+            for (i = 0; i < 8; i++) {
+                BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
+                p += 2;
+                strcat(oline, htmp);
+                if (i != 7)
+                    strcat(oline, ":");
+            }
+        } else {
+            X509V3_add_value("IP Address", "<invalid>", &ret);
+            break;
+        }
+        X509V3_add_value("IP Address", oline, &ret);
+        break;
 
-		case GEN_RID:
-		i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
-		X509V3_add_value("Registered ID",oline, &ret);
-		break;
-	}
-	return ret;
+    case GEN_RID:
+        i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+        X509V3_add_value("Registered ID", oline, &ret);
+        break;
+    }
+    return ret;
 }
 
 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
 {
-	unsigned char *p;
-	int i;
-	switch (gen->type)
-	{
-		case GEN_OTHERNAME:
-		BIO_printf(out, "othername:<unsupported>");
-		break;
+    unsigned char *p;
+    int i;
+    switch (gen->type) {
+    case GEN_OTHERNAME:
+        BIO_printf(out, "othername:<unsupported>");
+        break;
 
-		case GEN_X400:
-		BIO_printf(out, "X400Name:<unsupported>");
-		break;
+    case GEN_X400:
+        BIO_printf(out, "X400Name:<unsupported>");
+        break;
 
-		case GEN_EDIPARTY:
-		/* Maybe fix this: it is supported now */
-		BIO_printf(out, "EdiPartyName:<unsupported>");
-		break;
+    case GEN_EDIPARTY:
+        /* Maybe fix this: it is supported now */
+        BIO_printf(out, "EdiPartyName:<unsupported>");
+        break;
 
-		case GEN_EMAIL:
-		BIO_printf(out, "email:%s",gen->d.ia5->data);
-		break;
+    case GEN_EMAIL:
+        BIO_printf(out, "email:%s", gen->d.ia5->data);
+        break;
 
-		case GEN_DNS:
-		BIO_printf(out, "DNS:%s",gen->d.ia5->data);
-		break;
+    case GEN_DNS:
+        BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+        break;
 
-		case GEN_URI:
-		BIO_printf(out, "URI:%s",gen->d.ia5->data);
-		break;
+    case GEN_URI:
+        BIO_printf(out, "URI:%s", gen->d.ia5->data);
+        break;
 
-		case GEN_DIRNAME:
-		BIO_printf(out, "DirName: ");
-		X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
-		break;
+    case GEN_DIRNAME:
+        BIO_printf(out, "DirName: ");
+        X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
+        break;
 
-		case GEN_IPADD:
-		p = gen->d.ip->data;
-		if(gen->d.ip->length == 4)
-			BIO_printf(out, "IP Address:%d.%d.%d.%d",
-						p[0], p[1], p[2], p[3]);
-		else if(gen->d.ip->length == 16)
-			{
-			BIO_printf(out, "IP Address");
-			for (i = 0; i < 8; i++)
-				{
-				BIO_printf(out, ":%X", p[0] << 8 | p[1]);
-				p += 2;
-				}
-			BIO_puts(out, "\n");
-			}
-		else
-			{
-			BIO_printf(out,"IP Address:<invalid>");
-			break;
-			}
-		break;
+    case GEN_IPADD:
+        p = gen->d.ip->data;
+        if (gen->d.ip->length == 4)
+            BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+        else if (gen->d.ip->length == 16) {
+            BIO_printf(out, "IP Address");
+            for (i = 0; i < 8; i++) {
+                BIO_printf(out, ":%X", p[0] << 8 | p[1]);
+                p += 2;
+            }
+            BIO_puts(out, "\n");
+        } else {
+            BIO_printf(out, "IP Address:<invalid>");
+            break;
+        }
+        break;
 
-		case GEN_RID:
-		BIO_printf(out, "Registered ID");
-		i2a_ASN1_OBJECT(out, gen->d.rid);
-		break;
-	}
-	return 1;
+    case GEN_RID:
+        BIO_printf(out, "Registered ID");
+        i2a_ASN1_OBJECT(out, gen->d.rid);
+        break;
+    }
+    return 1;
 }
 
 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval)
 {
-	GENERAL_NAMES *gens = NULL;
-	CONF_VALUE *cnf;
-	size_t i;
-	if(!(gens = sk_GENERAL_NAME_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!name_cmp(cnf->name, "issuer") && cnf->value &&
-						!strcmp(cnf->value, "copy")) {
-			if(!copy_issuer(ctx, gens)) goto err;
-		} else {
-			GENERAL_NAME *gen;
-			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
-								 goto err; 
-			sk_GENERAL_NAME_push(gens, gen);
-		}
-	}
-	return gens;
-	err:
-	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-	return NULL;
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    size_t i;
+    if (!(gens = sk_GENERAL_NAME_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!name_cmp(cnf->name, "issuer") && cnf->value &&
+            !strcmp(cnf->value, "copy")) {
+            if (!copy_issuer(ctx, gens))
+                goto err;
+        } else {
+            GENERAL_NAME *gen;
+            if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+                goto err;
+            sk_GENERAL_NAME_push(gens, gen);
+        }
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
 }
 
 /* Append subject altname of issuer to issuer alt name of subject */
 
 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
 {
-	GENERAL_NAMES *ialt;
-	GENERAL_NAME *gen;
-	X509_EXTENSION *ext;
-	int i;
-	size_t j;
-	if(ctx && (ctx->flags == CTX_TEST)) return 1;
-	if(!ctx || !ctx->issuer_cert) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
-		goto err;
-	}
-        i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
-	if(i < 0) return 1;
-        if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
-                        !(ialt = X509V3_EXT_d2i(ext)) ) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
-		goto err;
-	}
+    GENERAL_NAMES *ialt;
+    GENERAL_NAME *gen;
+    X509_EXTENSION *ext;
+    int i;
+    size_t j;
+    if (ctx && (ctx->flags == CTX_TEST))
+        return 1;
+    if (!ctx || !ctx->issuer_cert) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
+        goto err;
+    }
+    i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
+    if (i < 0)
+        return 1;
+    if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
+        !(ialt = X509V3_EXT_d2i(ext))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
+        goto err;
+    }
 
-	for(j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
-		gen = sk_GENERAL_NAME_value(ialt, j);
-		if(!sk_GENERAL_NAME_push(gens, gen)) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-	}
-	sk_GENERAL_NAME_free(ialt);
+    for (j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
+        gen = sk_GENERAL_NAME_value(ialt, j);
+        if (!sk_GENERAL_NAME_push(gens, gen)) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    sk_GENERAL_NAME_free(ialt);
 
-	return 1;
-		
-	err:
-	return 0;
-	
+    return 1;
+
+ err:
+    return 0;
+
 }
 
 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+                                      X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *nval)
 {
-	GENERAL_NAMES *gens = NULL;
-	CONF_VALUE *cnf;
-	size_t i;
-	if(!(gens = sk_GENERAL_NAME_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!name_cmp(cnf->name, "email") && cnf->value &&
-						!strcmp(cnf->value, "copy")) {
-			if(!copy_email(ctx, gens, 0)) goto err;
-		} else if(!name_cmp(cnf->name, "email") && cnf->value &&
-						!strcmp(cnf->value, "move")) {
-			if(!copy_email(ctx, gens, 1)) goto err;
-		} else {
-			GENERAL_NAME *gen;
-			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
-								 goto err; 
-			sk_GENERAL_NAME_push(gens, gen);
-		}
-	}
-	return gens;
-	err:
-	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-	return NULL;
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    size_t i;
+    if (!(gens = sk_GENERAL_NAME_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!name_cmp(cnf->name, "email") && cnf->value &&
+            !strcmp(cnf->value, "copy")) {
+            if (!copy_email(ctx, gens, 0))
+                goto err;
+        } else if (!name_cmp(cnf->name, "email") && cnf->value &&
+                   !strcmp(cnf->value, "move")) {
+            if (!copy_email(ctx, gens, 1))
+                goto err;
+        } else {
+            GENERAL_NAME *gen;
+            if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+                goto err;
+            sk_GENERAL_NAME_push(gens, gen);
+        }
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
 }
 
-/* Copy any email addresses in a certificate or request to 
- * GENERAL_NAMES
+/*
+ * Copy any email addresses in a certificate or request to GENERAL_NAMES
  */
 
 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
 {
-	X509_NAME *nm;
-	ASN1_IA5STRING *email = NULL;
-	X509_NAME_ENTRY *ne;
-	GENERAL_NAME *gen = NULL;
-	int i;
-	if(ctx != NULL && ctx->flags == CTX_TEST)
-		return 1;
-	if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
-		goto err;
-	}
-	/* Find the subject name */
-	if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
-	else nm = X509_REQ_get_subject_name(ctx->subject_req);
+    X509_NAME *nm;
+    ASN1_IA5STRING *email = NULL;
+    X509_NAME_ENTRY *ne;
+    GENERAL_NAME *gen = NULL;
+    int i;
+    if (ctx != NULL && ctx->flags == CTX_TEST)
+        return 1;
+    if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
+        goto err;
+    }
+    /* Find the subject name */
+    if (ctx->subject_cert)
+        nm = X509_get_subject_name(ctx->subject_cert);
+    else
+        nm = X509_REQ_get_subject_name(ctx->subject_req);
 
-	/* Now add any email address(es) to STACK */
-	i = -1;
-	while((i = X509_NAME_get_index_by_NID(nm,
-					 NID_pkcs9_emailAddress, i)) >= 0) {
-		ne = X509_NAME_get_entry(nm, i);
-		email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
-                if (move_p)
-                        {
-                        X509_NAME_delete_entry(nm, i);
-			X509_NAME_ENTRY_free(ne);
-                        i--;
-                        }
-		if(!email || !(gen = GENERAL_NAME_new())) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		gen->d.ia5 = email;
-		email = NULL;
-		gen->type = GEN_EMAIL;
-		if(!sk_GENERAL_NAME_push(gens, gen)) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		gen = NULL;
-	}
+    /* Now add any email address(es) to STACK */
+    i = -1;
+    while ((i = X509_NAME_get_index_by_NID(nm,
+                                           NID_pkcs9_emailAddress, i)) >= 0) {
+        ne = X509_NAME_get_entry(nm, i);
+        email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
+        if (move_p) {
+            X509_NAME_delete_entry(nm, i);
+            X509_NAME_ENTRY_free(ne);
+            i--;
+        }
+        if (!email || !(gen = GENERAL_NAME_new())) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen->d.ia5 = email;
+        email = NULL;
+        gen->type = GEN_EMAIL;
+        if (!sk_GENERAL_NAME_push(gens, gen)) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen = NULL;
+    }
 
-	
-	return 1;
-		
-	err:
-	GENERAL_NAME_free(gen);
-	M_ASN1_IA5STRING_free(email);
-	return 0;
-	
+    return 1;
+
+ err:
+    GENERAL_NAME_free(gen);
+    M_ASN1_IA5STRING_free(email);
+    return 0;
+
 }
 
 GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
-	GENERAL_NAME *gen;
-	GENERAL_NAMES *gens = NULL;
-	CONF_VALUE *cnf;
-	size_t i;
-	if(!(gens = sk_GENERAL_NAME_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
-		sk_GENERAL_NAME_push(gens, gen);
-	}
-	return gens;
-	err:
-	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-	return NULL;
+    GENERAL_NAME *gen;
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    size_t i;
+    if (!(gens = sk_GENERAL_NAME_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+            goto err;
+        sk_GENERAL_NAME_push(gens, gen);
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
 }
 
-GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-			       CONF_VALUE *cnf)
-	{
-	return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
-	}
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, CONF_VALUE *cnf)
+{
+    return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
+}
 
 GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
-			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-			       int gen_type, char *value, int is_nc)
-	{
-	char is_string = 0;
-	GENERAL_NAME *gen = NULL;
+                               const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, int gen_type, char *value,
+                               int is_nc)
+{
+    char is_string = 0;
+    GENERAL_NAME *gen = NULL;
 
-	if(!value)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
-		return NULL;
-		}
+    if (!value) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
+        return NULL;
+    }
 
-	if (out)
-		gen = out;
-	else
-		{
-		gen = GENERAL_NAME_new();
-		if(gen == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			return NULL;
-			}
-		}
+    if (out)
+        gen = out;
+    else {
+        gen = GENERAL_NAME_new();
+        if (gen == NULL) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    }
 
-	switch (gen_type)
-		{
-		case GEN_URI:
-		case GEN_EMAIL:
-		case GEN_DNS:
-		is_string = 1;
-		break;
-		
-		case GEN_RID:
-		{
-		ASN1_OBJECT *obj;
-		if(!(obj = OBJ_txt2obj(value,0)))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
-			ERR_add_error_data(2, "value=", value);
-			goto err;
-			}
-		gen->d.rid = obj;
-		}
-		break;
+    switch (gen_type) {
+    case GEN_URI:
+    case GEN_EMAIL:
+    case GEN_DNS:
+        is_string = 1;
+        break;
 
-		case GEN_IPADD:
-		if (is_nc)
-			gen->d.ip = a2i_IPADDRESS_NC(value);
-		else
-			gen->d.ip = a2i_IPADDRESS(value);
-		if(gen->d.ip == NULL)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
-			ERR_add_error_data(2, "value=", value);
-			goto err;
-			}
-		break;
+    case GEN_RID:
+        {
+            ASN1_OBJECT *obj;
+            if (!(obj = OBJ_txt2obj(value, 0))) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
+                ERR_add_error_data(2, "value=", value);
+                goto err;
+            }
+            gen->d.rid = obj;
+        }
+        break;
 
-		case GEN_DIRNAME:
-		if (!do_dirname(gen, value, ctx))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
-			goto err;
-			}
-		break;
+    case GEN_IPADD:
+        if (is_nc)
+            gen->d.ip = a2i_IPADDRESS_NC(value);
+        else
+            gen->d.ip = a2i_IPADDRESS(value);
+        if (gen->d.ip == NULL) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
+            ERR_add_error_data(2, "value=", value);
+            goto err;
+        }
+        break;
 
-		case GEN_OTHERNAME:
-		if (!do_othername(gen, value, ctx))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
-			goto err;
-			}
-		break;
-		default:
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
-		goto err;
-		}
+    case GEN_DIRNAME:
+        if (!do_dirname(gen, value, ctx)) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
+            goto err;
+        }
+        break;
 
-	if(is_string)
-		{
-		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
-			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
-					       strlen(value)))
-			{
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
+    case GEN_OTHERNAME:
+        if (!do_othername(gen, value, ctx)) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
+            goto err;
+        }
+        break;
+    default:
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
+        goto err;
+    }
 
-	gen->type = gen_type;
+    if (is_string) {
+        if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
+            !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
+                             strlen(value))) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
 
-	return gen;
+    gen->type = gen_type;
 
-	err:
-	if (!out)
-		GENERAL_NAME_free(gen);
-	return NULL;
-	}
+    return gen;
+
+ err:
+    if (!out)
+        GENERAL_NAME_free(gen);
+    return NULL;
+}
 
 GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
-				  const X509V3_EXT_METHOD *method,
-				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
-	{
-	int type;
+                                  const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+{
+    int type;
 
-	char *name, *value;
+    char *name, *value;
 
-	name = cnf->name;
-	value = cnf->value;
+    name = cnf->name;
+    value = cnf->value;
 
-	if(!value)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
-		return NULL;
-		}
+    if (!value) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
+        return NULL;
+    }
 
-	if(!name_cmp(name, "email"))
-		type = GEN_EMAIL;
-	else if(!name_cmp(name, "URI"))
-		type = GEN_URI;
-	else if(!name_cmp(name, "DNS"))
-		type = GEN_DNS;
-	else if(!name_cmp(name, "RID"))
-		type = GEN_RID;
-	else if(!name_cmp(name, "IP"))
-		type = GEN_IPADD;
-	else if(!name_cmp(name, "dirName"))
-		type = GEN_DIRNAME;
-	else if(!name_cmp(name, "otherName"))
-		type = GEN_OTHERNAME;
-	else
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
-		ERR_add_error_data(2, "name=", name);
-		return NULL;
-		}
+    if (!name_cmp(name, "email"))
+        type = GEN_EMAIL;
+    else if (!name_cmp(name, "URI"))
+        type = GEN_URI;
+    else if (!name_cmp(name, "DNS"))
+        type = GEN_DNS;
+    else if (!name_cmp(name, "RID"))
+        type = GEN_RID;
+    else if (!name_cmp(name, "IP"))
+        type = GEN_IPADD;
+    else if (!name_cmp(name, "dirName"))
+        type = GEN_DIRNAME;
+    else if (!name_cmp(name, "otherName"))
+        type = GEN_OTHERNAME;
+    else {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
+        ERR_add_error_data(2, "name=", name);
+        return NULL;
+    }
 
-	return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+    return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
 
-	}
+}
 
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
-	{
-	char *objtmp = NULL, *p;
-	int objlen;
-	if (!(p = strchr(value, ';')))
-		return 0;
-	if (!(gen->d.otherName = OTHERNAME_new()))
-		return 0;
-	/* Free this up because we will overwrite it.
-	 * no need to free type_id because it is static
-	 */
-	ASN1_TYPE_free(gen->d.otherName->value);
-	if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
-		return 0;
-	objlen = p - value;
-	objtmp = OPENSSL_malloc(objlen + 1);
-	if (objtmp == NULL)
-		return 0;
-	strncpy(objtmp, value, objlen);
-	objtmp[objlen] = 0;
-	gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
-	OPENSSL_free(objtmp);	
-	if (!gen->d.otherName->type_id)
-		return 0;
-	return 1;
-	}
+{
+    char *objtmp = NULL, *p;
+    int objlen;
+    if (!(p = strchr(value, ';')))
+        return 0;
+    if (!(gen->d.otherName = OTHERNAME_new()))
+        return 0;
+    /*
+     * Free this up because we will overwrite it. no need to free type_id
+     * because it is static
+     */
+    ASN1_TYPE_free(gen->d.otherName->value);
+    if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
+        return 0;
+    objlen = p - value;
+    objtmp = OPENSSL_malloc(objlen + 1);
+    if (objtmp == NULL)
+        return 0;
+    strncpy(objtmp, value, objlen);
+    objtmp[objlen] = 0;
+    gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
+    OPENSSL_free(objtmp);
+    if (!gen->d.otherName->type_id)
+        return 0;
+    return 1;
+}
 
 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
-	{
-	int ret = 0;
-	STACK_OF(CONF_VALUE) *sk = NULL;
-	X509_NAME *nm = X509_NAME_new();
-	if (nm == NULL)
-		goto err;
-	sk = X509V3_get_section(ctx, value);
-	if (sk == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
-		ERR_add_error_data(2, "section=", value);
-		goto err;
-		}
-	/* FIXME: should allow other character types... */
-	if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
-		goto err;
-	gen->d.dirn = nm;
-	ret = 1;
+{
+    int ret = 0;
+    STACK_OF(CONF_VALUE) *sk = NULL;
+    X509_NAME *nm = X509_NAME_new();
+    if (nm == NULL)
+        goto err;
+    sk = X509V3_get_section(ctx, value);
+    if (sk == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+        ERR_add_error_data(2, "section=", value);
+        goto err;
+    }
+    /* FIXME: should allow other character types... */
+    if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
+        goto err;
+    gen->d.dirn = nm;
+    ret = 1;
 
-err:
-	if (!ret)
-		X509_NAME_free(nm);
-	X509V3_section_free(ctx, sk);
-	return ret;
-	}
+ err:
+    if (!ret)
+        X509_NAME_free(nm);
+    X509V3_section_free(ctx, sk);
+    return ret;
+}
diff --git a/src/crypto/x509v3/v3_bcons.c b/src/crypto/x509v3/v3_bcons.c
index 73ef21e..aefefdf 100644
--- a/src/crypto/x509v3/v3_bcons.c
+++ b/src/crypto/x509v3/v3_bcons.c
@@ -1,6 +1,7 @@
 /* v3_bcons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 #include <string.h>
 
@@ -65,62 +65,69 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
-static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                   BASIC_CONSTRAINTS *bcons,
+                                                   STACK_OF(CONF_VALUE)
+                                                   *extlist);
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                X509V3_CTX *ctx,
+                                                STACK_OF(CONF_VALUE) *values);
 
 const X509V3_EXT_METHOD v3_bcons = {
-NID_basic_constraints, 0,
-ASN1_ITEM_ref(BASIC_CONSTRAINTS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
-(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
-NULL,NULL,
-NULL
+    NID_basic_constraints, 0,
+    ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS,
+    (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
+    NULL, NULL,
+    NULL
 };
 
 ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
-	ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
-	ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
+        ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
+        ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
 } ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
 
 IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
 
-
 static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
-	     BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist)
+                                                   BASIC_CONSTRAINTS *bcons,
+                                                   STACK_OF(CONF_VALUE)
+                                                   *extlist)
 {
-	X509V3_add_value_bool("CA", bcons->ca, &extlist);
-	X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
-	return extlist;
+    X509V3_add_value_bool("CA", bcons->ca, &extlist);
+    X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
+    return extlist;
 }
 
 static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
+                                                X509V3_CTX *ctx,
+                                                STACK_OF(CONF_VALUE) *values)
 {
-	BASIC_CONSTRAINTS *bcons=NULL;
-	CONF_VALUE *val;
-	size_t i;
-	if(!(bcons = BASIC_CONSTRAINTS_new())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
-		val = sk_CONF_VALUE_value(values, i);
-		if(!strcmp(val->name, "CA")) {
-			if(!X509V3_get_value_bool(val, &bcons->ca)) goto err;
-		} else if(!strcmp(val->name, "pathlen")) {
-			if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
-		} else {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
-			X509V3_conf_err(val);
-			goto err;
-		}
-	}
-	return bcons;
-	err:
-	BASIC_CONSTRAINTS_free(bcons);
-	return NULL;
+    BASIC_CONSTRAINTS *bcons = NULL;
+    CONF_VALUE *val;
+    size_t i;
+    if (!(bcons = BASIC_CONSTRAINTS_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        val = sk_CONF_VALUE_value(values, i);
+        if (!strcmp(val->name, "CA")) {
+            if (!X509V3_get_value_bool(val, &bcons->ca))
+                goto err;
+        } else if (!strcmp(val->name, "pathlen")) {
+            if (!X509V3_get_value_int(val, &bcons->pathlen))
+                goto err;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    return bcons;
+ err:
+    BASIC_CONSTRAINTS_free(bcons);
+    return NULL;
 }
-
diff --git a/src/crypto/x509v3/v3_bitst.c b/src/crypto/x509v3/v3_bitst.c
index e1e2087..86a8c36 100644
--- a/src/crypto/x509v3/v3_bitst.c
+++ b/src/crypto/x509v3/v3_bitst.c
@@ -1,6 +1,7 @@
 /* v3_bitst.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -62,80 +63,79 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static const BIT_STRING_BITNAME ns_cert_type_table[] = {
-{0, "SSL Client", "client"},
-{1, "SSL Server", "server"},
-{2, "S/MIME", "email"},
-{3, "Object Signing", "objsign"},
-{4, "Unused", "reserved"},
-{5, "SSL CA", "sslCA"},
-{6, "S/MIME CA", "emailCA"},
-{7, "Object Signing CA", "objCA"},
-{-1, NULL, NULL}
+    {0, "SSL Client", "client"},
+    {1, "SSL Server", "server"},
+    {2, "S/MIME", "email"},
+    {3, "Object Signing", "objsign"},
+    {4, "Unused", "reserved"},
+    {5, "SSL CA", "sslCA"},
+    {6, "S/MIME CA", "emailCA"},
+    {7, "Object Signing CA", "objCA"},
+    {-1, NULL, NULL}
 };
 
 static const BIT_STRING_BITNAME key_usage_type_table[] = {
-{0, "Digital Signature", "digitalSignature"},
-{1, "Non Repudiation", "nonRepudiation"},
-{2, "Key Encipherment", "keyEncipherment"},
-{3, "Data Encipherment", "dataEncipherment"},
-{4, "Key Agreement", "keyAgreement"},
-{5, "Certificate Sign", "keyCertSign"},
-{6, "CRL Sign", "cRLSign"},
-{7, "Encipher Only", "encipherOnly"},
-{8, "Decipher Only", "decipherOnly"},
-{-1, NULL, NULL}
+    {0, "Digital Signature", "digitalSignature"},
+    {1, "Non Repudiation", "nonRepudiation"},
+    {2, "Key Encipherment", "keyEncipherment"},
+    {3, "Data Encipherment", "dataEncipherment"},
+    {4, "Key Agreement", "keyAgreement"},
+    {5, "Certificate Sign", "keyCertSign"},
+    {6, "CRL Sign", "cRLSign"},
+    {7, "Encipher Only", "encipherOnly"},
+    {8, "Decipher Only", "decipherOnly"},
+    {-1, NULL, NULL}
 };
 
-
-
-const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
-const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+const X509V3_EXT_METHOD v3_nscert =
+EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage =
+EXT_BITSTRING(NID_key_usage, key_usage_type_table);
 
 STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
-	     ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
+                                          ASN1_BIT_STRING *bits,
+                                          STACK_OF(CONF_VALUE) *ret)
 {
-	const BIT_STRING_BITNAME *bnam;
-	for(bnam =method->usr_data; bnam->lname; bnam++) {
-		if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) 
-			X509V3_add_value(bnam->lname, NULL, &ret);
-	}
-	return ret;
+    const BIT_STRING_BITNAME *bnam;
+    for (bnam = method->usr_data; bnam->lname; bnam++) {
+        if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
+            X509V3_add_value(bnam->lname, NULL, &ret);
+    }
+    return ret;
 }
-	
-ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
-{
-	CONF_VALUE *val;
-	ASN1_BIT_STRING *bs;
-	size_t i;
-	const BIT_STRING_BITNAME *bnam;
-	if(!(bs = M_ASN1_BIT_STRING_new())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		val = sk_CONF_VALUE_value(nval, i);
-		for(bnam = method->usr_data; bnam->lname; bnam++) {
-			if(!strcmp(bnam->sname, val->name) ||
-				!strcmp(bnam->lname, val->name) ) {
-				if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
-					OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-					M_ASN1_BIT_STRING_free(bs);
-					return NULL;
-				}
-				break;
-			}
-		}
-		if(!bnam->lname) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
-			X509V3_conf_err(val);
-			M_ASN1_BIT_STRING_free(bs);
-			return NULL;
-		}
-	}
-	return bs;
-}
-	
 
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval)
+{
+    CONF_VALUE *val;
+    ASN1_BIT_STRING *bs;
+    size_t i;
+    const BIT_STRING_BITNAME *bnam;
+    if (!(bs = M_ASN1_BIT_STRING_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        for (bnam = method->usr_data; bnam->lname; bnam++) {
+            if (!strcmp(bnam->sname, val->name) ||
+                !strcmp(bnam->lname, val->name)) {
+                if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
+                    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+                    M_ASN1_BIT_STRING_free(bs);
+                    return NULL;
+                }
+                break;
+            }
+        }
+        if (!bnam->lname) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+            X509V3_conf_err(val);
+            M_ASN1_BIT_STRING_free(bs);
+            return NULL;
+        }
+    }
+    return bs;
+}
diff --git a/src/crypto/x509v3/v3_conf.c b/src/crypto/x509v3/v3_conf.c
index fe71566..66abca4 100644
--- a/src/crypto/x509v3/v3_conf.c
+++ b/src/crypto/x509v3/v3_conf.c
@@ -1,6 +1,7 @@
 /* v3_conf.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -69,391 +70,391 @@
 
 #include "../internal.h"
 
-
 static int v3_check_critical(char **value);
 static int v3_check_generic(char **value);
-static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
-static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
-static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
-				  int crit, void *ext_struc);
-static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                    int crit, char *value);
+static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
+                                            int crit, int type,
+                                            X509V3_CTX *ctx);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+                                  int ext_nid, int crit, void *ext_struc);
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
+                                   long *ext_len);
 /* CONF *conf:  Config file    */
 /* char *name:  Name    */
 /* char *value:  Value    */
 X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
-				 char *value)
-	{
-	int crit;
-	int ext_type;
-	X509_EXTENSION *ret;
-	crit = v3_check_critical(&value);
-	if ((ext_type = v3_check_generic(&value))) 
-		return v3_generic_extension(name, value, crit, ext_type, ctx);
-	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
-	if (!ret)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
-		ERR_add_error_data(4,"name=", name, ", value=", value);
-		}
-	return ret;
-	}
+                                 char *value)
+{
+    int crit;
+    int ext_type;
+    X509_EXTENSION *ret;
+    crit = v3_check_critical(&value);
+    if ((ext_type = v3_check_generic(&value)))
+        return v3_generic_extension(name, value, crit, ext_type, ctx);
+    ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
+    if (!ret) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
+        ERR_add_error_data(4, "name=", name, ", value=", value);
+    }
+    return ret;
+}
 
 /* CONF *conf:  Config file    */
 /* char *value:  Value    */
 X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
-				     char *value)
-	{
-	int crit;
-	int ext_type;
-	crit = v3_check_critical(&value);
-	if ((ext_type = v3_check_generic(&value))) 
-		return v3_generic_extension(OBJ_nid2sn(ext_nid),
-						 value, crit, ext_type, ctx);
-	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
-	}
+                                     char *value)
+{
+    int crit;
+    int ext_type;
+    crit = v3_check_critical(&value);
+    if ((ext_type = v3_check_generic(&value)))
+        return v3_generic_extension(OBJ_nid2sn(ext_nid),
+                                    value, crit, ext_type, ctx);
+    return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+}
 
 /* CONF *conf:  Config file    */
 /* char *value:  Value    */
 static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
-				    int crit, char *value)
-	{
-	const X509V3_EXT_METHOD *method;
-	X509_EXTENSION *ext;
-	STACK_OF(CONF_VALUE) *nval;
-	void *ext_struc;
-	if (ext_nid == NID_undef)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
-		return NULL;
-		}
-	if (!(method = X509V3_EXT_get_nid(ext_nid)))
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
-		return NULL;
-		}
-	/* Now get internal extension representation based on type */
-	if (method->v2i)
-		{
-		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
-		else nval = X509V3_parse_list(value);
-		if(sk_CONF_VALUE_num(nval) <= 0)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
-			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
-			return NULL;
-			}
-		ext_struc = method->v2i(method, ctx, nval);
-		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
-							 X509V3_conf_free);
-		if(!ext_struc) return NULL;
-		}
-	else if(method->s2i)
-		{
-		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
-		}
-	else if(method->r2i)
-		{
-		if(!ctx->db || !ctx->db_meth)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
-			return NULL;
-			}
-		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
-		}
-	else
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
-		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
-		return NULL;
-		}
+                                    int crit, char *value)
+{
+    const X509V3_EXT_METHOD *method;
+    X509_EXTENSION *ext;
+    STACK_OF(CONF_VALUE) *nval;
+    void *ext_struc;
+    if (ext_nid == NID_undef) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
+        return NULL;
+    }
+    if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
+        return NULL;
+    }
+    /* Now get internal extension representation based on type */
+    if (method->v2i) {
+        if (*value == '@')
+            nval = NCONF_get_section(conf, value + 1);
+        else
+            nval = X509V3_parse_list(value);
+        if (sk_CONF_VALUE_num(nval) <= 0) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
+            ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
+                               value);
+            return NULL;
+        }
+        ext_struc = method->v2i(method, ctx, nval);
+        if (*value != '@')
+            sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+        if (!ext_struc)
+            return NULL;
+    } else if (method->s2i) {
+        if (!(ext_struc = method->s2i(method, ctx, value)))
+            return NULL;
+    } else if (method->r2i) {
+        if (!ctx->db || !ctx->db_meth) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
+            return NULL;
+        }
+        if (!(ext_struc = method->r2i(method, ctx, value)))
+            return NULL;
+    } else {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+        ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+        return NULL;
+    }
 
-	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
-	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
-	else method->ext_free(ext_struc);
-	return ext;
+    ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
+    if (method->it)
+        ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+    else
+        method->ext_free(ext_struc);
+    return ext;
 
-	}
+}
 
-static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
-				  int crit, void *ext_struc)
-	{
-	unsigned char *ext_der;
-	int ext_len;
-	ASN1_OCTET_STRING *ext_oct;
-	X509_EXTENSION *ext;
-	/* Convert internal representation to DER */
-	if (method->it)
-		{
-		ext_der = NULL;
-		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
-		if (ext_len < 0) goto merr;
-		}
-	 else
-		{
-		unsigned char *p;
-		ext_len = method->i2d(ext_struc, NULL);
-		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
-		p = ext_der;
-		method->i2d(ext_struc, &p);
-		}
-	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
-	ext_oct->data = ext_der;
-	ext_oct->length = ext_len;
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+                                  int ext_nid, int crit, void *ext_struc)
+{
+    unsigned char *ext_der;
+    int ext_len;
+    ASN1_OCTET_STRING *ext_oct;
+    X509_EXTENSION *ext;
+    /* Convert internal representation to DER */
+    if (method->it) {
+        ext_der = NULL;
+        ext_len =
+            ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
+        if (ext_len < 0)
+            goto merr;
+    } else {
+        unsigned char *p;
+        ext_len = method->i2d(ext_struc, NULL);
+        if (!(ext_der = OPENSSL_malloc(ext_len)))
+            goto merr;
+        p = ext_der;
+        method->i2d(ext_struc, &p);
+    }
+    if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
+        goto merr;
+    ext_oct->data = ext_der;
+    ext_oct->length = ext_len;
 
-	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
-	if (!ext) goto merr;
-	M_ASN1_OCTET_STRING_free(ext_oct);
+    ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
+    if (!ext)
+        goto merr;
+    M_ASN1_OCTET_STRING_free(ext_oct);
 
-	return ext;
+    return ext;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	return NULL;
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    return NULL;
 
-	}
+}
 
 /* Given an internal structure, nid and critical flag create an extension */
 
 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
-	{
-	const X509V3_EXT_METHOD *method;
-	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
-		return NULL;
-	}
-	return do_ext_i2d(method, ext_nid, crit, ext_struc);
+{
+    const X509V3_EXT_METHOD *method;
+    if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
+        return NULL;
+    }
+    return do_ext_i2d(method, ext_nid, crit, ext_struc);
 }
 
 /* Check the extension string for critical flag */
 static int v3_check_critical(char **value)
 {
-	char *p = *value;
-	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
-	p+=9;
-	while(isspace((unsigned char)*p)) p++;
-	*value = p;
-	return 1;
+    char *p = *value;
+    if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
+        return 0;
+    p += 9;
+    while (isspace((unsigned char)*p))
+        p++;
+    *value = p;
+    return 1;
 }
 
 /* Check extension string for generic extension and return the type */
 static int v3_check_generic(char **value)
 {
-	int gen_type = 0;
-	char *p = *value;
-	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
-		{
-		p+=4;
-		gen_type = 1;
-		}
-	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
-		{
-		p+=5;
-		gen_type = 2;
-		}
-	else
-		return 0;
+    int gen_type = 0;
+    char *p = *value;
+    if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
+        p += 4;
+        gen_type = 1;
+    } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
+        p += 5;
+        gen_type = 2;
+    } else
+        return 0;
 
-	while (isspace((unsigned char)*p)) p++;
-	*value = p;
-	return gen_type;
+    while (isspace((unsigned char)*p))
+        p++;
+    *value = p;
+    return gen_type;
 }
 
 /* Create a generic extension: for now just handle DER type */
 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
-					    int crit, int gen_type,
-					    X509V3_CTX *ctx)
-        OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-	{
-	unsigned char *ext_der=NULL;
-	long ext_len;
-	ASN1_OBJECT *obj=NULL;
-	ASN1_OCTET_STRING *oct=NULL;
-	X509_EXTENSION *extension=NULL;
-	if (!(obj = OBJ_txt2obj(ext, 0)))
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
-		ERR_add_error_data(2, "name=", ext);
-		goto err;
-		}
+                                            int crit, int gen_type,
+                                            X509V3_CTX *ctx)
+{
+    unsigned char *ext_der = NULL;
+    long ext_len = 0;
+    ASN1_OBJECT *obj = NULL;
+    ASN1_OCTET_STRING *oct = NULL;
+    X509_EXTENSION *extension = NULL;
+    if (!(obj = OBJ_txt2obj(ext, 0))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
+        ERR_add_error_data(2, "name=", ext);
+        goto err;
+    }
 
-	if (gen_type == 1)
-		ext_der = string_to_hex(value, &ext_len);
-	else if (gen_type == 2)
-		ext_der = generic_asn1(value, ctx, &ext_len);
+    if (gen_type == 1)
+        ext_der = string_to_hex(value, &ext_len);
+    else if (gen_type == 2)
+        ext_der = generic_asn1(value, ctx, &ext_len);
 
-	if (ext_der == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
-		ERR_add_error_data(2, "value=", value);
-		goto err;
-		}
+    if (ext_der == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
+        ERR_add_error_data(2, "value=", value);
+        goto err;
+    }
 
-	if (!(oct = M_ASN1_OCTET_STRING_new()))
-		{
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    if (!(oct = M_ASN1_OCTET_STRING_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	oct->data = ext_der;
-	oct->length = ext_len;
-	ext_der = NULL;
+    oct->data = ext_der;
+    oct->length = ext_len;
+    ext_der = NULL;
 
-	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
+    extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
 
-	err:
-	ASN1_OBJECT_free(obj);
-	M_ASN1_OCTET_STRING_free(oct);
-	if(ext_der) OPENSSL_free(ext_der);
-	return extension;
+ err:
+    ASN1_OBJECT_free(obj);
+    M_ASN1_OCTET_STRING_free(oct);
+    if (ext_der)
+        OPENSSL_free(ext_der);
+    return extension;
 
-	}
+}
 
-static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
-	{
-	ASN1_TYPE *typ;
-	unsigned char *ext_der = NULL;
-	typ = ASN1_generate_v3(value, ctx);
-	if (typ == NULL)
-		return NULL;
-	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
-	ASN1_TYPE_free(typ);
-	return ext_der;
-	}
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
+                                   long *ext_len)
+{
+    ASN1_TYPE *typ;
+    unsigned char *ext_der = NULL;
+    typ = ASN1_generate_v3(value, ctx);
+    if (typ == NULL)
+        return NULL;
+    *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
+    ASN1_TYPE_free(typ);
+    return ext_der;
+}
 
-/* This is the main function: add a bunch of extensions based on a config file
- * section to an extension STACK.
+/*
+ * This is the main function: add a bunch of extensions based on a config
+ * file section to an extension STACK.
  */
 
-
 int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
-			    STACK_OF(X509_EXTENSION) **sk)
-	{
-	X509_EXTENSION *ext;
-	STACK_OF(CONF_VALUE) *nval;
-	CONF_VALUE *val;	
-	size_t i;
-	if (!(nval = NCONF_get_section(conf, section))) return 0;
-	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
-		{
-		val = sk_CONF_VALUE_value(nval, i);
-		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
-								return 0;
-		if (sk) X509v3_add_ext(sk, ext, -1);
-		X509_EXTENSION_free(ext);
-		}
-	return 1;
-	}
+                            STACK_OF(X509_EXTENSION) **sk)
+{
+    X509_EXTENSION *ext;
+    STACK_OF(CONF_VALUE) *nval;
+    CONF_VALUE *val;
+    size_t i;
+    if (!(nval = NCONF_get_section(conf, section)))
+        return 0;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
+            return 0;
+        if (sk)
+            X509v3_add_ext(sk, ext, -1);
+        X509_EXTENSION_free(ext);
+    }
+    return 1;
+}
 
-/* Convenience functions to add extensions to a certificate, CRL and request */
+/*
+ * Convenience functions to add extensions to a certificate, CRL and request
+ */
 
 int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
-			 X509 *cert)
-	{
-	STACK_OF(X509_EXTENSION) **sk = NULL;
-	if (cert)
-		sk = &cert->cert_info->extensions;
-	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
-	}
+                         X509 *cert)
+{
+    STACK_OF(X509_EXTENSION) **sk = NULL;
+    if (cert)
+        sk = &cert->cert_info->extensions;
+    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
 
 /* Same as above but for a CRL */
 
 int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
-			     X509_CRL *crl)
-	{
-	STACK_OF(X509_EXTENSION) **sk = NULL;
-	if (crl)
-		sk = &crl->crl->extensions;
-	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
-	}
+                             X509_CRL *crl)
+{
+    STACK_OF(X509_EXTENSION) **sk = NULL;
+    if (crl)
+        sk = &crl->crl->extensions;
+    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
 
 /* Add extensions to certificate request */
 
 int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
-	     X509_REQ *req)
-	{
-	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
-	int i;
-	if (req)
-		sk = &extlist;
-	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
-	if (!i || !sk)
-		return i;
-	i = X509_REQ_add_extensions(req, extlist);
-	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
-	return i;
-	}
+                             X509_REQ *req)
+{
+    STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
+    int i;
+    if (req)
+        sk = &extlist;
+    i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+    if (!i || !sk)
+        return i;
+    i = X509_REQ_add_extensions(req, extlist);
+    sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
+    return i;
+}
 
 /* Config database functions */
 
-char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
-	{
-	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
-		return NULL;
-		}
-	if (ctx->db_meth->get_string)
-			return ctx->db_meth->get_string(ctx->db, name, section);
-	return NULL;
-	}
+char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
+{
+    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
+        return NULL;
+    }
+    if (ctx->db_meth->get_string)
+        return ctx->db_meth->get_string(ctx->db, name, section);
+    return NULL;
+}
 
-STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
-	{
-	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
-		return NULL;
-		}
-	if (ctx->db_meth->get_section)
-			return ctx->db_meth->get_section(ctx->db, section);
-	return NULL;
-	}
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section)
+{
+    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
+        return NULL;
+    }
+    if (ctx->db_meth->get_section)
+        return ctx->db_meth->get_section(ctx->db, section);
+    return NULL;
+}
 
 void X509V3_string_free(X509V3_CTX *ctx, char *str)
-	{
-	if (!str) return;
-	if (ctx->db_meth->free_string)
-			ctx->db_meth->free_string(ctx->db, str);
-	}
+{
+    if (!str)
+        return;
+    if (ctx->db_meth->free_string)
+        ctx->db_meth->free_string(ctx->db, str);
+}
 
 void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
-	{
-	if (!section) return;
-	if (ctx->db_meth->free_section)
-			ctx->db_meth->free_section(ctx->db, section);
-	}
+{
+    if (!section)
+        return;
+    if (ctx->db_meth->free_section)
+        ctx->db_meth->free_section(ctx->db, section);
+}
 
 static char *nconf_get_string(void *db, char *section, char *value)
-	{
-        /* TODO(fork): this should return a const value. */
-	return (char *) NCONF_get_string(db, section, value);
-	}
+{
+    /* TODO(fork): this should return a const value. */
+    return (char *)NCONF_get_string(db, section, value);
+}
 
 static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
-	{
-	return NCONF_get_section(db, section);
-	}
+{
+    return NCONF_get_section(db, section);
+}
 
 static const X509V3_CONF_METHOD nconf_method = {
-nconf_get_string,
-nconf_get_section,
-NULL,
-NULL
+    nconf_get_string,
+    nconf_get_section,
+    NULL,
+    NULL
 };
 
 void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
-	{
-	ctx->db_meth = &nconf_method;
-	ctx->db = conf;
-	}
+{
+    ctx->db_meth = &nconf_method;
+    ctx->db = conf;
+}
 
 void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
-		    X509_CRL *crl, int flags)
-	{
-	ctx->issuer_cert = issuer;
-	ctx->subject_cert = subj;
-	ctx->crl = crl;
-	ctx->subject_req = req;
-	ctx->flags = flags;
-	}
-
+                    X509_CRL *crl, int flags)
+{
+    ctx->issuer_cert = issuer;
+    ctx->subject_cert = subj;
+    ctx->crl = crl;
+    ctx->subject_req = req;
+    ctx->flags = flags;
+}
diff --git a/src/crypto/x509v3/v3_cpols.c b/src/crypto/x509v3/v3_cpols.c
index 0b58676..d67dcb0 100644
--- a/src/crypto/x509v3/v3_cpols.c
+++ b/src/crypto/x509v3/v3_cpols.c
@@ -1,6 +1,7 @@
 /* v3_cpols.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -72,35 +73,38 @@
 
 /* Certificate policies extension support: this one is a bit complex... */
 
-static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
-static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
-static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+                       BIO *out, int indent);
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, char *value);
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+                             int indent);
 static void print_notice(BIO *out, USERNOTICE *notice, int indent);
 static POLICYINFO *policy_section(X509V3_CTX *ctx,
-				 STACK_OF(CONF_VALUE) *polstrs, int ia5org);
+                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org);
 static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
-					STACK_OF(CONF_VALUE) *unot, int ia5org);
+                                      STACK_OF(CONF_VALUE) *unot, int ia5org);
 static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
 
 const X509V3_EXT_METHOD v3_cpols = {
-NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
-0,0,0,0,
-0,0,
-0,0,
-(X509V3_EXT_I2R)i2r_certpol,
-(X509V3_EXT_R2I)r2i_certpol,
-NULL
+    NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    (X509V3_EXT_I2R)i2r_certpol,
+    (X509V3_EXT_R2I)r2i_certpol,
+    NULL
 };
 
-ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
 ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
 
 IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
 
 ASN1_SEQUENCE(POLICYINFO) = {
-	ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
-	ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
+        ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
+        ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
 } ASN1_SEQUENCE_END(POLICYINFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
@@ -108,368 +112,385 @@
 ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
 
 ASN1_ADB(POLICYQUALINFO) = {
-	ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
-	ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
+        ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
+        ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
 } ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
 
 ASN1_SEQUENCE(POLICYQUALINFO) = {
-	ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
-	ASN1_ADB_OBJECT(POLICYQUALINFO)
+        ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(POLICYQUALINFO)
 } ASN1_SEQUENCE_END(POLICYQUALINFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
 
 ASN1_SEQUENCE(USERNOTICE) = {
-	ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
-	ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
+        ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
+        ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
 } ASN1_SEQUENCE_END(USERNOTICE)
 
 IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
 
 ASN1_SEQUENCE(NOTICEREF) = {
-	ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
-	ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
+        ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
+        ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
 } ASN1_SEQUENCE_END(NOTICEREF)
 
 IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
 
 static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
-		X509V3_CTX *ctx, char *value)
+                                         X509V3_CTX *ctx, char *value)
 {
-	STACK_OF(POLICYINFO) *pols = NULL;
-	char *pstr;
-	POLICYINFO *pol;
-	ASN1_OBJECT *pobj;
-	STACK_OF(CONF_VALUE) *vals;
-	CONF_VALUE *cnf;
-	size_t i;
-	int ia5org;
-	pols = sk_POLICYINFO_new_null();
-	if (pols == NULL) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	vals =  X509V3_parse_list(value);
-	if (vals == NULL) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB);
-		goto err;
-	}
-	ia5org = 0;
-	for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
-		cnf = sk_CONF_VALUE_value(vals, i);
-		if(cnf->value || !cnf->name ) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER);
-			X509V3_conf_err(cnf);
-			goto err;
-		}
-		pstr = cnf->name;
-		if(!strcmp(pstr,"ia5org")) {
-			ia5org = 1;
-			continue;
-		} else if(*pstr == '@') {
-			STACK_OF(CONF_VALUE) *polsect;
-			polsect = X509V3_get_section(ctx, pstr + 1);
-			if(!polsect) {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
+    STACK_OF(POLICYINFO) *pols = NULL;
+    char *pstr;
+    POLICYINFO *pol;
+    ASN1_OBJECT *pobj;
+    STACK_OF(CONF_VALUE) *vals;
+    CONF_VALUE *cnf;
+    size_t i;
+    int ia5org;
+    pols = sk_POLICYINFO_new_null();
+    if (pols == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    vals = X509V3_parse_list(value);
+    if (vals == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB);
+        goto err;
+    }
+    ia5org = 0;
+    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+        cnf = sk_CONF_VALUE_value(vals, i);
+        if (cnf->value || !cnf->name) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+        pstr = cnf->name;
+        if (!strcmp(pstr, "ia5org")) {
+            ia5org = 1;
+            continue;
+        } else if (*pstr == '@') {
+            STACK_OF(CONF_VALUE) *polsect;
+            polsect = X509V3_get_section(ctx, pstr + 1);
+            if (!polsect) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
 
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			pol = policy_section(ctx, polsect, ia5org);
-			X509V3_section_free(ctx, polsect);
-			if(!pol) goto err;
-		} else {
-			if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			pol = POLICYINFO_new();
-			pol->policyid = pobj;
-		}
-		if (!sk_POLICYINFO_push(pols, pol)){
-			POLICYINFO_free(pol);
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-	}
-	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
-	return pols;
-	err:
-	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
-	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
-	return NULL;
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol = policy_section(ctx, polsect, ia5org);
+            X509V3_section_free(ctx, polsect);
+            if (!pol)
+                goto err;
+        } else {
+            if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol = POLICYINFO_new();
+            if (pol == NULL) {
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+                ASN1_OBJECT_free(pobj);
+                goto err;
+            }
+            pol->policyid = pobj;
+        }
+        if (!sk_POLICYINFO_push(pols, pol)) {
+            POLICYINFO_free(pol);
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    return pols;
+ err:
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
+    return NULL;
 }
 
 static POLICYINFO *policy_section(X509V3_CTX *ctx,
-				STACK_OF(CONF_VALUE) *polstrs, int ia5org)
+                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org)
 {
-	size_t i;
-	CONF_VALUE *cnf;
-	POLICYINFO *pol;
-	POLICYQUALINFO *qual;
-	if(!(pol = POLICYINFO_new())) goto merr;
-	for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
-		cnf = sk_CONF_VALUE_value(polstrs, i);
-		if(!strcmp(cnf->name, "policyIdentifier")) {
-			ASN1_OBJECT *pobj;
-			if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			pol->policyid = pobj;
+    size_t i;
+    CONF_VALUE *cnf;
+    POLICYINFO *pol;
+    POLICYQUALINFO *qual;
+    if (!(pol = POLICYINFO_new()))
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
+        cnf = sk_CONF_VALUE_value(polstrs, i);
+        if (!strcmp(cnf->name, "policyIdentifier")) {
+            ASN1_OBJECT *pobj;
+            if (!(pobj = OBJ_txt2obj(cnf->value, 0))) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol->policyid = pobj;
 
-		} else if(!name_cmp(cnf->name, "CPS")) {
-			if(!pol->qualifiers) pol->qualifiers =
-						 sk_POLICYQUALINFO_new_null();
-			if(!(qual = POLICYQUALINFO_new())) goto merr;
-			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
-								 goto merr;
-                        /* TODO(fork): const correctness */
-			qual->pqualid = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_qt_cps);
-			if (qual->pqualid == NULL) {
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
-				goto err;
-			}
-			qual->d.cpsuri = M_ASN1_IA5STRING_new();
-			if (qual->d.cpsuri == NULL) {
-				goto err;
-			}
-			if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
-						 strlen(cnf->value))) goto merr;
-		} else if(!name_cmp(cnf->name, "userNotice")) {
-			STACK_OF(CONF_VALUE) *unot;
-			if(*cnf->value != '@') {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME);
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			unot = X509V3_get_section(ctx, cnf->value + 1);
-			if(!unot) {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
+        } else if (!name_cmp(cnf->name, "CPS")) {
+            if (!pol->qualifiers)
+                pol->qualifiers = sk_POLICYQUALINFO_new_null();
+            if (!(qual = POLICYQUALINFO_new()))
+                goto merr;
+            if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+                goto merr;
+            /* TODO(fork): const correctness */
+            qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_cps);
+            if (qual->pqualid == NULL) {
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            qual->d.cpsuri = M_ASN1_IA5STRING_new();
+            if (qual->d.cpsuri == NULL) {
+                goto err;
+            }
+            if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (!name_cmp(cnf->name, "userNotice")) {
+            STACK_OF(CONF_VALUE) *unot;
+            if (*cnf->value != '@') {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            unot = X509V3_get_section(ctx, cnf->value + 1);
+            if (!unot) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
 
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			qual = notice_section(ctx, unot, ia5org);
-			X509V3_section_free(ctx, unot);
-			if(!qual) goto err;
-			if(!pol->qualifiers) pol->qualifiers =
-						 sk_POLICYQUALINFO_new_null();
-			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
-								 goto merr;
-		} else {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            qual = notice_section(ctx, unot, ia5org);
+            X509V3_section_free(ctx, unot);
+            if (!qual)
+                goto err;
+            if (!pol->qualifiers)
+                pol->qualifiers = sk_POLICYQUALINFO_new_null();
+            if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+                goto merr;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
 
-			X509V3_conf_err(cnf);
-			goto err;
-		}
-	}
-	if(!pol->policyid) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
-		goto err;
-	}
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
+    if (!pol->policyid) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
+        goto err;
+    }
 
-	return pol;
+    return pol;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
 
-	err:
-	POLICYINFO_free(pol);
-	return NULL;
-	
-	
+ err:
+    POLICYINFO_free(pol);
+    return NULL;
+
 }
 
 static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
-					STACK_OF(CONF_VALUE) *unot, int ia5org)
+                                      STACK_OF(CONF_VALUE) *unot, int ia5org)
 {
-	size_t i;
-	int ret;
-	CONF_VALUE *cnf;
-	USERNOTICE *not;
-	POLICYQUALINFO *qual;
-	if(!(qual = POLICYQUALINFO_new())) goto merr;
-        /* TODO(fork): const correctness */
-	qual->pqualid = (ASN1_OBJECT *) OBJ_nid2obj(NID_id_qt_unotice);
-	if (qual->pqualid == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
-		goto err;
-		}
-	if(!(not = USERNOTICE_new())) goto merr;
-	qual->d.usernotice = not;
-	for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
-		cnf = sk_CONF_VALUE_value(unot, i);
-		if(!strcmp(cnf->name, "explicitText")) {
-			not->exptext = M_ASN1_VISIBLESTRING_new();
-			if (not->exptext == NULL)
-				goto merr;
-			if(!ASN1_STRING_set(not->exptext, cnf->value,
-						 strlen(cnf->value))) goto merr;
-		} else if(!strcmp(cnf->name, "organization")) {
-			NOTICEREF *nref;
-			if(!not->noticeref) {
-				if(!(nref = NOTICEREF_new())) goto merr;
-				not->noticeref = nref;
-			} else nref = not->noticeref;
-			if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
-			else nref->organization->type = V_ASN1_VISIBLESTRING;
-			if(!ASN1_STRING_set(nref->organization, cnf->value,
-						 strlen(cnf->value))) goto merr;
-		} else if(!strcmp(cnf->name, "noticeNumbers")) {
-			NOTICEREF *nref;
-			STACK_OF(CONF_VALUE) *nos;
-			if(!not->noticeref) {
-				if(!(nref = NOTICEREF_new())) goto merr;
-				not->noticeref = nref;
-			} else nref = not->noticeref;
-			nos = X509V3_parse_list(cnf->value);
-			if(!nos || !sk_CONF_VALUE_num(nos)) {
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
-				X509V3_conf_err(cnf);
-				goto err;
-			}
-			ret = nref_nos(nref->noticenos, nos);
-			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
-			if (!ret)
-				goto err;
-		} else {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
-			X509V3_conf_err(cnf);
-			goto err;
-		}
-	}
+    size_t i;
+    int ret;
+    CONF_VALUE *cnf;
+    USERNOTICE *not;
+    POLICYQUALINFO *qual;
+    if (!(qual = POLICYQUALINFO_new()))
+        goto merr;
+    /* TODO(fork): const correctness */
+    qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_unotice);
+    if (qual->pqualid == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if (!(not = USERNOTICE_new()))
+        goto merr;
+    qual->d.usernotice = not;
+    for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
+        cnf = sk_CONF_VALUE_value(unot, i);
+        if (!strcmp(cnf->name, "explicitText")) {
+            not->exptext = M_ASN1_VISIBLESTRING_new();
+            if (not->exptext == NULL)
+                goto merr;
+            if (!ASN1_STRING_set(not->exptext, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (!strcmp(cnf->name, "organization")) {
+            NOTICEREF *nref;
+            if (!not->noticeref) {
+                if (!(nref = NOTICEREF_new()))
+                    goto merr;
+                not->noticeref = nref;
+            } else
+                nref = not->noticeref;
+            if (ia5org)
+                nref->organization->type = V_ASN1_IA5STRING;
+            else
+                nref->organization->type = V_ASN1_VISIBLESTRING;
+            if (!ASN1_STRING_set(nref->organization, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (!strcmp(cnf->name, "noticeNumbers")) {
+            NOTICEREF *nref;
+            STACK_OF(CONF_VALUE) *nos;
+            if (!not->noticeref) {
+                if (!(nref = NOTICEREF_new()))
+                    goto merr;
+                not->noticeref = nref;
+            } else
+                nref = not->noticeref;
+            nos = X509V3_parse_list(cnf->value);
+            if (!nos || !sk_CONF_VALUE_num(nos)) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            ret = nref_nos(nref->noticenos, nos);
+            sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+            if (!ret)
+                goto err;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
 
-	if(not->noticeref && 
-	      (!not->noticeref->noticenos || !not->noticeref->organization)) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
-			goto err;
-	}
+    if (not->noticeref &&
+        (!not->noticeref->noticenos || !not->noticeref->organization)) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+        goto err;
+    }
 
-	return qual;
+    return qual;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
 
-	err:
-	POLICYQUALINFO_free(qual);
-	return NULL;
+ err:
+    POLICYQUALINFO_free(qual);
+    return NULL;
 }
 
 static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
 {
-	CONF_VALUE *cnf;
-	ASN1_INTEGER *aint;
+    CONF_VALUE *cnf;
+    ASN1_INTEGER *aint;
 
-	size_t i;
+    size_t i;
 
-	for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
-		cnf = sk_CONF_VALUE_value(nos, i);
-		if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER);
-			goto err;
-		}
-		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
-	}
-	return 1;
+    for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
+        cnf = sk_CONF_VALUE_value(nos, i);
+        if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER);
+            goto err;
+        }
+        if (!sk_ASN1_INTEGER_push(nnums, aint))
+            goto merr;
+    }
+    return 1;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
 
-	err:
-	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
-	return 0;
+ err:
+    sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
+    return 0;
 }
 
-
 static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
-		BIO *out, int indent)
+                       BIO *out, int indent)
 {
-	size_t i;
-	POLICYINFO *pinfo;
-	/* First print out the policy OIDs */
-	for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
-		pinfo = sk_POLICYINFO_value(pol, i);
-		BIO_printf(out, "%*sPolicy: ", indent, "");
-		i2a_ASN1_OBJECT(out, pinfo->policyid);
-		BIO_puts(out, "\n");
-		if(pinfo->qualifiers)
-			 print_qualifiers(out, pinfo->qualifiers, indent + 2);
-	}
-	return 1;
+    size_t i;
+    POLICYINFO *pinfo;
+    /* First print out the policy OIDs */
+    for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
+        pinfo = sk_POLICYINFO_value(pol, i);
+        BIO_printf(out, "%*sPolicy: ", indent, "");
+        i2a_ASN1_OBJECT(out, pinfo->policyid);
+        BIO_puts(out, "\n");
+        if (pinfo->qualifiers)
+            print_qualifiers(out, pinfo->qualifiers, indent + 2);
+    }
+    return 1;
 }
 
 static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
-		int indent)
+                             int indent)
 {
-	POLICYQUALINFO *qualinfo;
-	size_t i;
-	for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
-		qualinfo = sk_POLICYQUALINFO_value(quals, i);
-		switch(OBJ_obj2nid(qualinfo->pqualid))
-		{
-			case NID_id_qt_cps:
-			BIO_printf(out, "%*sCPS: %s\n", indent, "",
-						qualinfo->d.cpsuri->data);
-			break;
-		
-			case NID_id_qt_unotice:
-			BIO_printf(out, "%*sUser Notice:\n", indent, "");
-			print_notice(out, qualinfo->d.usernotice, indent + 2);
-			break;
+    POLICYQUALINFO *qualinfo;
+    size_t i;
+    for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
+        qualinfo = sk_POLICYQUALINFO_value(quals, i);
+        switch (OBJ_obj2nid(qualinfo->pqualid)) {
+        case NID_id_qt_cps:
+            BIO_printf(out, "%*sCPS: %s\n", indent, "",
+                       qualinfo->d.cpsuri->data);
+            break;
 
-			default:
-			BIO_printf(out, "%*sUnknown Qualifier: ",
-							 indent + 2, "");
-			
-			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
-			BIO_puts(out, "\n");
-			break;
-		}
-	}
+        case NID_id_qt_unotice:
+            BIO_printf(out, "%*sUser Notice:\n", indent, "");
+            print_notice(out, qualinfo->d.usernotice, indent + 2);
+            break;
+
+        default:
+            BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");
+
+            i2a_ASN1_OBJECT(out, qualinfo->pqualid);
+            BIO_puts(out, "\n");
+            break;
+        }
+    }
 }
 
 static void print_notice(BIO *out, USERNOTICE *notice, int indent)
 {
-	size_t i;
-	if(notice->noticeref) {
-		NOTICEREF *ref;
-		ref = notice->noticeref;
-		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
-						 ref->organization->data);
-		BIO_printf(out, "%*sNumber%s: ", indent, "",
-			   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
-		for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
-			ASN1_INTEGER *num;
-			char *tmp;
-			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
-			if(i) BIO_puts(out, ", ");
-			tmp = i2s_ASN1_INTEGER(NULL, num);
-			BIO_puts(out, tmp);
-			OPENSSL_free(tmp);
-		}
-		BIO_puts(out, "\n");
-	}
-	if(notice->exptext)
-		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
-							 notice->exptext->data);
+    size_t i;
+    if (notice->noticeref) {
+        NOTICEREF *ref;
+        ref = notice->noticeref;
+        BIO_printf(out, "%*sOrganization: %s\n", indent, "",
+                   ref->organization->data);
+        BIO_printf(out, "%*sNumber%s: ", indent, "",
+                   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
+        for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
+            ASN1_INTEGER *num;
+            char *tmp;
+            num = sk_ASN1_INTEGER_value(ref->noticenos, i);
+            if (i)
+                BIO_puts(out, ", ");
+            tmp = i2s_ASN1_INTEGER(NULL, num);
+            BIO_puts(out, tmp);
+            OPENSSL_free(tmp);
+        }
+        BIO_puts(out, "\n");
+    }
+    if (notice->exptext)
+        BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
+                   notice->exptext->data);
 }
 
 void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
-	{
-	const X509_POLICY_DATA *dat = node->data;
+{
+    const X509_POLICY_DATA *dat = node->data;
 
-	BIO_printf(out, "%*sPolicy: ", indent, "");
-			
-	i2a_ASN1_OBJECT(out, dat->valid_policy);
-	BIO_puts(out, "\n");
-	BIO_printf(out, "%*s%s\n", indent + 2, "",
-		node_data_critical(dat) ? "Critical" : "Non Critical");
-	if (dat->qualifier_set)
-		print_qualifiers(out, dat->qualifier_set, indent + 2);
-	else
-		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
-	}
+    BIO_printf(out, "%*sPolicy: ", indent, "");
+
+    i2a_ASN1_OBJECT(out, dat->valid_policy);
+    BIO_puts(out, "\n");
+    BIO_printf(out, "%*s%s\n", indent + 2, "",
+               node_data_critical(dat) ? "Critical" : "Non Critical");
+    if (dat->qualifier_set)
+        print_qualifiers(out, dat->qualifier_set, indent + 2);
+    else
+        BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
+}
diff --git a/src/crypto/x509v3/v3_crld.c b/src/crypto/x509v3/v3_crld.c
index 3984c31..c93c449 100644
--- a/src/crypto/x509v3/v3_crld.c
+++ b/src/crypto/x509v3/v3_crld.c
@@ -1,6 +1,7 @@
 /* v3_crld.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -65,552 +66,496 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static void *v2i_crld(const X509V3_EXT_METHOD *method,
-		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+                      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
-		     int indent);
+                     int indent);
 
-const X509V3_EXT_METHOD v3_crld =
-	{
-	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
-	0,0,0,0,
-	0,0,
-	0,
-	v2i_crld,
-	i2r_crldp,0,
-	NULL
-	};
+const X509V3_EXT_METHOD v3_crld = {
+    NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_crld,
+    i2r_crldp, 0,
+    NULL
+};
 
-const X509V3_EXT_METHOD v3_freshest_crl =
-	{
-	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
-	0,0,0,0,
-	0,0,
-	0,
-	v2i_crld,
-	i2r_crldp,0,
-	NULL
-	};
+const X509V3_EXT_METHOD v3_freshest_crl = {
+    NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_crld,
+    i2r_crldp, 0,
+    NULL
+};
 
-static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
-	{
-	STACK_OF(CONF_VALUE) *gnsect;
-	STACK_OF(GENERAL_NAME) *gens;
-	if (*sect == '@')
-		gnsect = X509V3_get_section(ctx, sect + 1);
-	else
-		gnsect = X509V3_parse_list(sect);
-	if (!gnsect)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
-		return NULL;
-		}
-	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
-	if (*sect == '@')
-		X509V3_section_free(ctx, gnsect);
-	else
-		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
-	return gens;
-	}
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx,
+                                                    char *sect)
+{
+    STACK_OF(CONF_VALUE) *gnsect;
+    STACK_OF(GENERAL_NAME) *gens;
+    if (*sect == '@')
+        gnsect = X509V3_get_section(ctx, sect + 1);
+    else
+        gnsect = X509V3_parse_list(sect);
+    if (!gnsect) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+        return NULL;
+    }
+    gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+    if (*sect == '@')
+        X509V3_section_free(ctx, gnsect);
+    else
+        sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+    return gens;
+}
 
 static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
-							CONF_VALUE *cnf)
-	{
-	STACK_OF(GENERAL_NAME) *fnm = NULL;
-	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
-	if (!strncmp(cnf->name, "fullname", 9))
-		{
-		fnm = gnames_from_sectname(ctx, cnf->value);
-		if (!fnm)
-			goto err;
-		}
-	else if (!strcmp(cnf->name, "relativename"))
-		{
-		int ret;
-		STACK_OF(CONF_VALUE) *dnsect;
-		X509_NAME *nm;
-		nm = X509_NAME_new();
-		if (!nm)
-			return -1;
-		dnsect = X509V3_get_section(ctx, cnf->value);
-		if (!dnsect)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
-			return -1;
-			}
-		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
-		X509V3_section_free(ctx, dnsect);
-		rnm = nm->entries;
-		nm->entries = NULL;
-		X509_NAME_free(nm);
-		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
-			goto err;
-		/* Since its a name fragment can't have more than one
-		 * RDNSequence
-		 */
-		if (sk_X509_NAME_ENTRY_value(rnm,
-				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
-			goto err;
-			}
-		}
-	else
-		return 0;
+                               CONF_VALUE *cnf)
+{
+    STACK_OF(GENERAL_NAME) *fnm = NULL;
+    STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+    if (!strncmp(cnf->name, "fullname", 9)) {
+        fnm = gnames_from_sectname(ctx, cnf->value);
+        if (!fnm)
+            goto err;
+    } else if (!strcmp(cnf->name, "relativename")) {
+        int ret;
+        STACK_OF(CONF_VALUE) *dnsect;
+        X509_NAME *nm;
+        nm = X509_NAME_new();
+        if (!nm)
+            return -1;
+        dnsect = X509V3_get_section(ctx, cnf->value);
+        if (!dnsect) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+            return -1;
+        }
+        ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+        X509V3_section_free(ctx, dnsect);
+        rnm = nm->entries;
+        nm->entries = NULL;
+        X509_NAME_free(nm);
+        if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+            goto err;
+        /*
+         * Since its a name fragment can't have more than one RDNSequence
+         */
+        if (sk_X509_NAME_ENTRY_value(rnm,
+                                     sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
+            goto err;
+        }
+    } else
+        return 0;
 
-	if (*pdp)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
-		goto err;
-		}
+    if (*pdp) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
+        goto err;
+    }
 
-	*pdp = DIST_POINT_NAME_new();
-	if (!*pdp)
-		goto err;
-	if (fnm)
-		{
-		(*pdp)->type = 0;
-		(*pdp)->name.fullname = fnm;
-		}
-	else
-		{
-		(*pdp)->type = 1;
-		(*pdp)->name.relativename = rnm;
-		}
+    *pdp = DIST_POINT_NAME_new();
+    if (!*pdp)
+        goto err;
+    if (fnm) {
+        (*pdp)->type = 0;
+        (*pdp)->name.fullname = fnm;
+    } else {
+        (*pdp)->type = 1;
+        (*pdp)->name.relativename = rnm;
+    }
 
-	return 1;
-		
-	err:
-	if (fnm)
-		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
-	if (rnm)
-		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
-	return -1;
-	}
+    return 1;
+
+ err:
+    if (fnm)
+        sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+    if (rnm)
+        sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+    return -1;
+}
 
 static const BIT_STRING_BITNAME reason_flags[] = {
-{0, "Unused", "unused"},
-{1, "Key Compromise", "keyCompromise"},
-{2, "CA Compromise", "CACompromise"},
-{3, "Affiliation Changed", "affiliationChanged"},
-{4, "Superseded", "superseded"},
-{5, "Cessation Of Operation", "cessationOfOperation"},
-{6, "Certificate Hold", "certificateHold"},
-{7, "Privilege Withdrawn", "privilegeWithdrawn"},
-{8, "AA Compromise", "AACompromise"},
-{-1, NULL, NULL}
+    {0, "Unused", "unused"},
+    {1, "Key Compromise", "keyCompromise"},
+    {2, "CA Compromise", "CACompromise"},
+    {3, "Affiliation Changed", "affiliationChanged"},
+    {4, "Superseded", "superseded"},
+    {5, "Cessation Of Operation", "cessationOfOperation"},
+    {6, "Certificate Hold", "certificateHold"},
+    {7, "Privilege Withdrawn", "privilegeWithdrawn"},
+    {8, "AA Compromise", "AACompromise"},
+    {-1, NULL, NULL}
 };
 
 static int set_reasons(ASN1_BIT_STRING **preas, char *value)
-	{
-	STACK_OF(CONF_VALUE) *rsk = NULL;
-	const BIT_STRING_BITNAME *pbn;
-	const char *bnam;
-	size_t i;
-	int ret = 0;
-	rsk = X509V3_parse_list(value);
-	if (!rsk)
-		return 0;
-	if (*preas)
-		return 0;
-	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
-		{
-		bnam = sk_CONF_VALUE_value(rsk, i)->name;
-		if (!*preas)
-			{
-			*preas = ASN1_BIT_STRING_new();
-			if (!*preas)
-				goto err;
-			}
-		for (pbn = reason_flags; pbn->lname; pbn++)
-			{
-			if (!strcmp(pbn->sname, bnam))
-				{
-				if (!ASN1_BIT_STRING_set_bit(*preas,
-							pbn->bitnum, 1))
-					goto err;
-				break;
-				}
-			}
-		if (!pbn->lname)
-			goto err;
-		}
-	ret = 1;
+{
+    STACK_OF(CONF_VALUE) *rsk = NULL;
+    const BIT_STRING_BITNAME *pbn;
+    const char *bnam;
+    size_t i;
+    int ret = 0;
+    rsk = X509V3_parse_list(value);
+    if (!rsk)
+        return 0;
+    if (*preas)
+        return 0;
+    for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
+        bnam = sk_CONF_VALUE_value(rsk, i)->name;
+        if (!*preas) {
+            *preas = ASN1_BIT_STRING_new();
+            if (!*preas)
+                goto err;
+        }
+        for (pbn = reason_flags; pbn->lname; pbn++) {
+            if (!strcmp(pbn->sname, bnam)) {
+                if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1))
+                    goto err;
+                break;
+            }
+        }
+        if (!pbn->lname)
+            goto err;
+    }
+    ret = 1;
 
-	err:
-	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
-	return ret;
-	}
+ err:
+    sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+    return ret;
+}
 
 static int print_reasons(BIO *out, const char *rname,
-			ASN1_BIT_STRING *rflags, int indent)
-	{
-	int first = 1;
-	const BIT_STRING_BITNAME *pbn;
-	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
-	for (pbn = reason_flags; pbn->lname; pbn++)
-		{
-		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
-			{
-			if (first)
-				first = 0;
-			else
-				BIO_puts(out, ", ");
-			BIO_puts(out, pbn->lname);
-			}
-		}
-	if (first)
-		BIO_puts(out, "<EMPTY>\n");
-	else
-		BIO_puts(out, "\n");
-	return 1;
-	}
+                         ASN1_BIT_STRING *rflags, int indent)
+{
+    int first = 1;
+    const BIT_STRING_BITNAME *pbn;
+    BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+    for (pbn = reason_flags; pbn->lname; pbn++) {
+        if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
+            if (first)
+                first = 0;
+            else
+                BIO_puts(out, ", ");
+            BIO_puts(out, pbn->lname);
+        }
+    }
+    if (first)
+        BIO_puts(out, "<EMPTY>\n");
+    else
+        BIO_puts(out, "\n");
+    return 1;
+}
 
 static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
-						STACK_OF(CONF_VALUE) *nval)
-	{
-	size_t i;
-	CONF_VALUE *cnf;
-	DIST_POINT *point = NULL;
-	point = DIST_POINT_new();
-	if (!point)
-		goto err;
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
-		{
-		int ret;
-		cnf = sk_CONF_VALUE_value(nval, i);
-		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
-		if (ret > 0)
-			continue;
-		if (ret < 0)
-			goto err;
-		if (!strcmp(cnf->name, "reasons"))
-			{
-			if (!set_reasons(&point->reasons, cnf->value))
-				goto err;
-			}
-		else if (!strcmp(cnf->name, "CRLissuer"))
-			{
-			point->CRLissuer =
-				gnames_from_sectname(ctx, cnf->value);
-			if (!point->CRLissuer)
-				goto err;
-			}
-		}
+                                      STACK_OF(CONF_VALUE) *nval)
+{
+    size_t i;
+    CONF_VALUE *cnf;
+    DIST_POINT *point = NULL;
+    point = DIST_POINT_new();
+    if (!point)
+        goto err;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        int ret;
+        cnf = sk_CONF_VALUE_value(nval, i);
+        ret = set_dist_point_name(&point->distpoint, ctx, cnf);
+        if (ret > 0)
+            continue;
+        if (ret < 0)
+            goto err;
+        if (!strcmp(cnf->name, "reasons")) {
+            if (!set_reasons(&point->reasons, cnf->value))
+                goto err;
+        } else if (!strcmp(cnf->name, "CRLissuer")) {
+            point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
+            if (!point->CRLissuer)
+                goto err;
+        }
+    }
 
-	return point;
-			
+    return point;
 
-	err:
-	if (point)
-		DIST_POINT_free(point);
-	return NULL;
-	}
+ err:
+    if (point)
+        DIST_POINT_free(point);
+    return NULL;
+}
 
 static void *v2i_crld(const X509V3_EXT_METHOD *method,
-		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
-	{
-	STACK_OF(DIST_POINT) *crld = NULL;
-	GENERAL_NAMES *gens = NULL;
-	GENERAL_NAME *gen = NULL;
-	CONF_VALUE *cnf;
-	size_t i;
-	if(!(crld = sk_DIST_POINT_new_null())) goto merr;
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		DIST_POINT *point;
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if (!cnf->value)
-			{
-			STACK_OF(CONF_VALUE) *dpsect;
-			dpsect = X509V3_get_section(ctx, cnf->name);
-			if (!dpsect)
-				goto err;
-			point = crldp_from_section(ctx, dpsect);
-			X509V3_section_free(ctx, dpsect);
-			if (!point)
-				goto err;
-			if(!sk_DIST_POINT_push(crld, point))
-				{
-				DIST_POINT_free(point);
-				goto merr;
-				}
-			}
-		else
-			{
-			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
-				goto err; 
-			if(!(gens = GENERAL_NAMES_new()))
-				goto merr;
-			if(!sk_GENERAL_NAME_push(gens, gen))
-				goto merr;
-			gen = NULL;
-			if(!(point = DIST_POINT_new()))
-				goto merr;
-			if(!sk_DIST_POINT_push(crld, point))
-				{
-				DIST_POINT_free(point);
-				goto merr;
-				}
-			if(!(point->distpoint = DIST_POINT_NAME_new()))
-				goto merr;
-			point->distpoint->name.fullname = gens;
-			point->distpoint->type = 0;
-			gens = NULL;
-			}
-	}
-	return crld;
+                      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    STACK_OF(DIST_POINT) *crld = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    CONF_VALUE *cnf;
+    size_t i;
+    if (!(crld = sk_DIST_POINT_new_null()))
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        DIST_POINT *point;
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!cnf->value) {
+            STACK_OF(CONF_VALUE) *dpsect;
+            dpsect = X509V3_get_section(ctx, cnf->name);
+            if (!dpsect)
+                goto err;
+            point = crldp_from_section(ctx, dpsect);
+            X509V3_section_free(ctx, dpsect);
+            if (!point)
+                goto err;
+            if (!sk_DIST_POINT_push(crld, point)) {
+                DIST_POINT_free(point);
+                goto merr;
+            }
+        } else {
+            if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+                goto err;
+            if (!(gens = GENERAL_NAMES_new()))
+                goto merr;
+            if (!sk_GENERAL_NAME_push(gens, gen))
+                goto merr;
+            gen = NULL;
+            if (!(point = DIST_POINT_new()))
+                goto merr;
+            if (!sk_DIST_POINT_push(crld, point)) {
+                DIST_POINT_free(point);
+                goto merr;
+            }
+            if (!(point->distpoint = DIST_POINT_NAME_new()))
+                goto merr;
+            point->distpoint->name.fullname = gens;
+            point->distpoint->type = 0;
+            gens = NULL;
+        }
+    }
+    return crld;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	err:
-	GENERAL_NAME_free(gen);
-	GENERAL_NAMES_free(gens);
-	sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
-	return NULL;
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+    GENERAL_NAME_free(gen);
+    GENERAL_NAMES_free(gens);
+    sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
+    return NULL;
 }
 
 IMPLEMENT_ASN1_SET_OF(DIST_POINT)
 
 static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-								void *exarg)
-	{
-	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
+                  void *exarg)
+{
+    DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
 
-	switch(operation)
-		{
-		case ASN1_OP_NEW_POST:
-		dpn->dpname = NULL;
-		break;
+    switch (operation) {
+    case ASN1_OP_NEW_POST:
+        dpn->dpname = NULL;
+        break;
 
-		case ASN1_OP_FREE_POST:
-		if (dpn->dpname)
-			X509_NAME_free(dpn->dpname);
-		break;
-		}
-	return 1;
-	}
+    case ASN1_OP_FREE_POST:
+        if (dpn->dpname)
+            X509_NAME_free(dpn->dpname);
+        break;
+    }
+    return 1;
+}
 
 
 ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
-	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
-	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
+        ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
+        ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
 } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
 
 
 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
 
 ASN1_SEQUENCE(DIST_POINT) = {
-	ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
-	ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
-	ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
+        ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+        ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
+        ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
 } ASN1_SEQUENCE_END(DIST_POINT)
 
 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
 
-ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
 ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
 
 IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
 
 ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
-	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
-	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
-	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
-	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
-	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
-	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
+        ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
 } ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
 
 IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
 
 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
-		   int indent);
+                   int indent);
 static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-		     STACK_OF(CONF_VALUE) *nval);
+                     STACK_OF(CONF_VALUE) *nval);
 
-const X509V3_EXT_METHOD v3_idp =
-	{
-	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
-	ASN1_ITEM_ref(ISSUING_DIST_POINT),
-	0,0,0,0,
-	0,0,
-	0,
-	v2i_idp,
-	i2r_idp,0,
-	NULL
-	};
+const X509V3_EXT_METHOD v3_idp = {
+    NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(ISSUING_DIST_POINT),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_idp,
+    i2r_idp, 0,
+    NULL
+};
 
 static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-		     STACK_OF(CONF_VALUE) *nval)
-	{
-	ISSUING_DIST_POINT *idp = NULL;
-	CONF_VALUE *cnf;
-	char *name, *val;
-	size_t i;
-	int ret;
-	idp = ISSUING_DIST_POINT_new();
-	if (!idp)
-		goto merr;
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
-		{
-		cnf = sk_CONF_VALUE_value(nval, i);
-		name = cnf->name;
-		val = cnf->value;
-		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
-		if (ret > 0)
-			continue;
-		if (ret < 0)
-			goto err;
-		if (!strcmp(name, "onlyuser"))
-			{
-			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
-				goto err;
-			}
-		else if (!strcmp(name, "onlyCA"))
-			{
-			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
-				goto err;
-			}
-		else if (!strcmp(name, "onlyAA"))
-			{
-			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
-				goto err;
-			}
-		else if (!strcmp(name, "indirectCRL"))
-			{
-			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
-				goto err;
-			}
-		else if (!strcmp(name, "onlysomereasons"))
-			{
-			if (!set_reasons(&idp->onlysomereasons, val))
-				goto err;
-			}
-		else
-			{
-                        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
-                        X509V3_conf_err(cnf);
-                        goto err;
-			}
-		}
-	return idp;
+                     STACK_OF(CONF_VALUE) *nval)
+{
+    ISSUING_DIST_POINT *idp = NULL;
+    CONF_VALUE *cnf;
+    char *name, *val;
+    size_t i;
+    int ret;
+    idp = ISSUING_DIST_POINT_new();
+    if (!idp)
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        name = cnf->name;
+        val = cnf->value;
+        ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+        if (ret > 0)
+            continue;
+        if (ret < 0)
+            goto err;
+        if (!strcmp(name, "onlyuser")) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+                goto err;
+        } else if (!strcmp(name, "onlyCA")) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+                goto err;
+        } else if (!strcmp(name, "onlyAA")) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+                goto err;
+        } else if (!strcmp(name, "indirectCRL")) {
+            if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+                goto err;
+        } else if (!strcmp(name, "onlysomereasons")) {
+            if (!set_reasons(&idp->onlysomereasons, val))
+                goto err;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
+    return idp;
 
-	merr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	err:
-	ISSUING_DIST_POINT_free(idp);
-	return NULL;
-	}
+ merr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+    ISSUING_DIST_POINT_free(idp);
+    return NULL;
+}
 
 static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
-	{
-	size_t i;
-	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
-		{
-		BIO_printf(out, "%*s", indent + 2, "");
-		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
-		BIO_puts(out, "\n");
-		}
-	return 1;
-	}
+{
+    size_t i;
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        BIO_printf(out, "%*s", indent + 2, "");
+        GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+        BIO_puts(out, "\n");
+    }
+    return 1;
+}
 
 static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
-	{
-	if (dpn->type == 0)
-		{
-		BIO_printf(out, "%*sFull Name:\n", indent, "");
-		print_gens(out, dpn->name.fullname, indent);
-		}
-	else
-		{
-		X509_NAME ntmp;
-		ntmp.entries = dpn->name.relativename;
-		BIO_printf(out, "%*sRelative Name:\n%*s",
-						indent, "", indent + 2, "");
-		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
-		BIO_puts(out, "\n");
-		}
-	return 1;
-	}
+{
+    if (dpn->type == 0) {
+        BIO_printf(out, "%*sFull Name:\n", indent, "");
+        print_gens(out, dpn->name.fullname, indent);
+    } else {
+        X509_NAME ntmp;
+        ntmp.entries = dpn->name.relativename;
+        BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
+        X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
+        BIO_puts(out, "\n");
+    }
+    return 1;
+}
 
 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
-		   int indent)
-	{
-	ISSUING_DIST_POINT *idp = pidp;
-	if (idp->distpoint)
-		print_distpoint(out, idp->distpoint, indent);
-	if (idp->onlyuser > 0)
-		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
-	if (idp->onlyCA > 0)
-		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
-	if (idp->indirectCRL > 0)
-		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
-	if (idp->onlysomereasons)
-		print_reasons(out, "Only Some Reasons", 
-				idp->onlysomereasons, indent);
-	if (idp->onlyattr > 0)
-		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
-	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
-		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
-		&& (idp->onlyattr <= 0))
-		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
-		
-	return 1;
-	}
+                   int indent)
+{
+    ISSUING_DIST_POINT *idp = pidp;
+    if (idp->distpoint)
+        print_distpoint(out, idp->distpoint, indent);
+    if (idp->onlyuser > 0)
+        BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
+    if (idp->onlyCA > 0)
+        BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
+    if (idp->indirectCRL > 0)
+        BIO_printf(out, "%*sIndirect CRL\n", indent, "");
+    if (idp->onlysomereasons)
+        print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
+    if (idp->onlyattr > 0)
+        BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
+    if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
+        && (idp->indirectCRL <= 0) && !idp->onlysomereasons
+        && (idp->onlyattr <= 0))
+        BIO_printf(out, "%*s<EMPTY>\n", indent, "");
+
+    return 1;
+}
 
 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
-		     int indent)
-	{
-	STACK_OF(DIST_POINT) *crld = pcrldp;
-	DIST_POINT *point;
-	size_t i;
-	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
-		{
-		BIO_puts(out, "\n");
-		point = sk_DIST_POINT_value(crld, i);
-		if(point->distpoint)
-			print_distpoint(out, point->distpoint, indent);
-		if(point->reasons) 
-			print_reasons(out, "Reasons", point->reasons,
-								indent);
-		if(point->CRLissuer)
-			{
-			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
-			print_gens(out, point->CRLissuer, indent);
-			}
-		}
-	return 1;
-	}
+                     int indent)
+{
+    STACK_OF(DIST_POINT) *crld = pcrldp;
+    DIST_POINT *point;
+    size_t i;
+    for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
+        BIO_puts(out, "\n");
+        point = sk_DIST_POINT_value(crld, i);
+        if (point->distpoint)
+            print_distpoint(out, point->distpoint, indent);
+        if (point->reasons)
+            print_reasons(out, "Reasons", point->reasons, indent);
+        if (point->CRLissuer) {
+            BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
+            print_gens(out, point->CRLissuer, indent);
+        }
+    }
+    return 1;
+}
 
 int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
-	{
-	size_t i;
-	STACK_OF(X509_NAME_ENTRY) *frag;
-	X509_NAME_ENTRY *ne;
-	if (!dpn || (dpn->type != 1))
-		return 1;
-	frag = dpn->name.relativename;
-	dpn->dpname = X509_NAME_dup(iname);
-	if (!dpn->dpname)
-		return 0;
-	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
-		{
-		ne = sk_X509_NAME_ENTRY_value(frag, i);
-		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
-			{
-			X509_NAME_free(dpn->dpname);
-			dpn->dpname = NULL;
-			return 0;
-			}
-		}
-	/* generate cached encoding of name */
-	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
-		{
-		X509_NAME_free(dpn->dpname);
-		dpn->dpname = NULL;
-		return 0;
-		}
-	return 1;
-	}
+{
+    size_t i;
+    STACK_OF(X509_NAME_ENTRY) *frag;
+    X509_NAME_ENTRY *ne;
+    if (!dpn || (dpn->type != 1))
+        return 1;
+    frag = dpn->name.relativename;
+    dpn->dpname = X509_NAME_dup(iname);
+    if (!dpn->dpname)
+        return 0;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
+        ne = sk_X509_NAME_ENTRY_value(frag, i);
+        if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
+            X509_NAME_free(dpn->dpname);
+            dpn->dpname = NULL;
+            return 0;
+        }
+    }
+    /* generate cached encoding of name */
+    if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
+        X509_NAME_free(dpn->dpname);
+        dpn->dpname = NULL;
+        return 0;
+    }
+    return 1;
+}
diff --git a/src/crypto/x509v3/v3_enum.c b/src/crypto/x509v3/v3_enum.c
index 0fe6bb6..6bfb232 100644
--- a/src/crypto/x509v3/v3_enum.c
+++ b/src/crypto/x509v3/v3_enum.c
@@ -1,6 +1,7 @@
 /* v3_enum.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -60,39 +61,40 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static const ENUMERATED_NAMES crl_reasons[] = {
-{CRL_REASON_UNSPECIFIED, 	 "Unspecified", "unspecified"},
-{CRL_REASON_KEY_COMPROMISE,	 "Key Compromise", "keyCompromise"},
-{CRL_REASON_CA_COMPROMISE,	 "CA Compromise", "CACompromise"},
-{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
-{CRL_REASON_SUPERSEDED, 	 "Superseded", "superseded"},
-{CRL_REASON_CESSATION_OF_OPERATION,
-			"Cessation Of Operation", "cessationOfOperation"},
-{CRL_REASON_CERTIFICATE_HOLD,	 "Certificate Hold", "certificateHold"},
-{CRL_REASON_REMOVE_FROM_CRL,	 "Remove From CRL", "removeFromCRL"},
-{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
-{CRL_REASON_AA_COMPROMISE,	 "AA Compromise", "AACompromise"},
-{-1, NULL, NULL}
+    {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
+    {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
+    {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
+    {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed",
+     "affiliationChanged"},
+    {CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
+    {CRL_REASON_CESSATION_OF_OPERATION,
+     "Cessation Of Operation", "cessationOfOperation"},
+    {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
+    {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
+    {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn",
+     "privilegeWithdrawn"},
+    {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
+    {-1, NULL, NULL}
 };
 
-const X509V3_EXT_METHOD v3_crl_reason = { 
-NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
-0,0,0,0,
-(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
-0,
-0,0,0,0,
-(void *)crl_reasons};
+const X509V3_EXT_METHOD v3_crl_reason = {
+    NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
+    0,
+    0, 0, 0, 0,
+    (void *)crl_reasons
+};
 
-
-char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method,
-	     ASN1_ENUMERATED *e)
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e)
 {
-	const ENUMERATED_NAMES *enam;
-	long strval;
-	strval = ASN1_ENUMERATED_get(e);
-	for(enam = method->usr_data; enam->lname; enam++) {
-		if(strval == enam->bitnum) return BUF_strdup(enam->lname);
-	}
-	return i2s_ASN1_ENUMERATED(method, e);
+    const ENUMERATED_NAMES *enam;
+    long strval;
+    strval = ASN1_ENUMERATED_get(e);
+    for (enam = method->usr_data; enam->lname; enam++) {
+        if (strval == enam->bitnum)
+            return BUF_strdup(enam->lname);
+    }
+    return i2s_ASN1_ENUMERATED(method, e);
 }
diff --git a/src/crypto/x509v3/v3_extku.c b/src/crypto/x509v3/v3_extku.c
index d64eb9c..952e032 100644
--- a/src/crypto/x509v3/v3_extku.c
+++ b/src/crypto/x509v3/v3_extku.c
@@ -1,6 +1,7 @@
 /* v3_extku.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 
 #include <openssl/asn1t.h>
@@ -63,83 +63,86 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
-				    X509V3_CTX *ctx,
-				    STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
-		void *eku, STACK_OF(CONF_VALUE) *extlist);
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+                                                    *method, void *eku, STACK_OF(CONF_VALUE)
+                                                    *extlist);
 
 const X509V3_EXT_METHOD v3_ext_ku = {
-	NID_ext_key_usage, 0,
-	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
-	0,0,0,0,
-	0,0,
-	i2v_EXTENDED_KEY_USAGE,
-	v2i_EXTENDED_KEY_USAGE,
-	0,0,
-	NULL
+    NID_ext_key_usage, 0,
+    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_EXTENDED_KEY_USAGE,
+    v2i_EXTENDED_KEY_USAGE,
+    0, 0,
+    NULL
 };
 
 /* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
 const X509V3_EXT_METHOD v3_ocsp_accresp = {
-	NID_id_pkix_OCSP_acceptableResponses, 0,
-	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
-	0,0,0,0,
-	0,0,
-	i2v_EXTENDED_KEY_USAGE,
-	v2i_EXTENDED_KEY_USAGE,
-	0,0,
-	NULL
+    NID_id_pkix_OCSP_acceptableResponses, 0,
+    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_EXTENDED_KEY_USAGE,
+    v2i_EXTENDED_KEY_USAGE,
+    0, 0,
+    NULL
 };
 
-ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
 ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
 
 IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
 
-static STACK_OF(CONF_VALUE) *
-  i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
-			 STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+                                                    *method, void *a, STACK_OF(CONF_VALUE)
+                                                    *ext_list)
 {
-	EXTENDED_KEY_USAGE *eku = a;
-	size_t i;
-	ASN1_OBJECT *obj;
-	char obj_tmp[80];
-	for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
-		obj = sk_ASN1_OBJECT_value(eku, i);
-		i2t_ASN1_OBJECT(obj_tmp, 80, obj);
-		X509V3_add_value(NULL, obj_tmp, &ext_list);
-	}
-	return ext_list;
+    EXTENDED_KEY_USAGE *eku = a;
+    size_t i;
+    ASN1_OBJECT *obj;
+    char obj_tmp[80];
+    for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+        obj = sk_ASN1_OBJECT_value(eku, i);
+        i2t_ASN1_OBJECT(obj_tmp, 80, obj);
+        X509V3_add_value(NULL, obj_tmp, &ext_list);
+    }
+    return ext_list;
 }
 
 static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
-				    X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *nval)
 {
-	EXTENDED_KEY_USAGE *extku;
-	char *extval;
-	ASN1_OBJECT *objtmp;
-	CONF_VALUE *val;
-	size_t i;
+    EXTENDED_KEY_USAGE *extku;
+    char *extval;
+    ASN1_OBJECT *objtmp;
+    CONF_VALUE *val;
+    size_t i;
 
-	if(!(extku = sk_ASN1_OBJECT_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
+    if (!(extku = sk_ASN1_OBJECT_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
 
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		val = sk_CONF_VALUE_value(nval, i);
-		if(val->value) extval = val->value;
-		else extval = val->name;
-		if(!(objtmp = OBJ_txt2obj(extval, 0))) {
-			sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-			X509V3_conf_err(val);
-			return NULL;
-		}
-		sk_ASN1_OBJECT_push(extku, objtmp);
-	}
-	return extku;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (val->value)
+            extval = val->value;
+        else
+            extval = val->name;
+        if (!(objtmp = OBJ_txt2obj(extval, 0))) {
+            sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return NULL;
+        }
+        sk_ASN1_OBJECT_push(extku, objtmp);
+    }
+    return extku;
 }
diff --git a/src/crypto/x509v3/v3_genn.c b/src/crypto/x509v3/v3_genn.c
index 8b0a68d..2331cd4 100644
--- a/src/crypto/x509v3/v3_genn.c
+++ b/src/crypto/x509v3/v3_genn.c
@@ -1,6 +1,7 @@
 /* v3_genn.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 
 #include <openssl/asn1t.h>
@@ -64,189 +64,187 @@
 
 
 ASN1_SEQUENCE(OTHERNAME) = {
-	ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
-	/* Maybe have a true ANY DEFINED BY later */
-	ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
+        ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
+        /* Maybe have a true ANY DEFINED BY later */
+        ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
 } ASN1_SEQUENCE_END(OTHERNAME)
 
 IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
 
 ASN1_SEQUENCE(EDIPARTYNAME) = {
-	ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
-	ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+        ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+        ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
 } ASN1_SEQUENCE_END(EDIPARTYNAME)
 
 IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
 
 ASN1_CHOICE(GENERAL_NAME) = {
-	ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
-	ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
-	ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
-	/* Don't decode this */
-	ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
-	/* X509_NAME is a CHOICE type so use EXPLICIT */
-	ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
-	ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
-	ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
-	ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
-	ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
+        ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
+        ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
+        ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
+        /* Don't decode this */
+        ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
+        /* X509_NAME is a CHOICE type so use EXPLICIT */
+        ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
+        ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
+        ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
+        ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
+        ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
 } ASN1_CHOICE_END(GENERAL_NAME)
 
 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
 
-ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
 ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
 
 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
 
 GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
-	{
-	return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
-					 (d2i_of_void *) d2i_GENERAL_NAME,
-					 (char *) a);
-	}
+{
+    return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
+                                    (d2i_of_void *)d2i_GENERAL_NAME,
+                                    (char *)a);
+}
 
 /* Returns 0 if they are equal, != 0 otherwise. */
 int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
-	{
-	int result = -1;
+{
+    int result = -1;
 
-	if (!a || !b || a->type != b->type) return -1;
-	switch(a->type)
-		{
-	case GEN_X400:
-	case GEN_EDIPARTY:
-		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
-		break;
+    if (!a || !b || a->type != b->type)
+        return -1;
+    switch (a->type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+        break;
 
-	case GEN_OTHERNAME:
-		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
-		break;
+    case GEN_OTHERNAME:
+        result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
+        break;
 
-	case GEN_EMAIL:
-	case GEN_DNS:
-	case GEN_URI:
-		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
-		break;
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
+        break;
 
-	case GEN_DIRNAME:
-		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
-		break;
+    case GEN_DIRNAME:
+        result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
+        break;
 
-	case GEN_IPADD:
-		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
-		break;
-	
-	case GEN_RID:
-		result = OBJ_cmp(a->d.rid, b->d.rid);
-		break;
-		}
-	return result;
-	}
+    case GEN_IPADD:
+        result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
+        break;
+
+    case GEN_RID:
+        result = OBJ_cmp(a->d.rid, b->d.rid);
+        break;
+    }
+    return result;
+}
 
 /* Returns 0 if they are equal, != 0 otherwise. */
 int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
-	{
-	int result = -1;
+{
+    int result = -1;
 
-	if (!a || !b) return -1;
-	/* Check their type first. */
-	if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
-		return result;
-	/* Check the value. */
-	result = ASN1_TYPE_cmp(a->value, b->value);
-	return result;
-	}
+    if (!a || !b)
+        return -1;
+    /* Check their type first. */
+    if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
+        return result;
+    /* Check the value. */
+    result = ASN1_TYPE_cmp(a->value, b->value);
+    return result;
+}
 
 void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
-	{
-	switch(type)
-		{
-	case GEN_X400:
-	case GEN_EDIPARTY:
-		a->d.other = value;
-		break;
+{
+    switch (type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        a->d.other = value;
+        break;
 
-	case GEN_OTHERNAME:
-		a->d.otherName = value;
-		break;
+    case GEN_OTHERNAME:
+        a->d.otherName = value;
+        break;
 
-	case GEN_EMAIL:
-	case GEN_DNS:
-	case GEN_URI:
-		a->d.ia5 = value;
-		break;
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        a->d.ia5 = value;
+        break;
 
-	case GEN_DIRNAME:
-		a->d.dirn = value;
-		break;
+    case GEN_DIRNAME:
+        a->d.dirn = value;
+        break;
 
-	case GEN_IPADD:
-		a->d.ip = value;
-		break;
-	
-	case GEN_RID:
-		a->d.rid = value;
-		break;
-		}
-	a->type = type;
-	}
+    case GEN_IPADD:
+        a->d.ip = value;
+        break;
+
+    case GEN_RID:
+        a->d.rid = value;
+        break;
+    }
+    a->type = type;
+}
 
 void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
-	{
-	if (ptype)
-		*ptype = a->type;
-	switch(a->type)
-		{
-	case GEN_X400:
-	case GEN_EDIPARTY:
-		return a->d.other;
+{
+    if (ptype)
+        *ptype = a->type;
+    switch (a->type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        return a->d.other;
 
-	case GEN_OTHERNAME:
-		return a->d.otherName;
+    case GEN_OTHERNAME:
+        return a->d.otherName;
 
-	case GEN_EMAIL:
-	case GEN_DNS:
-	case GEN_URI:
-		return a->d.ia5;
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        return a->d.ia5;
 
-	case GEN_DIRNAME:
-		return a->d.dirn;
+    case GEN_DIRNAME:
+        return a->d.dirn;
 
-	case GEN_IPADD:
-		return a->d.ip;
-	
-	case GEN_RID:
-		return a->d.rid;
+    case GEN_IPADD:
+        return a->d.ip;
 
-	default:
-		return NULL;
-		}
-	}
+    case GEN_RID:
+        return a->d.rid;
+
+    default:
+        return NULL;
+    }
+}
 
 int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
-				ASN1_OBJECT *oid, ASN1_TYPE *value)
-	{
-	OTHERNAME *oth;
-	oth = OTHERNAME_new();
-	if (!oth)
-		return 0;
-	oth->type_id = oid;
-	oth->value = value;
-	GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
-	return 1;
-	}
+                                ASN1_OBJECT *oid, ASN1_TYPE *value)
+{
+    OTHERNAME *oth;
+    oth = OTHERNAME_new();
+    if (!oth)
+        return 0;
+    oth->type_id = oid;
+    oth->value = value;
+    GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
+    return 1;
+}
 
-int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
-				ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
-	{
-	if (gen->type != GEN_OTHERNAME)
-		return 0;
-	if (poid)
-		*poid = gen->d.otherName->type_id;
-	if (pvalue)
-		*pvalue = gen->d.otherName->value;
-	return 1;
-	}
-
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
+{
+    if (gen->type != GEN_OTHERNAME)
+        return 0;
+    if (poid)
+        *poid = gen->d.otherName->type_id;
+    if (pvalue)
+        *pvalue = gen->d.otherName->value;
+    return 1;
+}
diff --git a/src/crypto/x509v3/v3_ia5.c b/src/crypto/x509v3/v3_ia5.c
index 5a27233..6fc6b59 100644
--- a/src/crypto/x509v3/v3_ia5.c
+++ b/src/crypto/x509v3/v3_ia5.c
@@ -1,6 +1,7 @@
 /* v3_ia5.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -66,52 +67,53 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
-static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
-const X509V3_EXT_METHOD v3_ns_ia5_list[] = { 
-EXT_IA5STRING(NID_netscape_base_url),
-EXT_IA5STRING(NID_netscape_revocation_url),
-EXT_IA5STRING(NID_netscape_ca_revocation_url),
-EXT_IA5STRING(NID_netscape_renewal_url),
-EXT_IA5STRING(NID_netscape_ca_policy_url),
-EXT_IA5STRING(NID_netscape_ssl_server_name),
-EXT_IA5STRING(NID_netscape_comment),
-EXT_END
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+                                ASN1_IA5STRING *ia5);
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+                                          X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
+    EXT_IA5STRING(NID_netscape_base_url),
+    EXT_IA5STRING(NID_netscape_revocation_url),
+    EXT_IA5STRING(NID_netscape_ca_revocation_url),
+    EXT_IA5STRING(NID_netscape_renewal_url),
+    EXT_IA5STRING(NID_netscape_ca_policy_url),
+    EXT_IA5STRING(NID_netscape_ssl_server_name),
+    EXT_IA5STRING(NID_netscape_comment),
+    EXT_END
 };
 
-
 static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
-	     ASN1_IA5STRING *ia5)
+                                ASN1_IA5STRING *ia5)
 {
-	char *tmp;
-	if(!ia5 || !ia5->length) return NULL;
-	if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	memcpy(tmp, ia5->data, ia5->length);
-	tmp[ia5->length] = 0;
-	return tmp;
+    char *tmp;
+    if (!ia5 || !ia5->length)
+        return NULL;
+    if (!(tmp = OPENSSL_malloc(ia5->length + 1))) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    memcpy(tmp, ia5->data, ia5->length);
+    tmp[ia5->length] = 0;
+    return tmp;
 }
 
 static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, char *str)
+                                          X509V3_CTX *ctx, char *str)
 {
-	ASN1_IA5STRING *ia5;
-	if(!str) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
-		return NULL;
-	}
-	if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
-	if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
-			    strlen(str))) {
-		M_ASN1_IA5STRING_free(ia5);
-		goto err;
-	}
-	return ia5;
-	err:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	return NULL;
+    ASN1_IA5STRING *ia5;
+    if (!str) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+        return NULL;
+    }
+    if (!(ia5 = M_ASN1_IA5STRING_new()))
+        goto err;
+    if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str,
+                         strlen(str))) {
+        M_ASN1_IA5STRING_free(ia5);
+        goto err;
+    }
+    return ia5;
+ err:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    return NULL;
 }
-
diff --git a/src/crypto/x509v3/v3_info.c b/src/crypto/x509v3/v3_info.c
index 475c56f..482208d 100644
--- a/src/crypto/x509v3/v3_info.c
+++ b/src/crypto/x509v3/v3_info.c
@@ -1,6 +1,7 @@
 /* v3_info.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -68,133 +69,144 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                       *method, AUTHORITY_INFO_ACCESS
+                                                       *ainfo, STACK_OF(CONF_VALUE)
+                                                       *ret);
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                        *method,
+                                                        X509V3_CTX *ctx,
+                                                        STACK_OF(CONF_VALUE)
+                                                        *nval);
 
-static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
-				AUTHORITY_INFO_ACCESS *ainfo,
-						STACK_OF(CONF_VALUE) *ret);
-static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+    0, 0,
+    NULL
+};
 
-const X509V3_EXT_METHOD v3_info =
-{ NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
-(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
-0,0,
-NULL};
-
-const X509V3_EXT_METHOD v3_sinfo =
-{ NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
-(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
-0,0,
-NULL};
+const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+    0, 0,
+    NULL
+};
 
 ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
-	ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
-	ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
+        ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
+        ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
 } ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
 
 IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
 
-ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
 ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
 
 IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
 
-static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
-				AUTHORITY_INFO_ACCESS *ainfo,
-						STACK_OF(CONF_VALUE) *ret)
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                       *method, AUTHORITY_INFO_ACCESS
+                                                       *ainfo, STACK_OF(CONF_VALUE)
+                                                       *ret)
 {
-	ACCESS_DESCRIPTION *desc;
-	size_t i;
-	int nlen;
-	char objtmp[80], *ntmp;
-	CONF_VALUE *vtmp;
-	for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
-		desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
-		ret = i2v_GENERAL_NAME(method, desc->location, ret);
-		if(!ret) break;
-		vtmp = sk_CONF_VALUE_value(ret, i);
-		i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
-		nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
-		ntmp = OPENSSL_malloc(nlen);
-		if(!ntmp) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			return NULL;
-		}
-		BUF_strlcpy(ntmp, objtmp, nlen);
-		BUF_strlcat(ntmp, " - ", nlen);
-		BUF_strlcat(ntmp, vtmp->name, nlen);
-		OPENSSL_free(vtmp->name);
-		vtmp->name = ntmp;
-		
-	}
-	if(!ret) return sk_CONF_VALUE_new_null();
-	return ret;
+    ACCESS_DESCRIPTION *desc;
+    size_t i;
+    int nlen;
+    char objtmp[80], *ntmp;
+    CONF_VALUE *vtmp;
+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+        desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+        ret = i2v_GENERAL_NAME(method, desc->location, ret);
+        if (!ret)
+            break;
+        vtmp = sk_CONF_VALUE_value(ret, i);
+        i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
+        nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
+        ntmp = OPENSSL_malloc(nlen);
+        if (!ntmp) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        BUF_strlcpy(ntmp, objtmp, nlen);
+        BUF_strlcat(ntmp, " - ", nlen);
+        BUF_strlcat(ntmp, vtmp->name, nlen);
+        OPENSSL_free(vtmp->name);
+        vtmp->name = ntmp;
+
+    }
+    if (!ret)
+        return sk_CONF_VALUE_new_null();
+    return ret;
 }
 
-static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                        *method,
+                                                        X509V3_CTX *ctx,
+                                                        STACK_OF(CONF_VALUE)
+                                                        *nval)
 {
-	AUTHORITY_INFO_ACCESS *ainfo = NULL;
-	CONF_VALUE *cnf, ctmp;
-	ACCESS_DESCRIPTION *acc;
-	size_t i;
-	int objlen;
-	char *objtmp, *ptmp;
-	if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!(acc = ACCESS_DESCRIPTION_new())
-			|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ptmp = strchr(cnf->name, ';');
-		if(!ptmp) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
-			goto err;
-		}
-		objlen = ptmp - cnf->name;
-		ctmp.name = ptmp + 1;
-		ctmp.value = cnf->value;
-		if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
-								 goto err; 
-		if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		strncpy(objtmp, cnf->name, objlen);
-		objtmp[objlen] = 0;
-		acc->method = OBJ_txt2obj(objtmp, 0);
-		if(!acc->method) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
-			ERR_add_error_data(2, "value=", objtmp);
-			OPENSSL_free(objtmp);
-			goto err;
-		}
-		OPENSSL_free(objtmp);
+    AUTHORITY_INFO_ACCESS *ainfo = NULL;
+    CONF_VALUE *cnf, ctmp;
+    ACCESS_DESCRIPTION *acc;
+    size_t i;
+    int objlen;
+    char *objtmp, *ptmp;
+    if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!(acc = ACCESS_DESCRIPTION_new())
+            || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ptmp = strchr(cnf->name, ';');
+        if (!ptmp) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
+            goto err;
+        }
+        objlen = ptmp - cnf->name;
+        ctmp.name = ptmp + 1;
+        ctmp.value = cnf->value;
+        if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
+            goto err;
+        if (!(objtmp = OPENSSL_malloc(objlen + 1))) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        strncpy(objtmp, cnf->name, objlen);
+        objtmp[objlen] = 0;
+        acc->method = OBJ_txt2obj(objtmp, 0);
+        if (!acc->method) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
+            ERR_add_error_data(2, "value=", objtmp);
+            OPENSSL_free(objtmp);
+            goto err;
+        }
+        OPENSSL_free(objtmp);
 
-	}
-	return ainfo;
-	err:
-	sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
-	return NULL;
+    }
+    return ainfo;
+ err:
+    sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
+    return NULL;
 }
 
-int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a)
-        {
-	i2a_ASN1_OBJECT(bp, a->method);
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a)
+{
+    i2a_ASN1_OBJECT(bp, a->method);
 #ifdef UNDEF
-	i2a_GENERAL_NAME(bp, a->location);
+    i2a_GENERAL_NAME(bp, a->location);
 #endif
-	return 2;
-	}
+    return 2;
+}
diff --git a/src/crypto/x509v3/v3_int.c b/src/crypto/x509v3/v3_int.c
index 8ca23bd..7bde446 100644
--- a/src/crypto/x509v3/v3_int.c
+++ b/src/crypto/x509v3/v3_int.c
@@ -1,6 +1,7 @@
 /* v3_int.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -59,29 +60,32 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
+const X509V3_EXT_METHOD v3_crl_num = {
+    NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    0,
+    0, 0, 0, 0, NULL
+};
 
-const X509V3_EXT_METHOD v3_crl_num = { 
-	NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
-	0,0,0,0,
-	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
-	0,
-	0,0,0,0, NULL};
+const X509V3_EXT_METHOD v3_delta_crl = {
+    NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    0,
+    0, 0, 0, 0, NULL
+};
 
-const X509V3_EXT_METHOD v3_delta_crl = { 
-	NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
-	0,0,0,0,
-	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
-	0,
-	0,0,0,0, NULL};
+static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx,
+                          char *value)
+{
+    return s2i_ASN1_INTEGER(meth, value);
+}
 
-static void * s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
-	{
-	return s2i_ASN1_INTEGER(meth, value);
-	}
-
-const X509V3_EXT_METHOD v3_inhibit_anyp = { 
-	NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
-	0,0,0,0,
-	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
-	(X509V3_EXT_S2I)s2i_asn1_int,
-	0,0,0,0, NULL};
+const X509V3_EXT_METHOD v3_inhibit_anyp = {
+    NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    (X509V3_EXT_S2I)s2i_asn1_int,
+    0, 0, 0, 0, NULL
+};
diff --git a/src/crypto/x509v3/v3_lib.c b/src/crypto/x509v3/v3_lib.c
index f8e5531..c4718e3 100644
--- a/src/crypto/x509v3/v3_lib.c
+++ b/src/crypto/x509v3/v3_lib.c
@@ -1,6 +1,7 @@
 /* v3_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -70,266 +71,292 @@
 
 static void ext_list_free(X509V3_EXT_METHOD *ext);
 
-static int ext_stack_cmp(const X509V3_EXT_METHOD **a, const X509V3_EXT_METHOD **b)
+static int ext_stack_cmp(const X509V3_EXT_METHOD **a,
+                         const X509V3_EXT_METHOD **b)
 {
-	return ((*a)->ext_nid - (*b)->ext_nid);
+    return ((*a)->ext_nid - (*b)->ext_nid);
 }
 
 int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
 {
-	if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		ext_list_free(ext);
-		return 0;
-	}
-	if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		ext_list_free(ext);
-		return 0;
-	}
-	return 1;
+    if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        ext_list_free(ext);
+        return 0;
+    }
+    if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        ext_list_free(ext);
+        return 0;
+    }
+    return 1;
 }
 
-static int ext_cmp(const void *void_a,
-		   const void *void_b)
+static int ext_cmp(const void *void_a, const void *void_b)
 {
-	const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD**) void_a;
-	const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD**) void_b;
-	return ext_stack_cmp(a, b);
+    const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a;
+    const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b;
+    return ext_stack_cmp(a, b);
 }
 
 const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
 {
-	X509V3_EXT_METHOD tmp;
-	const X509V3_EXT_METHOD *t = &tmp, * const *ret;
-	size_t idx;
+    X509V3_EXT_METHOD tmp;
+    const X509V3_EXT_METHOD *t = &tmp, *const *ret;
+    size_t idx;
 
-	if(nid < 0) return NULL;
-	tmp.ext_nid = nid;
-	ret = bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, sizeof(X509V3_EXT_METHOD*), ext_cmp);
-	if(ret) return *ret;
-	if(!ext_list) return NULL;
+    if (nid < 0)
+        return NULL;
+    tmp.ext_nid = nid;
+    ret =
+        bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT,
+                sizeof(X509V3_EXT_METHOD *), ext_cmp);
+    if (ret)
+        return *ret;
+    if (!ext_list)
+        return NULL;
 
-	if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
-		return NULL;
-	return sk_X509V3_EXT_METHOD_value(ext_list, idx);
+    if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
+        return NULL;
+    return sk_X509V3_EXT_METHOD_value(ext_list, idx);
 }
 
 const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
 {
-	int nid;
-	if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
-	return X509V3_EXT_get_nid(nid);
+    int nid;
+    if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
+        return NULL;
+    return X509V3_EXT_get_nid(nid);
 }
 
 int X509V3_EXT_free(int nid, void *ext_data)
 {
-	    const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
-	    if (ext_method == NULL)
-	    {
-		    OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
-		    return 0;
-	    }
+    const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
+    if (ext_method == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+        return 0;
+    }
 
-	    if (ext_method->it != NULL)
-		    ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
-	    else if (ext_method->ext_free != NULL)
-		    ext_method->ext_free(ext_data);
-	    else
-	    {
-		    OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
-		    return 0;
-	    }
+    if (ext_method->it != NULL)
+        ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
+    else if (ext_method->ext_free != NULL)
+        ext_method->ext_free(ext_data);
+    else {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+        return 0;
+    }
 
-	    return 1;
+    return 1;
 }
 
 int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
 {
-	for(;extlist->ext_nid!=-1;extlist++) 
-			if(!X509V3_EXT_add(extlist)) return 0;
-	return 1;
+    for (; extlist->ext_nid != -1; extlist++)
+        if (!X509V3_EXT_add(extlist))
+            return 0;
+    return 1;
 }
 
 int X509V3_EXT_add_alias(int nid_to, int nid_from)
 {
-	const X509V3_EXT_METHOD *ext;
-	X509V3_EXT_METHOD *tmpext;
+    const X509V3_EXT_METHOD *ext;
+    X509V3_EXT_METHOD *tmpext;
 
-	if(!(ext = X509V3_EXT_get_nid(nid_from))) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
-		return 0;
-	}
-	if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	*tmpext = *ext;
-	tmpext->ext_nid = nid_to;
-	tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
-	return X509V3_EXT_add(tmpext);
+    if (!(ext = X509V3_EXT_get_nid(nid_from))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
+        return 0;
+    }
+    if (!
+        (tmpext =
+         (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    *tmpext = *ext;
+    tmpext->ext_nid = nid_to;
+    tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
+    return X509V3_EXT_add(tmpext);
 }
 
 void X509V3_EXT_cleanup(void)
 {
-	sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
-	ext_list = NULL;
+    sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
+    ext_list = NULL;
 }
 
 static void ext_list_free(X509V3_EXT_METHOD *ext)
 {
-	if(ext->ext_flags & X509V3_EXT_DYNAMIC) OPENSSL_free(ext);
+    if (ext->ext_flags & X509V3_EXT_DYNAMIC)
+        OPENSSL_free(ext);
 }
 
-/* Legacy function: we don't need to add standard extensions
- * any more because they are now kept in ext_dat.h.
+/*
+ * Legacy function: we don't need to add standard extensions any more because
+ * they are now kept in ext_dat.h.
  */
 
 int X509V3_add_standard_extensions(void)
 {
-	return 1;
+    return 1;
 }
 
 /* Return an extension internal structure */
 
 void *X509V3_EXT_d2i(X509_EXTENSION *ext)
 {
-	const X509V3_EXT_METHOD *method;
-	const unsigned char *p;
+    const X509V3_EXT_METHOD *method;
+    const unsigned char *p;
 
-	if(!(method = X509V3_EXT_get(ext))) return NULL;
-	p = ext->value->data;
-	if(method->it) return ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
-	return method->d2i(NULL, &p, ext->value->length);
+    if (!(method = X509V3_EXT_get(ext)))
+        return NULL;
+    p = ext->value->data;
+    if (method->it)
+        return ASN1_item_d2i(NULL, &p, ext->value->length,
+                             ASN1_ITEM_ptr(method->it));
+    return method->d2i(NULL, &p, ext->value->length);
 }
 
-/* Get critical flag and decoded version of extension from a NID.
- * The "idx" variable returns the last found extension and can
- * be used to retrieve multiple extensions of the same NID.
- * However multiple extensions with the same NID is usually
- * due to a badly encoded certificate so if idx is NULL we
- * choke if multiple extensions exist.
- * The "crit" variable is set to the critical value.
- * The return value is the decoded extension or NULL on
- * error. The actual error can have several different causes,
- * the value of *crit reflects the cause:
- * >= 0, extension found but not decoded (reflects critical value).
- * -1 extension not found.
- * -2 extension occurs more than once.
+/*
+ * Get critical flag and decoded version of extension from a NID. The "idx"
+ * variable returns the last found extension and can be used to retrieve
+ * multiple extensions of the same NID. However multiple extensions with the
+ * same NID is usually due to a badly encoded certificate so if idx is NULL
+ * we choke if multiple extensions exist. The "crit" variable is set to the
+ * critical value. The return value is the decoded extension or NULL on
+ * error. The actual error can have several different causes, the value of
+ * *crit reflects the cause: >= 0, extension found but not decoded (reflects
+ * critical value). -1 extension not found. -2 extension occurs more than
+ * once.
  */
 
-void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+                     int *idx)
 {
-	int lastpos;
-	size_t i;
-	X509_EXTENSION *ex, *found_ex = NULL;
-	if(!x) {
-		if(idx) *idx = -1;
-		if(crit) *crit = -1;
-		return NULL;
-	}
-	if(idx) lastpos = *idx + 1;
-	else lastpos = 0;
-	if(lastpos < 0) lastpos = 0;
-	for(i = lastpos; i < sk_X509_EXTENSION_num(x); i++)
-	{
-		ex = sk_X509_EXTENSION_value(x, i);
-		if(OBJ_obj2nid(ex->object) == nid) {
-			if(idx) {
-				*idx = i;
-				found_ex = ex;
-				break;
-			} else if(found_ex) {
-				/* Found more than one */
-				if(crit) *crit = -2;
-				return NULL;
-			}
-			found_ex = ex;
-		}
-	}
-	if(found_ex) {
-		/* Found it */
-		if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
-		return X509V3_EXT_d2i(found_ex);
-	}
+    int lastpos;
+    size_t i;
+    X509_EXTENSION *ex, *found_ex = NULL;
+    if (!x) {
+        if (idx)
+            *idx = -1;
+        if (crit)
+            *crit = -1;
+        return NULL;
+    }
+    if (idx)
+        lastpos = *idx + 1;
+    else
+        lastpos = 0;
+    if (lastpos < 0)
+        lastpos = 0;
+    for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
+        ex = sk_X509_EXTENSION_value(x, i);
+        if (OBJ_obj2nid(ex->object) == nid) {
+            if (idx) {
+                *idx = i;
+                found_ex = ex;
+                break;
+            } else if (found_ex) {
+                /* Found more than one */
+                if (crit)
+                    *crit = -2;
+                return NULL;
+            }
+            found_ex = ex;
+        }
+    }
+    if (found_ex) {
+        /* Found it */
+        if (crit)
+            *crit = X509_EXTENSION_get_critical(found_ex);
+        return X509V3_EXT_d2i(found_ex);
+    }
 
-	/* Extension not found */
-	if(idx) *idx = -1;
-	if(crit) *crit = -1;
-	return NULL;
+    /* Extension not found */
+    if (idx)
+        *idx = -1;
+    if (crit)
+        *crit = -1;
+    return NULL;
 }
 
-/* This function is a general extension append, replace and delete utility.
+/*
+ * This function is a general extension append, replace and delete utility.
  * The precise operation is governed by the 'flags' value. The 'crit' and
  * 'value' arguments (if relevant) are the extensions internal structure.
  */
 
 int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
-					int crit, unsigned long flags)
+                    int crit, unsigned long flags)
 {
-	int extidx = -1;
-	int errcode;
-	X509_EXTENSION *ext, *extmp;
-	unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+    int extidx = -1;
+    int errcode;
+    X509_EXTENSION *ext, *extmp;
+    unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
 
-	/* If appending we don't care if it exists, otherwise
-	 * look for existing extension.
-	 */
-	if(ext_op != X509V3_ADD_APPEND)
-		extidx = X509v3_get_ext_by_NID(*x, nid, -1);
+    /*
+     * If appending we don't care if it exists, otherwise look for existing
+     * extension.
+     */
+    if (ext_op != X509V3_ADD_APPEND)
+        extidx = X509v3_get_ext_by_NID(*x, nid, -1);
 
-	/* See if extension exists */
-	if(extidx >= 0) {
-		/* If keep existing, nothing to do */
-		if(ext_op == X509V3_ADD_KEEP_EXISTING)
-			return 1;
-		/* If default then its an error */
-		if(ext_op == X509V3_ADD_DEFAULT) {
-			errcode = X509V3_R_EXTENSION_EXISTS;
-			goto err;
-		}
-		/* If delete, just delete it */
-		if(ext_op == X509V3_ADD_DELETE) {
-			if(!sk_X509_EXTENSION_delete(*x, extidx)) return -1;
-			return 1;
-		}
-	} else {
-		/* If replace existing or delete, error since 
-		 * extension must exist
-		 */
-		if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
-		   (ext_op == X509V3_ADD_DELETE)) {
-			errcode = X509V3_R_EXTENSION_NOT_FOUND;
-			goto err;
-		}
-	}
+    /* See if extension exists */
+    if (extidx >= 0) {
+        /* If keep existing, nothing to do */
+        if (ext_op == X509V3_ADD_KEEP_EXISTING)
+            return 1;
+        /* If default then its an error */
+        if (ext_op == X509V3_ADD_DEFAULT) {
+            errcode = X509V3_R_EXTENSION_EXISTS;
+            goto err;
+        }
+        /* If delete, just delete it */
+        if (ext_op == X509V3_ADD_DELETE) {
+            if (!sk_X509_EXTENSION_delete(*x, extidx))
+                return -1;
+            return 1;
+        }
+    } else {
+        /*
+         * If replace existing or delete, error since extension must exist
+         */
+        if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+            (ext_op == X509V3_ADD_DELETE)) {
+            errcode = X509V3_R_EXTENSION_NOT_FOUND;
+            goto err;
+        }
+    }
 
-	/* If we get this far then we have to create an extension:
-	 * could have some flags for alternative encoding schemes...
-	 */
+    /*
+     * If we get this far then we have to create an extension: could have
+     * some flags for alternative encoding schemes...
+     */
 
-	ext = X509V3_EXT_i2d(nid, crit, value);
+    ext = X509V3_EXT_i2d(nid, crit, value);
 
-	if(!ext) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
-		return 0;
-	}
+    if (!ext) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
+        return 0;
+    }
 
-	/* If extension exists replace it.. */
-	if(extidx >= 0) {
-		extmp = sk_X509_EXTENSION_value(*x, extidx);
-		X509_EXTENSION_free(extmp);
-		if(!sk_X509_EXTENSION_set(*x, extidx, ext)) return -1;
-		return 1;
-	}
+    /* If extension exists replace it.. */
+    if (extidx >= 0) {
+        extmp = sk_X509_EXTENSION_value(*x, extidx);
+        X509_EXTENSION_free(extmp);
+        if (!sk_X509_EXTENSION_set(*x, extidx, ext))
+            return -1;
+        return 1;
+    }
 
-	if(!*x && !(*x = sk_X509_EXTENSION_new_null())) return -1;
-	if(!sk_X509_EXTENSION_push(*x, ext)) return -1;
+    if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
+        return -1;
+    if (!sk_X509_EXTENSION_push(*x, ext))
+        return -1;
 
-	return 1;
+    return 1;
 
-	err:
-	if(!(flags & X509V3_ADD_SILENT))
-		OPENSSL_PUT_ERROR(X509V3, errcode);
-	return 0;
+ err:
+    if (!(flags & X509V3_ADD_SILENT))
+        OPENSSL_PUT_ERROR(X509V3, errcode);
+    return 0;
 }
diff --git a/src/crypto/x509v3/v3_ncons.c b/src/crypto/x509v3/v3_ncons.c
index 19f5e94..368ad27 100644
--- a/src/crypto/x509v3/v3_ncons.c
+++ b/src/crypto/x509v3/v3_ncons.c
@@ -1,5 +1,6 @@
 /* v3_ncons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 #include <string.h>
 
@@ -65,14 +65,14 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
-				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 
-				void *a, BIO *bp, int ind);
+                                  X509V3_CTX *ctx,
+                                  STACK_OF(CONF_VALUE) *nval);
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+                                BIO *bp, int ind);
 static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
-				   STACK_OF(GENERAL_SUBTREE) *trees,
-				   BIO *bp, int ind, const char *name);
+                                   STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp,
+                                   int ind, const char *name);
 static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
 
 static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
@@ -83,428 +83,400 @@
 static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
 
 const X509V3_EXT_METHOD v3_name_constraints = {
-	NID_name_constraints, 0,
-	ASN1_ITEM_ref(NAME_CONSTRAINTS),
-	0,0,0,0,
-	0,0,
-	0, v2i_NAME_CONSTRAINTS,
-	i2r_NAME_CONSTRAINTS,0,
-	NULL
+    NID_name_constraints, 0,
+    ASN1_ITEM_ref(NAME_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0, v2i_NAME_CONSTRAINTS,
+    i2r_NAME_CONSTRAINTS, 0,
+    NULL
 };
 
 ASN1_SEQUENCE(GENERAL_SUBTREE) = {
-	ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
-	ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
-	ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
+        ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
+        ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
+        ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
 } ASN1_SEQUENCE_END(GENERAL_SUBTREE)
 
 ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
-	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
-							GENERAL_SUBTREE, 0),
-	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
-							GENERAL_SUBTREE, 1),
+        ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
+                                                        GENERAL_SUBTREE, 0),
+        ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
+                                                        GENERAL_SUBTREE, 1),
 } ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
-	
+
 
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
 
 static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
-				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
-	{
-	size_t i;
-	CONF_VALUE tval, *val;
-	STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
-	NAME_CONSTRAINTS *ncons = NULL;
-	GENERAL_SUBTREE *sub = NULL;
-	ncons = NAME_CONSTRAINTS_new();
-	if (!ncons)
-		goto memerr;
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
-		{
-		val = sk_CONF_VALUE_value(nval, i);
-		if (!strncmp(val->name, "permitted", 9) && val->name[9])
-			{
-			ptree = &ncons->permittedSubtrees;
-			tval.name = val->name + 10;
-			}
-		else if (!strncmp(val->name, "excluded", 8) && val->name[8])
-			{
-			ptree = &ncons->excludedSubtrees;
-			tval.name = val->name + 9;
-			}
-		else
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
-			goto err;
-			}
-		tval.value = val->value;
-		sub = GENERAL_SUBTREE_new();
-		if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
-			goto err;
-		if (!*ptree)
-			*ptree = sk_GENERAL_SUBTREE_new_null();
-		if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
-			goto memerr;
-		sub = NULL;
-		}
+                                  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    size_t i;
+    CONF_VALUE tval, *val;
+    STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
+    NAME_CONSTRAINTS *ncons = NULL;
+    GENERAL_SUBTREE *sub = NULL;
+    ncons = NAME_CONSTRAINTS_new();
+    if (!ncons)
+        goto memerr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
+            ptree = &ncons->permittedSubtrees;
+            tval.name = val->name + 10;
+        } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
+            ptree = &ncons->excludedSubtrees;
+            tval.name = val->name + 9;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
+            goto err;
+        }
+        tval.value = val->value;
+        sub = GENERAL_SUBTREE_new();
+        if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
+            goto err;
+        if (!*ptree)
+            *ptree = sk_GENERAL_SUBTREE_new_null();
+        if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
+            goto memerr;
+        sub = NULL;
+    }
 
-	return ncons;
+    return ncons;
 
-	memerr:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	err:
-	if (ncons)
-		NAME_CONSTRAINTS_free(ncons);
-	if (sub)
-		GENERAL_SUBTREE_free(sub);
+ memerr:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+    if (ncons)
+        NAME_CONSTRAINTS_free(ncons);
+    if (sub)
+        GENERAL_SUBTREE_free(sub);
 
-	return NULL;
-	}
-			
-
-	
+    return NULL;
+}
 
 static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
-				BIO *bp, int ind)
-	{
-	NAME_CONSTRAINTS *ncons = a;
-	do_i2r_name_constraints(method, ncons->permittedSubtrees,
-					bp, ind, "Permitted");
-	do_i2r_name_constraints(method, ncons->excludedSubtrees,
-					bp, ind, "Excluded");
-	return 1;
-	}
+                                BIO *bp, int ind)
+{
+    NAME_CONSTRAINTS *ncons = a;
+    do_i2r_name_constraints(method, ncons->permittedSubtrees,
+                            bp, ind, "Permitted");
+    do_i2r_name_constraints(method, ncons->excludedSubtrees,
+                            bp, ind, "Excluded");
+    return 1;
+}
 
 static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
-				   STACK_OF(GENERAL_SUBTREE) *trees,
-				   BIO *bp, int ind, const char *name)
-	{
-	GENERAL_SUBTREE *tree;
-	size_t i;
-	if (sk_GENERAL_SUBTREE_num(trees) > 0)
-		BIO_printf(bp, "%*s%s:\n", ind, "", name);
-	for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
-		{
-		tree = sk_GENERAL_SUBTREE_value(trees, i);
-		BIO_printf(bp, "%*s", ind + 2, "");
-		if (tree->base->type == GEN_IPADD)
-			print_nc_ipadd(bp, tree->base->d.ip);
-		else
-			GENERAL_NAME_print(bp, tree->base);
-		BIO_puts(bp, "\n");
-		}
-	return 1;
-	}
+                                   STACK_OF(GENERAL_SUBTREE) *trees,
+                                   BIO *bp, int ind, const char *name)
+{
+    GENERAL_SUBTREE *tree;
+    size_t i;
+    if (sk_GENERAL_SUBTREE_num(trees) > 0)
+        BIO_printf(bp, "%*s%s:\n", ind, "", name);
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
+        tree = sk_GENERAL_SUBTREE_value(trees, i);
+        BIO_printf(bp, "%*s", ind + 2, "");
+        if (tree->base->type == GEN_IPADD)
+            print_nc_ipadd(bp, tree->base->d.ip);
+        else
+            GENERAL_NAME_print(bp, tree->base);
+        BIO_puts(bp, "\n");
+    }
+    return 1;
+}
 
 static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
-	{
-	int i, len;
-	unsigned char *p;
-	p = ip->data;
-	len = ip->length;
-	BIO_puts(bp, "IP:");
-	if(len == 8)
-		{
-		BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
-				p[0], p[1], p[2], p[3],
-				p[4], p[5], p[6], p[7]);
-		}
-	else if(len == 32)
-		{
-		for (i = 0; i < 16; i++)
-			{
-			BIO_printf(bp, "%X", p[0] << 8 | p[1]);
-			p += 2;
-			if (i == 7)
-				BIO_puts(bp, "/");
-			else if (i != 15)
-				BIO_puts(bp, ":");
-			}
-		}
-	else
-		BIO_printf(bp, "IP Address:<invalid>");
-	return 1;
-	}
+{
+    int i, len;
+    unsigned char *p;
+    p = ip->data;
+    len = ip->length;
+    BIO_puts(bp, "IP:");
+    if (len == 8) {
+        BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
+                   p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+    } else if (len == 32) {
+        for (i = 0; i < 16; i++) {
+            BIO_printf(bp, "%X", p[0] << 8 | p[1]);
+            p += 2;
+            if (i == 7)
+                BIO_puts(bp, "/");
+            else if (i != 15)
+                BIO_puts(bp, ":");
+        }
+    } else
+        BIO_printf(bp, "IP Address:<invalid>");
+    return 1;
+}
 
-/* Check a certificate conforms to a specified set of constraints.
- * Return values:
- *  X509_V_OK: All constraints obeyed.
- *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
- *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
- *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
- *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
- *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
- *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
-
+/*
+ * Check a certificate conforms to a specified set of constraints. Return
+ * values: X509_V_OK: All constraints obeyed.
+ * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
+ * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
+ * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint
+ * syntax.  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of
+ * name
+ *
  */
 
 int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
-	{
-	int r, i;
-	size_t j;
-	X509_NAME *nm;
+{
+    int r, i;
+    size_t j;
+    X509_NAME *nm;
 
-	nm = X509_get_subject_name(x);
+    nm = X509_get_subject_name(x);
 
-	if (X509_NAME_entry_count(nm) > 0)
-		{
-		GENERAL_NAME gntmp;
-		gntmp.type = GEN_DIRNAME;
-		gntmp.d.directoryName = nm;
+    if (X509_NAME_entry_count(nm) > 0) {
+        GENERAL_NAME gntmp;
+        gntmp.type = GEN_DIRNAME;
+        gntmp.d.directoryName = nm;
 
-		r = nc_match(&gntmp, nc);
+        r = nc_match(&gntmp, nc);
 
-		if (r != X509_V_OK)
-			return r;
+        if (r != X509_V_OK)
+            return r;
 
-		gntmp.type = GEN_EMAIL;
+        gntmp.type = GEN_EMAIL;
 
+        /* Process any email address attributes in subject name */
 
-		/* Process any email address attributes in subject name */
+        for (i = -1;;) {
+            X509_NAME_ENTRY *ne;
+            i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i);
+            if (i == -1)
+                break;
+            ne = X509_NAME_get_entry(nm, i);
+            gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
+            if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
+                return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
 
-		for (i = -1;;)
-			{
-			X509_NAME_ENTRY *ne;
-			i = X509_NAME_get_index_by_NID(nm,
-						       NID_pkcs9_emailAddress,
-						       i);
-			if (i == -1)
-				break;
-			ne = X509_NAME_get_entry(nm, i);
-			gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
-			if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
-				return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+            r = nc_match(&gntmp, nc);
 
-			r = nc_match(&gntmp, nc);
+            if (r != X509_V_OK)
+                return r;
+        }
 
-			if (r != X509_V_OK)
-				return r;
-			}
-		
-		}
+    }
 
-	for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++)
-		{
-		GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j);
-		r = nc_match(gen, nc);
-		if (r != X509_V_OK)
-			return r;
-		}
+    for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j);
+        r = nc_match(gen, nc);
+        if (r != X509_V_OK)
+            return r;
+    }
 
-	return X509_V_OK;
+    return X509_V_OK;
 
-	}
+}
 
 static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
-	{
-	GENERAL_SUBTREE *sub;
-	int r, match = 0;
-	size_t i;
+{
+    GENERAL_SUBTREE *sub;
+    int r, match = 0;
+    size_t i;
 
-	/* Permitted subtrees: if any subtrees exist of matching the type
-	 * at least one subtree must match.
-	 */
+    /*
+     * Permitted subtrees: if any subtrees exist of matching the type at
+     * least one subtree must match.
+     */
 
-	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
-		{
-		sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
-		if (gen->type != sub->base->type)
-			continue;
-		if (sub->minimum || sub->maximum)
-			return X509_V_ERR_SUBTREE_MINMAX;
-		/* If we already have a match don't bother trying any more */
-		if (match == 2)
-			continue;
-		if (match == 0)
-			match = 1;
-		r = nc_match_single(gen, sub->base);
-		if (r == X509_V_OK)
-			match = 2;
-		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
-			return r;
-		}
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
+        sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
+        if (gen->type != sub->base->type)
+            continue;
+        if (sub->minimum || sub->maximum)
+            return X509_V_ERR_SUBTREE_MINMAX;
+        /* If we already have a match don't bother trying any more */
+        if (match == 2)
+            continue;
+        if (match == 0)
+            match = 1;
+        r = nc_match_single(gen, sub->base);
+        if (r == X509_V_OK)
+            match = 2;
+        else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+            return r;
+    }
 
-	if (match == 1)
-		return X509_V_ERR_PERMITTED_VIOLATION;
+    if (match == 1)
+        return X509_V_ERR_PERMITTED_VIOLATION;
 
-	/* Excluded subtrees: must not match any of these */
+    /* Excluded subtrees: must not match any of these */
 
-	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
-		{
-		sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
-		if (gen->type != sub->base->type)
-			continue;
-		if (sub->minimum || sub->maximum)
-			return X509_V_ERR_SUBTREE_MINMAX;
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
+        sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
+        if (gen->type != sub->base->type)
+            continue;
+        if (sub->minimum || sub->maximum)
+            return X509_V_ERR_SUBTREE_MINMAX;
 
-		r = nc_match_single(gen, sub->base);
-		if (r == X509_V_OK)
-			return X509_V_ERR_EXCLUDED_VIOLATION;
-		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
-			return r;
+        r = nc_match_single(gen, sub->base);
+        if (r == X509_V_OK)
+            return X509_V_ERR_EXCLUDED_VIOLATION;
+        else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+            return r;
 
-		}
+    }
 
-	return X509_V_OK;
+    return X509_V_OK;
 
-	}
+}
 
 static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
-	{
-	switch(base->type)
-		{
-		case GEN_DIRNAME:
-		return nc_dn(gen->d.directoryName, base->d.directoryName);
+{
+    switch (base->type) {
+    case GEN_DIRNAME:
+        return nc_dn(gen->d.directoryName, base->d.directoryName);
 
-		case GEN_DNS:
-		return nc_dns(gen->d.dNSName, base->d.dNSName);
+    case GEN_DNS:
+        return nc_dns(gen->d.dNSName, base->d.dNSName);
 
-		case GEN_EMAIL:
-		return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
+    case GEN_EMAIL:
+        return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
 
-		case GEN_URI:
-		return nc_uri(gen->d.uniformResourceIdentifier,
-					base->d.uniformResourceIdentifier);
+    case GEN_URI:
+        return nc_uri(gen->d.uniformResourceIdentifier,
+                      base->d.uniformResourceIdentifier);
 
-		default:
-		return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
-		}
+    default:
+        return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+    }
 
-	}
+}
 
-/* directoryName name constraint matching.
- * The canonical encoding of X509_NAME makes this comparison easy. It is
- * matched if the subtree is a subset of the name.
+/*
+ * directoryName name constraint matching. The canonical encoding of
+ * X509_NAME makes this comparison easy. It is matched if the subtree is a
+ * subset of the name.
  */
 
 static int nc_dn(X509_NAME *nm, X509_NAME *base)
-	{
-	/* Ensure canonical encodings are up to date.  */
-	if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
-		return X509_V_ERR_OUT_OF_MEM;
-	if (base->modified && i2d_X509_NAME(base, NULL) < 0)
-		return X509_V_ERR_OUT_OF_MEM;
-	if (base->canon_enclen > nm->canon_enclen)
-		return X509_V_ERR_PERMITTED_VIOLATION;
-	if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
-		return X509_V_ERR_PERMITTED_VIOLATION;
-	return X509_V_OK;
-	}
+{
+    /* Ensure canonical encodings are up to date.  */
+    if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
+        return X509_V_ERR_OUT_OF_MEM;
+    if (base->modified && i2d_X509_NAME(base, NULL) < 0)
+        return X509_V_ERR_OUT_OF_MEM;
+    if (base->canon_enclen > nm->canon_enclen)
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    return X509_V_OK;
+}
 
 static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
-	{
-	char *baseptr = (char *)base->data;
-	char *dnsptr = (char *)dns->data;
-	/* Empty matches everything */
-	if (!*baseptr)
-		return X509_V_OK;
-	/* Otherwise can add zero or more components on the left so
-	 * compare RHS and if dns is longer and expect '.' as preceding
-	 * character.
-	 */
-	if (dns->length > base->length)
-		{
-		dnsptr += dns->length - base->length;
-		if (*baseptr != '.' && dnsptr[-1] != '.')
-			return X509_V_ERR_PERMITTED_VIOLATION;
-		}
+{
+    char *baseptr = (char *)base->data;
+    char *dnsptr = (char *)dns->data;
+    /* Empty matches everything */
+    if (!*baseptr)
+        return X509_V_OK;
+    /*
+     * Otherwise can add zero or more components on the left so compare RHS
+     * and if dns is longer and expect '.' as preceding character.
+     */
+    if (dns->length > base->length) {
+        dnsptr += dns->length - base->length;
+        if (*baseptr != '.' && dnsptr[-1] != '.')
+            return X509_V_ERR_PERMITTED_VIOLATION;
+    }
 
-	if (OPENSSL_strcasecmp(baseptr, dnsptr))
-			return X509_V_ERR_PERMITTED_VIOLATION;
+    if (OPENSSL_strcasecmp(baseptr, dnsptr))
+        return X509_V_ERR_PERMITTED_VIOLATION;
 
-	return X509_V_OK;
+    return X509_V_OK;
 
-	}
+}
 
 static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
-	{
-	const char *baseptr = (char *)base->data;
-	const char *emlptr = (char *)eml->data;
+{
+    const char *baseptr = (char *)base->data;
+    const char *emlptr = (char *)eml->data;
 
-	const char *baseat = strchr(baseptr, '@');
-	const char *emlat = strchr(emlptr, '@');
-	if (!emlat)
-		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
-	/* Special case: inital '.' is RHS match */
-	if (!baseat && (*baseptr == '.'))
-		{
-		if (eml->length > base->length)
-			{
-			emlptr += eml->length - base->length;
-			if (!OPENSSL_strcasecmp(baseptr, emlptr))
-				return X509_V_OK;
-			}
-		return X509_V_ERR_PERMITTED_VIOLATION;
-		}
+    const char *baseat = strchr(baseptr, '@');
+    const char *emlat = strchr(emlptr, '@');
+    if (!emlat)
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    /* Special case: inital '.' is RHS match */
+    if (!baseat && (*baseptr == '.')) {
+        if (eml->length > base->length) {
+            emlptr += eml->length - base->length;
+            if (!OPENSSL_strcasecmp(baseptr, emlptr))
+                return X509_V_OK;
+        }
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    }
 
-	/* If we have anything before '@' match local part */
+    /* If we have anything before '@' match local part */
 
-	if (baseat)
-		{
-		if (baseat != baseptr)
-			{
-			if ((baseat - baseptr) != (emlat - emlptr))
-				return X509_V_ERR_PERMITTED_VIOLATION;
-			/* Case sensitive match of local part */
-			if (strncmp(baseptr, emlptr, emlat - emlptr))
-				return X509_V_ERR_PERMITTED_VIOLATION;
-			}
-		/* Position base after '@' */
-		baseptr = baseat + 1;
-		}
-	emlptr = emlat + 1;
-	/* Just have hostname left to match: case insensitive */
-	if (OPENSSL_strcasecmp(baseptr, emlptr))
-		return X509_V_ERR_PERMITTED_VIOLATION;
+    if (baseat) {
+        if (baseat != baseptr) {
+            if ((baseat - baseptr) != (emlat - emlptr))
+                return X509_V_ERR_PERMITTED_VIOLATION;
+            /* Case sensitive match of local part */
+            if (strncmp(baseptr, emlptr, emlat - emlptr))
+                return X509_V_ERR_PERMITTED_VIOLATION;
+        }
+        /* Position base after '@' */
+        baseptr = baseat + 1;
+    }
+    emlptr = emlat + 1;
+    /* Just have hostname left to match: case insensitive */
+    if (OPENSSL_strcasecmp(baseptr, emlptr))
+        return X509_V_ERR_PERMITTED_VIOLATION;
 
-	return X509_V_OK;
+    return X509_V_OK;
 
-	}
+}
 
 static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
-	{
-	const char *baseptr = (char *)base->data;
-	const char *hostptr = (char *)uri->data;
-	const char *p = strchr(hostptr, ':');
-	int hostlen;
-	/* Check for foo:// and skip past it */
-	if (!p || (p[1] != '/') || (p[2] != '/'))
-		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
-	hostptr = p + 3;
+{
+    const char *baseptr = (char *)base->data;
+    const char *hostptr = (char *)uri->data;
+    const char *p = strchr(hostptr, ':');
+    int hostlen;
+    /* Check for foo:// and skip past it */
+    if (!p || (p[1] != '/') || (p[2] != '/'))
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    hostptr = p + 3;
 
-	/* Determine length of hostname part of URI */
+    /* Determine length of hostname part of URI */
 
-	/* Look for a port indicator as end of hostname first */
+    /* Look for a port indicator as end of hostname first */
 
-	p = strchr(hostptr, ':');
-	/* Otherwise look for trailing slash */
-	if (!p)
-		p = strchr(hostptr, '/');
+    p = strchr(hostptr, ':');
+    /* Otherwise look for trailing slash */
+    if (!p)
+        p = strchr(hostptr, '/');
 
-	if (!p)
-		hostlen = strlen(hostptr);
-	else
-		hostlen = p - hostptr;
+    if (!p)
+        hostlen = strlen(hostptr);
+    else
+        hostlen = p - hostptr;
 
-	if (hostlen == 0)
-		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    if (hostlen == 0)
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
 
-	/* Special case: inital '.' is RHS match */
-	if (*baseptr == '.')
-		{
-		if (hostlen > base->length)
-			{
-			p = hostptr + hostlen - base->length;
-			if (!OPENSSL_strncasecmp(p, baseptr, base->length))
-				return X509_V_OK;
-			}
-		return X509_V_ERR_PERMITTED_VIOLATION;
-		}
+    /* Special case: inital '.' is RHS match */
+    if (*baseptr == '.') {
+        if (hostlen > base->length) {
+            p = hostptr + hostlen - base->length;
+            if (!OPENSSL_strncasecmp(p, baseptr, base->length))
+                return X509_V_OK;
+        }
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    }
 
-	if ((base->length != (int)hostlen) || OPENSSL_strncasecmp(hostptr, baseptr, hostlen))
-		return X509_V_ERR_PERMITTED_VIOLATION;
+    if ((base->length != (int)hostlen)
+        || OPENSSL_strncasecmp(hostptr, baseptr, hostlen))
+        return X509_V_ERR_PERMITTED_VIOLATION;
 
-	return X509_V_OK;
+    return X509_V_OK;
 
-	}
+}
diff --git a/src/crypto/x509v3/v3_pci.c b/src/crypto/x509v3/v3_pci.c
index f19a37a..220f65e 100644
--- a/src/crypto/x509v3/v3_pci.c
+++ b/src/crypto/x509v3/v3_pci.c
@@ -1,6 +1,7 @@
 /* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
-/* Contributed to the OpenSSL Project 2004
- * by Richard Levitte (richard@levitte.org)
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
  */
 /* Copyright (c) 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
@@ -43,293 +44,274 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
-	BIO *out, int indent);
+                   BIO *out, int indent);
 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
-	X509V3_CTX *ctx, char *str);
+                                          X509V3_CTX *ctx, char *str);
 
 const X509V3_EXT_METHOD v3_pci =
-	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
-	  0,0,0,0,
-	  0,0,
-	  NULL, NULL,
-	  (X509V3_EXT_I2R)i2r_pci,
-	  (X509V3_EXT_R2I)r2i_pci,
-	  NULL,
-	};
+    { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+    0, 0, 0, 0,
+    0, 0,
+    NULL, NULL,
+    (X509V3_EXT_I2R)i2r_pci,
+    (X509V3_EXT_R2I)r2i_pci,
+    NULL,
+};
 
 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
-	BIO *out, int indent)
-	{
-	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
-	if (pci->pcPathLengthConstraint)
-	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
-	else
-	  BIO_printf(out, "infinite");
-	BIO_puts(out, "\n");
-	BIO_printf(out, "%*sPolicy Language: ", indent, "");
-	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
-	BIO_puts(out, "\n");
-	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
-	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
-		     pci->proxyPolicy->policy->data);
-	return 1;
-	}
+                   BIO *out, int indent)
+{
+    BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
+    if (pci->pcPathLengthConstraint)
+        i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
+    else
+        BIO_printf(out, "infinite");
+    BIO_puts(out, "\n");
+    BIO_printf(out, "%*sPolicy Language: ", indent, "");
+    i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
+    BIO_puts(out, "\n");
+    if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
+        BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
+                   pci->proxyPolicy->policy->data);
+    return 1;
+}
 
 static int process_pci_value(CONF_VALUE *val,
-	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
-	ASN1_OCTET_STRING **policy)
-	{
-	int free_policy = 0;
+                             ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
+                             ASN1_OCTET_STRING **policy)
+{
+    int free_policy = 0;
 
-	if (strcmp(val->name, "language") == 0)
-		{
-		if (*language)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
-			X509V3_conf_err(val);
-			return 0;
-			}
-		if (!(*language = OBJ_txt2obj(val->value, 0)))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-			X509V3_conf_err(val);
-			return 0;
-			}
-		}
-	else if (strcmp(val->name, "pathlen") == 0)
-		{
-		if (*pathlen)
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
-			X509V3_conf_err(val);
-			return 0;
-			}
-		if (!X509V3_get_value_int(val, pathlen))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH);
-			X509V3_conf_err(val);
-			return 0;
-			}
-		}
-	else if (strcmp(val->name, "policy") == 0)
-		{
-		unsigned char *tmp_data = NULL;
-		long val_len;
-		if (!*policy)
-			{
-			*policy = ASN1_OCTET_STRING_new();
-			if (!*policy)
-				{
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-				X509V3_conf_err(val);
-				return 0;
-				}
-			free_policy = 1;
-			}
-		if (strncmp(val->value, "hex:", 4) == 0)
-			{
-			unsigned char *tmp_data2 =
-				string_to_hex(val->value + 4, &val_len);
+    if (strcmp(val->name, "language") == 0) {
+        if (*language) {
+            OPENSSL_PUT_ERROR(X509V3,
+                              X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+            X509V3_conf_err(val);
+            return 0;
+        }
+        if (!(*language = OBJ_txt2obj(val->value, 0))) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return 0;
+        }
+    } else if (strcmp(val->name, "pathlen") == 0) {
+        if (*pathlen) {
+            OPENSSL_PUT_ERROR(X509V3,
+                              X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+            X509V3_conf_err(val);
+            return 0;
+        }
+        if (!X509V3_get_value_int(val, pathlen)) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH);
+            X509V3_conf_err(val);
+            return 0;
+        }
+    } else if (strcmp(val->name, "policy") == 0) {
+        unsigned char *tmp_data = NULL;
+        long val_len;
+        if (!*policy) {
+            *policy = ASN1_OCTET_STRING_new();
+            if (!*policy) {
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                return 0;
+            }
+            free_policy = 1;
+        }
+        if (strncmp(val->value, "hex:", 4) == 0) {
+            unsigned char *tmp_data2 =
+                string_to_hex(val->value + 4, &val_len);
 
-			if (!tmp_data2) 
-				{
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
-				X509V3_conf_err(val);
-				goto err;
-				}
+            if (!tmp_data2) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
+                X509V3_conf_err(val);
+                goto err;
+            }
 
-			tmp_data = OPENSSL_realloc((*policy)->data,
-				(*policy)->length + val_len + 1);
-			if (tmp_data)
-				{
-				(*policy)->data = tmp_data;
-				memcpy(&(*policy)->data[(*policy)->length],
-					tmp_data2, val_len);
-				(*policy)->length += val_len;
-				(*policy)->data[(*policy)->length] = '\0';
-				}
-			else
-				{
-				OPENSSL_free(tmp_data2);
-				/* realloc failure implies the original data space is b0rked too! */
-				(*policy)->data = NULL;
-				(*policy)->length = 0;
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-				X509V3_conf_err(val);
-				goto err;
-				}
-			OPENSSL_free(tmp_data2);
-			}
-		else if (strncmp(val->value, "file:", 5) == 0)
-			{
-			unsigned char buf[2048];
-			int n;
-			BIO *b = BIO_new_file(val->value + 5, "r");
-			if (!b)
-				{
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
-				X509V3_conf_err(val);
-				goto err;
-				}
-			while((n = BIO_read(b, buf, sizeof(buf))) > 0
-				|| (n == 0 && BIO_should_retry(b)))
-				{
-				if (!n) continue;
+            tmp_data = OPENSSL_realloc((*policy)->data,
+                                       (*policy)->length + val_len + 1);
+            if (tmp_data) {
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length],
+                       tmp_data2, val_len);
+                (*policy)->length += val_len;
+                (*policy)->data[(*policy)->length] = '\0';
+            } else {
+                OPENSSL_free(tmp_data2);
+                /*
+                 * realloc failure implies the original data space is b0rked
+                 * too!
+                 */
+                (*policy)->data = NULL;
+                (*policy)->length = 0;
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            OPENSSL_free(tmp_data2);
+        } else if (strncmp(val->value, "file:", 5) == 0) {
+            unsigned char buf[2048];
+            int n;
+            BIO *b = BIO_new_file(val->value + 5, "r");
+            if (!b) {
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            while ((n = BIO_read(b, buf, sizeof(buf))) > 0
+                   || (n == 0 && BIO_should_retry(b))) {
+                if (!n)
+                    continue;
 
-				tmp_data = OPENSSL_realloc((*policy)->data,
-					(*policy)->length + n + 1);
+                tmp_data = OPENSSL_realloc((*policy)->data,
+                                           (*policy)->length + n + 1);
 
-				if (!tmp_data)
-					break;
+                if (!tmp_data)
+                    break;
 
-				(*policy)->data = tmp_data;
-				memcpy(&(*policy)->data[(*policy)->length],
-					buf, n);
-				(*policy)->length += n;
-				(*policy)->data[(*policy)->length] = '\0';
-				}
-			BIO_free_all(b);
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length], buf, n);
+                (*policy)->length += n;
+                (*policy)->data[(*policy)->length] = '\0';
+            }
+            BIO_free_all(b);
 
-			if (n < 0)
-				{
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
-				X509V3_conf_err(val);
-				goto err;
-				}
-			}
-		else if (strncmp(val->value, "text:", 5) == 0)
-			{
-			val_len = strlen(val->value + 5);
-			tmp_data = OPENSSL_realloc((*policy)->data,
-				(*policy)->length + val_len + 1);
-			if (tmp_data)
-				{
-				(*policy)->data = tmp_data;
-				memcpy(&(*policy)->data[(*policy)->length],
-					val->value + 5, val_len);
-				(*policy)->length += val_len;
-				(*policy)->data[(*policy)->length] = '\0';
-				}
-			else
-				{
-				/* realloc failure implies the original data space is b0rked too! */
-				(*policy)->data = NULL;
-				(*policy)->length = 0;
-				OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-				X509V3_conf_err(val);
-				goto err;
-				}
-			}
-		else
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
-			X509V3_conf_err(val);
-			goto err;
-			}
-		if (!tmp_data)
-			{
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			X509V3_conf_err(val);
-			goto err;
-			}
-		}
-	return 1;
-err:
-	if (free_policy)
-		{
-		ASN1_OCTET_STRING_free(*policy);
-		*policy = NULL;
-		}
-	return 0;
-	}
+            if (n < 0) {
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        } else if (strncmp(val->value, "text:", 5) == 0) {
+            val_len = strlen(val->value + 5);
+            tmp_data = OPENSSL_realloc((*policy)->data,
+                                       (*policy)->length + val_len + 1);
+            if (tmp_data) {
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length],
+                       val->value + 5, val_len);
+                (*policy)->length += val_len;
+                (*policy)->data[(*policy)->length] = '\0';
+            } else {
+                /*
+                 * realloc failure implies the original data space is b0rked
+                 * too!
+                 */
+                (*policy)->data = NULL;
+                (*policy)->length = 0;
+                OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+            X509V3_conf_err(val);
+            goto err;
+        }
+        if (!tmp_data) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    return 1;
+ err:
+    if (free_policy) {
+        ASN1_OCTET_STRING_free(*policy);
+        *policy = NULL;
+    }
+    return 0;
+}
 
 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
-	X509V3_CTX *ctx, char *value)
-	{
-	PROXY_CERT_INFO_EXTENSION *pci = NULL;
-	STACK_OF(CONF_VALUE) *vals;
-	ASN1_OBJECT *language = NULL;
-	ASN1_INTEGER *pathlen = NULL;
-	ASN1_OCTET_STRING *policy = NULL;
-	size_t i, j;
-	int nid;
+                                          X509V3_CTX *ctx, char *value)
+{
+    PROXY_CERT_INFO_EXTENSION *pci = NULL;
+    STACK_OF(CONF_VALUE) *vals;
+    ASN1_OBJECT *language = NULL;
+    ASN1_INTEGER *pathlen = NULL;
+    ASN1_OCTET_STRING *policy = NULL;
+    size_t i, j;
+    int nid;
 
-	vals = X509V3_parse_list(value);
-	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
-		{
-		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
-		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
-			{
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
-			X509V3_conf_err(cnf);
-			goto err;
-			}
-		if (*cnf->name == '@')
-			{
-			STACK_OF(CONF_VALUE) *sect;
-			int success_p = 1;
+    vals = X509V3_parse_list(value);
+    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+        CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
+        if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+        if (*cnf->name == '@') {
+            STACK_OF(CONF_VALUE) *sect;
+            int success_p = 1;
 
-			sect = X509V3_get_section(ctx, cnf->name + 1);
-			if (!sect)
-				{
-				OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
-				X509V3_conf_err(cnf);
-				goto err;
-				}
-			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
-				{
-				success_p =
-					process_pci_value(sk_CONF_VALUE_value(sect, j),
-						&language, &pathlen, &policy);
-				}
-			X509V3_section_free(ctx, sect);
-			if (!success_p)
-				goto err;
-			}
-		else
-			{
-			if (!process_pci_value(cnf,
-					&language, &pathlen, &policy))
-				{
-				X509V3_conf_err(cnf);
-				goto err;
-				}
-			}
-		}
+            sect = X509V3_get_section(ctx, cnf->name + 1);
+            if (!sect) {
+                OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
+                success_p =
+                    process_pci_value(sk_CONF_VALUE_value(sect, j),
+                                      &language, &pathlen, &policy);
+            }
+            X509V3_section_free(ctx, sect);
+            if (!success_p)
+                goto err;
+        } else {
+            if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+        }
+    }
 
-	/* Language is mandatory */
-	if (!language)
-		{
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
-		goto err;
-		}
-	nid = OBJ_obj2nid(language);
-	if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy)
-		{
-		OPENSSL_PUT_ERROR(X509V3,
-			X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
-		goto err;
-		}
+    /* Language is mandatory */
+    if (!language) {
+        OPENSSL_PUT_ERROR(X509V3,
+                          X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+        goto err;
+    }
+    nid = OBJ_obj2nid(language);
+    if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) {
+        OPENSSL_PUT_ERROR(X509V3,
+                          X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+        goto err;
+    }
 
-	pci = PROXY_CERT_INFO_EXTENSION_new();
-	if (!pci)
-		{
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    pci = PROXY_CERT_INFO_EXTENSION_new();
+    if (!pci) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	pci->proxyPolicy->policyLanguage = language; language = NULL;
-	pci->proxyPolicy->policy = policy; policy = NULL;
-	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
-	goto end;
-err:
-	if (language) { ASN1_OBJECT_free(language); language = NULL; }
-	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
-	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
-	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
-end:
-	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
-	return pci;
-	}
+    pci->proxyPolicy->policyLanguage = language;
+    language = NULL;
+    pci->proxyPolicy->policy = policy;
+    policy = NULL;
+    pci->pcPathLengthConstraint = pathlen;
+    pathlen = NULL;
+    goto end;
+ err:
+    if (language) {
+        ASN1_OBJECT_free(language);
+        language = NULL;
+    }
+    if (pathlen) {
+        ASN1_INTEGER_free(pathlen);
+        pathlen = NULL;
+    }
+    if (policy) {
+        ASN1_OCTET_STRING_free(policy);
+        policy = NULL;
+    }
+    if (pci) {
+        PROXY_CERT_INFO_EXTENSION_free(pci);
+        pci = NULL;
+    }
+ end:
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    return pci;
+}
diff --git a/src/crypto/x509v3/v3_pcia.c b/src/crypto/x509v3/v3_pcia.c
index e3e3192..3f285f3 100644
--- a/src/crypto/x509v3/v3_pcia.c
+++ b/src/crypto/x509v3/v3_pcia.c
@@ -1,6 +1,7 @@
 /* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */
-/* Contributed to the OpenSSL Project 2004
- * by Richard Levitte (richard@levitte.org)
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
  */
 /* Copyright (c) 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
@@ -40,17 +41,17 @@
 
 
 ASN1_SEQUENCE(PROXY_POLICY) =
-	{
-	ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
-	ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
+        {
+        ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
+        ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
 } ASN1_SEQUENCE_END(PROXY_POLICY)
 
 IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
 
 ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
-	{
-	ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
-	ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
+        {
+        ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
+        ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
 } ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
 
 IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
diff --git a/src/crypto/x509v3/v3_pcons.c b/src/crypto/x509v3/v3_pcons.c
index b752290..1a46314 100644
--- a/src/crypto/x509v3/v3_pcons.c
+++ b/src/crypto/x509v3/v3_pcons.c
@@ -1,5 +1,6 @@
 /* v3_pcons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 #include <string.h>
 
@@ -65,78 +65,75 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
-		       STACK_OF(CONF_VALUE) *extlist);
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+                                                    *method, void *bcons, STACK_OF(CONF_VALUE)
+                                                    *extlist);
 static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
-				    X509V3_CTX *ctx,
-				    STACK_OF(CONF_VALUE) *values);
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *values);
 
 const X509V3_EXT_METHOD v3_policy_constraints = {
-NID_policy_constraints, 0,
-ASN1_ITEM_ref(POLICY_CONSTRAINTS),
-0,0,0,0,
-0,0,
-i2v_POLICY_CONSTRAINTS,
-v2i_POLICY_CONSTRAINTS,
-NULL,NULL,
-NULL
+    NID_policy_constraints, 0,
+    ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_POLICY_CONSTRAINTS,
+    v2i_POLICY_CONSTRAINTS,
+    NULL, NULL,
+    NULL
 };
 
 ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
-	ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
-	ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
+        ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
+        ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
 } ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
 
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
-		       STACK_OF(CONF_VALUE) *extlist)
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+                                                    *method, void *a, STACK_OF(CONF_VALUE)
+                                                    *extlist)
 {
-	POLICY_CONSTRAINTS *pcons = a;
-	X509V3_add_value_int("Require Explicit Policy",
-			pcons->requireExplicitPolicy, &extlist);
-	X509V3_add_value_int("Inhibit Policy Mapping",
-			pcons->inhibitPolicyMapping, &extlist);
-	return extlist;
+    POLICY_CONSTRAINTS *pcons = a;
+    X509V3_add_value_int("Require Explicit Policy",
+                         pcons->requireExplicitPolicy, &extlist);
+    X509V3_add_value_int("Inhibit Policy Mapping",
+                         pcons->inhibitPolicyMapping, &extlist);
+    return extlist;
 }
 
 static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
-				    X509V3_CTX *ctx,
-				    STACK_OF(CONF_VALUE) *values)
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *values)
 {
-	POLICY_CONSTRAINTS *pcons=NULL;
-	CONF_VALUE *val;
-	size_t i;
-	if(!(pcons = POLICY_CONSTRAINTS_new())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
-		val = sk_CONF_VALUE_value(values, i);
-		if(!strcmp(val->name, "requireExplicitPolicy")) {
-			if(!X509V3_get_value_int(val,
-				&pcons->requireExplicitPolicy)) goto err;
-		} else if(!strcmp(val->name, "inhibitPolicyMapping")) {
-			if(!X509V3_get_value_int(val,
-				&pcons->inhibitPolicyMapping)) goto err;
-		} else {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
-			X509V3_conf_err(val);
-			goto err;
-		}
-	}
-	if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
-		goto err;
-	}
+    POLICY_CONSTRAINTS *pcons = NULL;
+    CONF_VALUE *val;
+    size_t i;
+    if (!(pcons = POLICY_CONSTRAINTS_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        val = sk_CONF_VALUE_value(values, i);
+        if (!strcmp(val->name, "requireExplicitPolicy")) {
+            if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy))
+                goto err;
+        } else if (!strcmp(val->name, "inhibitPolicyMapping")) {
+            if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping))
+                goto err;
+        } else {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+        goto err;
+    }
 
-	return pcons;
-	err:
-	POLICY_CONSTRAINTS_free(pcons);
-	return NULL;
+    return pcons;
+ err:
+    POLICY_CONSTRAINTS_free(pcons);
+    return NULL;
 }
-
diff --git a/src/crypto/x509v3/v3_pku.c b/src/crypto/x509v3/v3_pku.c
index 445eda6..e4868b4 100644
--- a/src/crypto/x509v3/v3_pku.c
+++ b/src/crypto/x509v3/v3_pku.c
@@ -1,6 +1,7 @@
 /* v3_pku.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -62,48 +63,48 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
-static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+                                 PKEY_USAGE_PERIOD *usage, BIO *out,
+                                 int indent);
 /*
-static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
-*/
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+ */
 const X509V3_EXT_METHOD v3_pkey_usage_period = {
-NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
-0,0,0,0,
-0,0,0,0,
-(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
-NULL
+    NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+    0, 0, 0, 0,
+    0, 0, 0, 0,
+    (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
+    NULL
 };
 
 ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
-	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
-	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
+        ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
+        ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
 } ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
 
 static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
-	     PKEY_USAGE_PERIOD *usage, BIO *out, int indent)
+                                 PKEY_USAGE_PERIOD *usage, BIO *out,
+                                 int indent)
 {
-	BIO_printf(out, "%*s", indent, "");
-	if(usage->notBefore) {
-		BIO_write(out, "Not Before: ", 12);
-		ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
-		if(usage->notAfter) BIO_write(out, ", ", 2);
-	}
-	if(usage->notAfter) {
-		BIO_write(out, "Not After: ", 11);
-		ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
-	}
-	return 1;
+    BIO_printf(out, "%*s", indent, "");
+    if (usage->notBefore) {
+        BIO_write(out, "Not Before: ", 12);
+        ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
+        if (usage->notAfter)
+            BIO_write(out, ", ", 2);
+    }
+    if (usage->notAfter) {
+        BIO_write(out, "Not After: ", 11);
+        ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
+    }
+    return 1;
 }
 
 /*
-static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
-X509V3_EXT_METHOD *method;
-X509V3_CTX *ctx;
-STACK_OF(CONF_VALUE) *values;
-{
-return NULL;
-}
-*/
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
+ * X509V3_EXT_METHOD *method; X509V3_CTX *ctx; STACK_OF(CONF_VALUE) *values;
+ * { return NULL; }
+ */
diff --git a/src/crypto/x509v3/v3_pmaps.c b/src/crypto/x509v3/v3_pmaps.c
index 5b90977..caacdb2 100644
--- a/src/crypto/x509v3/v3_pmaps.c
+++ b/src/crypto/x509v3/v3_pmaps.c
@@ -1,5 +1,6 @@
 /* v3_pmaps.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 
 #include <openssl/asn1t.h>
@@ -63,94 +63,92 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
-		    STACK_OF(CONF_VALUE) *extlist);
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+                                                 *method, void *pmps, STACK_OF(CONF_VALUE)
+                                                 *extlist);
 
 const X509V3_EXT_METHOD v3_policy_mappings = {
-	NID_policy_mappings, 0,
-	ASN1_ITEM_ref(POLICY_MAPPINGS),
-	0,0,0,0,
-	0,0,
-	i2v_POLICY_MAPPINGS,
-	v2i_POLICY_MAPPINGS,
-	0,0,
-	NULL
+    NID_policy_mappings, 0,
+    ASN1_ITEM_ref(POLICY_MAPPINGS),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_POLICY_MAPPINGS,
+    v2i_POLICY_MAPPINGS,
+    0, 0,
+    NULL
 };
 
 ASN1_SEQUENCE(POLICY_MAPPING) = {
-	ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
-	ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
+        ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
+        ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
 } ASN1_SEQUENCE_END(POLICY_MAPPING)
 
-ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = 
-	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
-								POLICY_MAPPING)
+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
+                                                                POLICY_MAPPING)
 ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
 
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
 
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
-		    STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+                                                 *method, void *a, STACK_OF(CONF_VALUE)
+                                                 *ext_list)
 {
-	POLICY_MAPPINGS *pmaps = a;
-	POLICY_MAPPING *pmap;
-	size_t i;
-	char obj_tmp1[80];
-	char obj_tmp2[80];
-	for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
-		pmap = sk_POLICY_MAPPING_value(pmaps, i);
-		i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
-		i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
-		X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
-	}
-	return ext_list;
+    POLICY_MAPPINGS *pmaps = a;
+    POLICY_MAPPING *pmap;
+    size_t i;
+    char obj_tmp1[80];
+    char obj_tmp2[80];
+    for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
+        pmap = sk_POLICY_MAPPING_value(pmaps, i);
+        i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
+        i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
+        X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
+    }
+    return ext_list;
 }
 
 static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
-				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
-	POLICY_MAPPINGS *pmaps;
-	POLICY_MAPPING *pmap;
-	ASN1_OBJECT *obj1, *obj2;
-	CONF_VALUE *val;
-	size_t i;
+    POLICY_MAPPINGS *pmaps;
+    POLICY_MAPPING *pmap;
+    ASN1_OBJECT *obj1, *obj2;
+    CONF_VALUE *val;
+    size_t i;
 
-	if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
+    if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
 
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		val = sk_CONF_VALUE_value(nval, i);
-		if(!val->value || !val->name) {
-			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-			X509V3_conf_err(val);
-			return NULL;
-		}
-		obj1 = OBJ_txt2obj(val->name, 0);
-		obj2 = OBJ_txt2obj(val->value, 0);
-		if(!obj1 || !obj2) {
-			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
-			X509V3_conf_err(val);
-			return NULL;
-		}
-		pmap = POLICY_MAPPING_new();
-		if (!pmap) {
-			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			return NULL;
-		}
-		pmap->issuerDomainPolicy = obj1;
-		pmap->subjectDomainPolicy = obj2;
-		sk_POLICY_MAPPING_push(pmaps, pmap);
-	}
-	return pmaps;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (!val->value || !val->name) {
+            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return NULL;
+        }
+        obj1 = OBJ_txt2obj(val->name, 0);
+        obj2 = OBJ_txt2obj(val->value, 0);
+        if (!obj1 || !obj2) {
+            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return NULL;
+        }
+        pmap = POLICY_MAPPING_new();
+        if (!pmap) {
+            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        pmap->issuerDomainPolicy = obj1;
+        pmap->subjectDomainPolicy = obj2;
+        sk_POLICY_MAPPING_push(pmaps, pmap);
+    }
+    return pmaps;
 }
diff --git a/src/crypto/x509v3/v3_prn.c b/src/crypto/x509v3/v3_prn.c
index 87aef4d..5015efc 100644
--- a/src/crypto/x509v3/v3_prn.c
+++ b/src/crypto/x509v3/v3_prn.c
@@ -1,6 +1,7 @@
 /* v3_prn.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -63,145 +64,169 @@
 #include <openssl/mem.h>
 #include <openssl/x509v3.h>
 
-
 /* Extension printing routines */
 
-static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+                             unsigned long flag, int indent, int supported);
 
 /* Print out a name+value stack */
 
-void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+                        int ml)
 {
-	size_t i;
-	CONF_VALUE *nval;
-	if(!val) return;
-	if(!ml || !sk_CONF_VALUE_num(val)) {
-		BIO_printf(out, "%*s", indent, "");
-		if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n");
-	}
-	for(i = 0; i < sk_CONF_VALUE_num(val); i++) {
-		if(ml) BIO_printf(out, "%*s", indent, "");
-		else if(i > 0) BIO_printf(out, ", ");
-		nval = sk_CONF_VALUE_value(val, i);
-		if(!nval->name) BIO_puts(out, nval->value);
-		else if(!nval->value) BIO_puts(out, nval->name);
-		else BIO_printf(out, "%s:%s", nval->name, nval->value);
-		if(ml) BIO_puts(out, "\n");
-	}
+    size_t i;
+    CONF_VALUE *nval;
+    if (!val)
+        return;
+    if (!ml || !sk_CONF_VALUE_num(val)) {
+        BIO_printf(out, "%*s", indent, "");
+        if (!sk_CONF_VALUE_num(val))
+            BIO_puts(out, "<EMPTY>\n");
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
+        if (ml)
+            BIO_printf(out, "%*s", indent, "");
+        else if (i > 0)
+            BIO_printf(out, ", ");
+        nval = sk_CONF_VALUE_value(val, i);
+        if (!nval->name)
+            BIO_puts(out, nval->value);
+        else if (!nval->value)
+            BIO_puts(out, nval->name);
+        else
+            BIO_printf(out, "%s:%s", nval->name, nval->value);
+        if (ml)
+            BIO_puts(out, "\n");
+    }
 }
 
 /* Main routine: print out a general extension */
 
-int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+                     int indent)
 {
-	void *ext_str = NULL;
-	char *value = NULL;
-	const unsigned char *p;
-	const X509V3_EXT_METHOD *method;	
-	STACK_OF(CONF_VALUE) *nval = NULL;
-	int ok = 1;
+    void *ext_str = NULL;
+    char *value = NULL;
+    const unsigned char *p;
+    const X509V3_EXT_METHOD *method;
+    STACK_OF(CONF_VALUE) *nval = NULL;
+    int ok = 1;
 
-	if(!(method = X509V3_EXT_get(ext)))
-		return unknown_ext_print(out, ext, flag, indent, 0);
-	p = ext->value->data;
-	if(method->it) ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
-	else ext_str = method->d2i(NULL, &p, ext->value->length);
+    if (!(method = X509V3_EXT_get(ext)))
+        return unknown_ext_print(out, ext, flag, indent, 0);
+    p = ext->value->data;
+    if (method->it)
+        ext_str =
+            ASN1_item_d2i(NULL, &p, ext->value->length,
+                          ASN1_ITEM_ptr(method->it));
+    else
+        ext_str = method->d2i(NULL, &p, ext->value->length);
 
-	if(!ext_str) return unknown_ext_print(out, ext, flag, indent, 1);
+    if (!ext_str)
+        return unknown_ext_print(out, ext, flag, indent, 1);
 
-	if(method->i2s) {
-		if(!(value = method->i2s(method, ext_str))) {
-			ok = 0;
-			goto err;
-		}
-		BIO_printf(out, "%*s%s", indent, "", value);
-	} else if(method->i2v) {
-		if(!(nval = method->i2v(method, ext_str, NULL))) {
-			ok = 0;
-			goto err;
-		}
-		X509V3_EXT_val_prn(out, nval, indent,
-				 method->ext_flags & X509V3_EXT_MULTILINE);
-	} else if(method->i2r) {
-		if(!method->i2r(method, ext_str, out, indent)) ok = 0;
-	} else ok = 0;
+    if (method->i2s) {
+        if (!(value = method->i2s(method, ext_str))) {
+            ok = 0;
+            goto err;
+        }
+        BIO_printf(out, "%*s%s", indent, "", value);
+    } else if (method->i2v) {
+        if (!(nval = method->i2v(method, ext_str, NULL))) {
+            ok = 0;
+            goto err;
+        }
+        X509V3_EXT_val_prn(out, nval, indent,
+                           method->ext_flags & X509V3_EXT_MULTILINE);
+    } else if (method->i2r) {
+        if (!method->i2r(method, ext_str, out, indent))
+            ok = 0;
+    } else
+        ok = 0;
 
-	err:
-		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
-		if(value) OPENSSL_free(value);
-		if(method->it) ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
-		else method->ext_free(ext_str);
-		return ok;
+ err:
+    sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+    if (value)
+        OPENSSL_free(value);
+    if (method->it)
+        ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
+    else
+        method->ext_free(ext_str);
+    return ok;
 }
 
-int X509V3_extensions_print(BIO *bp, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
+int X509V3_extensions_print(BIO *bp, const char *title,
+                            STACK_OF(X509_EXTENSION) *exts,
+                            unsigned long flag, int indent)
 {
-	size_t i;
-	int j;
+    size_t i;
+    int j;
 
-	if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
+    if (sk_X509_EXTENSION_num(exts) <= 0)
+        return 1;
 
-	if(title) 
-		{
-		BIO_printf(bp,"%*s%s:\n",indent, "", title);
-		indent += 4;
-		}
+    if (title) {
+        BIO_printf(bp, "%*s%s:\n", indent, "", title);
+        indent += 4;
+    }
 
-	for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
-		{
-		ASN1_OBJECT *obj;
-		X509_EXTENSION *ex;
-		ex=sk_X509_EXTENSION_value(exts, i);
-		if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
-		obj=X509_EXTENSION_get_object(ex);
-		i2a_ASN1_OBJECT(bp,obj);
-		j=X509_EXTENSION_get_critical(ex);
-		if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
-			return 0;
-		if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
-			{
-			BIO_printf(bp, "%*s", indent + 4, "");
-			M_ASN1_OCTET_STRING_print(bp,ex->value);
-			}
-		if (BIO_write(bp,"\n",1) <= 0) return 0;
-		}
-	return 1;
+    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+        ASN1_OBJECT *obj;
+        X509_EXTENSION *ex;
+        ex = sk_X509_EXTENSION_value(exts, i);
+        if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
+            return 0;
+        obj = X509_EXTENSION_get_object(ex);
+        i2a_ASN1_OBJECT(bp, obj);
+        j = X509_EXTENSION_get_critical(ex);
+        if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+            return 0;
+        if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
+            BIO_printf(bp, "%*s", indent + 4, "");
+            M_ASN1_OCTET_STRING_print(bp, ex->value);
+        }
+        if (BIO_write(bp, "\n", 1) <= 0)
+            return 0;
+    }
+    return 1;
 }
 
-static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+                             unsigned long flag, int indent, int supported)
 {
-	switch(flag & X509V3_EXT_UNKNOWN_MASK) {
+    switch (flag & X509V3_EXT_UNKNOWN_MASK) {
 
-		case X509V3_EXT_DEFAULT:
-		return 0;
+    case X509V3_EXT_DEFAULT:
+        return 0;
 
-		case X509V3_EXT_ERROR_UNKNOWN:
-		if(supported)
-			BIO_printf(out, "%*s<Parse Error>", indent, "");
-		else
-			BIO_printf(out, "%*s<Not Supported>", indent, "");
-		return 1;
+    case X509V3_EXT_ERROR_UNKNOWN:
+        if (supported)
+            BIO_printf(out, "%*s<Parse Error>", indent, "");
+        else
+            BIO_printf(out, "%*s<Not Supported>", indent, "");
+        return 1;
 
-		case X509V3_EXT_PARSE_UNKNOWN:
-			return ASN1_parse_dump(out,
-				ext->value->data, ext->value->length, indent, -1);
-		case X509V3_EXT_DUMP_UNKNOWN:
-			return BIO_hexdump(out, ext->value->data, ext->value->length, indent);
+    case X509V3_EXT_PARSE_UNKNOWN:
+        return ASN1_parse_dump(out,
+                               ext->value->data, ext->value->length, indent,
+                               -1);
+    case X509V3_EXT_DUMP_UNKNOWN:
+        return BIO_hexdump(out, ext->value->data, ext->value->length, indent);
 
-		default:
-		return 1;
-	}
+    default:
+        return 1;
+    }
 }
-	
 
 #ifndef OPENSSL_NO_FP_API
 int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
 {
-	BIO *bio_tmp;
-	int ret;
-	if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0;
-	ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
-	BIO_free(bio_tmp);
-	return ret;
+    BIO *bio_tmp;
+    int ret;
+    if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)))
+        return 0;
+    ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
+    BIO_free(bio_tmp);
+    return ret;
 }
 #endif
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 9a0a7bc..85bc15b 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -1,6 +1,7 @@
 /* v3_purp.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
  */
 /* ====================================================================
  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -69,26 +70,32 @@
 
 #include "../internal.h"
 
-
 #define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
 #define ku_reject(x, usage) \
-	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+        (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
 #define xku_reject(x, usage) \
-	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+        (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
 #define ns_reject(x, usage) \
-	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+        (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
 
 static void x509v3_cache_extensions(X509 *x);
 
 static int check_ssl_ca(const X509 *x);
-static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca);
 static int purpose_smime(const X509 *x, int ca);
-static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca);
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+                                  int ca);
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+                                        int ca);
 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
 
@@ -96,15 +103,29 @@
 static void xptable_free(X509_PURPOSE *p);
 
 static X509_PURPOSE xstandard[] = {
-	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, (char *) "SSL client", (char *) "sslclient", NULL},
-	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, (char *) "SSL server", (char *) "sslserver", NULL},
-	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, (char *) "Netscape SSL server", (char *) "nssslserver", NULL},
-	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, (char *) "S/MIME signing", (char *) "smimesign", NULL},
-	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, (char *) "S/MIME encryption", (char *) "smimeencrypt", NULL},
-	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, (char *) "CRL signing", (char *) "crlsign", NULL},
-	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *) "Any Purpose", (char *) "any", NULL},
-	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, (char *) "OCSP helper", (char *) "ocsphelper", NULL},
-	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, (char *) "Time Stamp signing", (char *) "timestampsign", NULL},
+    {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0,
+     check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient",
+     NULL},
+    {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+     check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver",
+     NULL},
+    {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+     check_purpose_ns_ssl_server, (char *)"Netscape SSL server",
+     (char *)"nssslserver", NULL},
+    {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign,
+     (char *)"S/MIME signing", (char *)"smimesign", NULL},
+    {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0,
+     check_purpose_smime_encrypt, (char *)"S/MIME encryption",
+     (char *)"smimeencrypt", NULL},
+    {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign,
+     (char *)"CRL signing", (char *)"crlsign", NULL},
+    {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose",
+     (char *)"any", NULL},
+    {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper,
+     (char *)"OCSP helper", (char *)"ocsphelper", NULL},
+    {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0,
+     check_purpose_timestamp_sign, (char *)"Time Stamp signing",
+     (char *)"timestampsign", NULL},
 };
 
 #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
@@ -113,693 +134,741 @@
 
 static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b)
 {
-	return (*a)->purpose - (*b)->purpose;
+    return (*a)->purpose - (*b)->purpose;
 }
 
-/* As much as I'd like to make X509_check_purpose use a "const" X509*
- * I really can't because it does recalculate hashes and do other non-const
- * things. */
+/*
+ * As much as I'd like to make X509_check_purpose use a "const" X509* I
+ * really can't because it does recalculate hashes and do other non-const
+ * things.
+ */
 int X509_check_purpose(X509 *x, int id, int ca)
 {
-	int idx;
-	const X509_PURPOSE *pt;
-	if(!(x->ex_flags & EXFLAG_SET)) {
-		x509v3_cache_extensions(x);
-	}
-	if(id == -1) return 1;
-	idx = X509_PURPOSE_get_by_id(id);
-	if(idx == -1) return -1;
-	pt = X509_PURPOSE_get0(idx);
-	return pt->check_purpose(pt, x, ca);
+    int idx;
+    const X509_PURPOSE *pt;
+    if (!(x->ex_flags & EXFLAG_SET)) {
+        x509v3_cache_extensions(x);
+    }
+    if (id == -1)
+        return 1;
+    idx = X509_PURPOSE_get_by_id(id);
+    if (idx == -1)
+        return -1;
+    pt = X509_PURPOSE_get0(idx);
+    return pt->check_purpose(pt, x, ca);
 }
 
 int X509_PURPOSE_set(int *p, int purpose)
 {
-	if(X509_PURPOSE_get_by_id(purpose) == -1) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
-		return 0;
-	}
-	*p = purpose;
-	return 1;
+    if (X509_PURPOSE_get_by_id(purpose) == -1) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
+        return 0;
+    }
+    *p = purpose;
+    return 1;
 }
 
 int X509_PURPOSE_get_count(void)
 {
-	if(!xptable) return X509_PURPOSE_COUNT;
-	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
+    if (!xptable)
+        return X509_PURPOSE_COUNT;
+    return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
 }
 
-X509_PURPOSE * X509_PURPOSE_get0(int idx)
+X509_PURPOSE *X509_PURPOSE_get0(int idx)
 {
-	if(idx < 0) return NULL;
-	if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
-	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
+    if (idx < 0)
+        return NULL;
+    if (idx < (int)X509_PURPOSE_COUNT)
+        return xstandard + idx;
+    return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
 }
 
 int X509_PURPOSE_get_by_sname(char *sname)
 {
-	int i;
-	X509_PURPOSE *xptmp;
-	for(i = 0; i < X509_PURPOSE_get_count(); i++) {
-		xptmp = X509_PURPOSE_get0(i);
-		if(!strcmp(xptmp->sname, sname)) return i;
-	}
-	return -1;
+    int i;
+    X509_PURPOSE *xptmp;
+    for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+        xptmp = X509_PURPOSE_get0(i);
+        if (!strcmp(xptmp->sname, sname))
+            return i;
+    }
+    return -1;
 }
 
 int X509_PURPOSE_get_by_id(int purpose)
 {
-	X509_PURPOSE tmp;
-	size_t idx;
+    X509_PURPOSE tmp;
+    size_t idx;
 
-	if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
-		return purpose - X509_PURPOSE_MIN;
-	tmp.purpose = purpose;
-	if(!xptable) return -1;
+    if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
+        return purpose - X509_PURPOSE_MIN;
+    tmp.purpose = purpose;
+    if (!xptable)
+        return -1;
 
-	if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
-		return -1;
-	return idx + X509_PURPOSE_COUNT;
+    if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
+        return -1;
+    return idx + X509_PURPOSE_COUNT;
 }
 
 int X509_PURPOSE_add(int id, int trust, int flags,
-			int (*ck)(const X509_PURPOSE *, const X509 *, int),
-					char *name, char *sname, void *arg)
+                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
+                     char *name, char *sname, void *arg)
 {
-	int idx;
-	X509_PURPOSE *ptmp;
-	char *name_dup, *sname_dup;
+    int idx;
+    X509_PURPOSE *ptmp;
+    char *name_dup, *sname_dup;
 
-	/* This is set according to what we change: application can't set it */
-	flags &= ~X509_PURPOSE_DYNAMIC;
-	/* This will always be set for application modified trust entries */
-	flags |= X509_PURPOSE_DYNAMIC_NAME;
-	/* Get existing entry if any */
-	idx = X509_PURPOSE_get_by_id(id);
-	/* Need a new entry */
-	if(idx == -1) {
-		if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			return 0;
-		}
-		ptmp->flags = X509_PURPOSE_DYNAMIC;
-	} else ptmp = X509_PURPOSE_get0(idx);
+    /*
+     * This is set according to what we change: application can't set it
+     */
+    flags &= ~X509_PURPOSE_DYNAMIC;
+    /* This will always be set for application modified trust entries */
+    flags |= X509_PURPOSE_DYNAMIC_NAME;
+    /* Get existing entry if any */
+    idx = X509_PURPOSE_get_by_id(id);
+    /* Need a new entry */
+    if (idx == -1) {
+        if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        ptmp->flags = X509_PURPOSE_DYNAMIC;
+    } else
+        ptmp = X509_PURPOSE_get0(idx);
 
-	/* Duplicate the supplied names. */
-	name_dup = BUF_strdup(name);
-	sname_dup = BUF_strdup(sname);
-	if (name_dup == NULL || sname_dup == NULL) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		if (name_dup != NULL)
-			OPENSSL_free(name_dup);
-		if (sname_dup != NULL)
-			OPENSSL_free(sname_dup);
-		if (idx == -1)
-			OPENSSL_free(ptmp);
-		return 0;
-	}
+    /* Duplicate the supplied names. */
+    name_dup = BUF_strdup(name);
+    sname_dup = BUF_strdup(sname);
+    if (name_dup == NULL || sname_dup == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        if (name_dup != NULL)
+            OPENSSL_free(name_dup);
+        if (sname_dup != NULL)
+            OPENSSL_free(sname_dup);
+        if (idx == -1)
+            OPENSSL_free(ptmp);
+        return 0;
+    }
 
-	/* OPENSSL_free existing name if dynamic */
-	if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
-		OPENSSL_free(ptmp->name);
-		OPENSSL_free(ptmp->sname);
-	}
-	/* dup supplied name */
-	ptmp->name = name_dup;
-	ptmp->sname = sname_dup;
-	/* Keep the dynamic flag of existing entry */
-	ptmp->flags &= X509_PURPOSE_DYNAMIC;
-	/* Set all other flags */
-	ptmp->flags |= flags;
+    /* OPENSSL_free existing name if dynamic */
+    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
+        OPENSSL_free(ptmp->name);
+        OPENSSL_free(ptmp->sname);
+    }
+    /* dup supplied name */
+    ptmp->name = name_dup;
+    ptmp->sname = sname_dup;
+    /* Keep the dynamic flag of existing entry */
+    ptmp->flags &= X509_PURPOSE_DYNAMIC;
+    /* Set all other flags */
+    ptmp->flags |= flags;
 
-	ptmp->purpose = id;
-	ptmp->trust = trust;
-	ptmp->check_purpose = ck;
-	ptmp->usr_data = arg;
+    ptmp->purpose = id;
+    ptmp->trust = trust;
+    ptmp->check_purpose = ck;
+    ptmp->usr_data = arg;
 
-	/* If its a new entry manage the dynamic table */
-	if(idx == -1) {
-		if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			xptable_free(ptmp);
-			return 0;
-		}
-		if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
-			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-			xptable_free(ptmp);
-			return 0;
-		}
-	}
-	return 1;
+    /* If its a new entry manage the dynamic table */
+    if (idx == -1) {
+        if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            xptable_free(ptmp);
+            return 0;
+        }
+        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
+            OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+            xptable_free(ptmp);
+            return 0;
+        }
+    }
+    return 1;
 }
 
 static void xptable_free(X509_PURPOSE *p)
-	{
-	if(!p) return;
-	if (p->flags & X509_PURPOSE_DYNAMIC) 
-		{
-		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
-			OPENSSL_free(p->name);
-			OPENSSL_free(p->sname);
-		}
-		OPENSSL_free(p);
-		}
-	}
+{
+    if (!p)
+        return;
+    if (p->flags & X509_PURPOSE_DYNAMIC) {
+        if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+            OPENSSL_free(p->name);
+            OPENSSL_free(p->sname);
+        }
+        OPENSSL_free(p);
+    }
+}
 
 void X509_PURPOSE_cleanup(void)
 {
-	unsigned int i;
-	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
-	for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
-	xptable = NULL;
+    unsigned int i;
+    sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+    for (i = 0; i < X509_PURPOSE_COUNT; i++)
+        xptable_free(xstandard + i);
+    xptable = NULL;
 }
 
 int X509_PURPOSE_get_id(X509_PURPOSE *xp)
 {
-	return xp->purpose;
+    return xp->purpose;
 }
 
 char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
 {
-	return xp->name;
+    return xp->name;
 }
 
 char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
 {
-	return xp->sname;
+    return xp->sname;
 }
 
 int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
 {
-	return xp->trust;
+    return xp->trust;
 }
 
 static int nid_cmp(const void *void_a, const void *void_b)
-	{
-	const int *a = void_a, *b = void_b;
+{
+    const int *a = void_a, *b = void_b;
 
-	return *a - *b;
-	}
+    return *a - *b;
+}
 
 int X509_supported_extension(X509_EXTENSION *ex)
-	{
-	/* This table is a list of the NIDs of supported extensions:
-	 * that is those which are used by the verify process. If
-	 * an extension is critical and doesn't appear in this list
-	 * then the verify process will normally reject the certificate.
-	 * The list must be kept in numerical order because it will be
-	 * searched using bsearch.
-	 */
+{
+    /*
+     * This table is a list of the NIDs of supported extensions: that is
+     * those which are used by the verify process. If an extension is
+     * critical and doesn't appear in this list then the verify process will
+     * normally reject the certificate. The list must be kept in numerical
+     * order because it will be searched using bsearch.
+     */
 
-	static const int supported_nids[] = {
-		NID_netscape_cert_type, /* 71 */
-        	NID_key_usage,		/* 83 */
-		NID_subject_alt_name,	/* 85 */
-		NID_basic_constraints,	/* 87 */
-		NID_certificate_policies, /* 89 */
-        	NID_ext_key_usage,	/* 126 */
-		NID_policy_constraints,	/* 401 */
-		NID_proxyCertInfo,	/* 663 */
-		NID_name_constraints,	/* 666 */
-		NID_policy_mappings,	/* 747 */
-		NID_inhibit_any_policy	/* 748 */
-	};
+    static const int supported_nids[] = {
+        NID_netscape_cert_type, /* 71 */
+        NID_key_usage,          /* 83 */
+        NID_subject_alt_name,   /* 85 */
+        NID_basic_constraints,  /* 87 */
+        NID_certificate_policies, /* 89 */
+        NID_ext_key_usage,      /* 126 */
+        NID_policy_constraints, /* 401 */
+        NID_proxyCertInfo,      /* 663 */
+        NID_name_constraints,   /* 666 */
+        NID_policy_mappings,    /* 747 */
+        NID_inhibit_any_policy  /* 748 */
+    };
 
-	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+    int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
 
-	if (ex_nid == NID_undef) 
-		return 0;
+    if (ex_nid == NID_undef)
+        return 0;
 
-	if (bsearch(&ex_nid, supported_nids, sizeof(supported_nids)/sizeof(int), sizeof(int), nid_cmp) != NULL)
-		return 1;
-	return 0;
-	}
+    if (bsearch
+        (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int),
+         sizeof(int), nid_cmp) != NULL)
+        return 1;
+    return 0;
+}
 
 static void setup_dp(X509 *x, DIST_POINT *dp)
-	{
-	X509_NAME *iname = NULL;
-	size_t i;
-	if (dp->reasons)
-		{
-		if (dp->reasons->length > 0)
-			dp->dp_reasons = dp->reasons->data[0];
-		if (dp->reasons->length > 1)
-			dp->dp_reasons |= (dp->reasons->data[1] << 8);
-		dp->dp_reasons &= CRLDP_ALL_REASONS;
-		}
-	else
-		dp->dp_reasons = CRLDP_ALL_REASONS;
-	if (!dp->distpoint || (dp->distpoint->type != 1))
-		return;
-	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
-		{
-		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
-		if (gen->type == GEN_DIRNAME)
-			{
-			iname = gen->d.directoryName;
-			break;
-			}
-		}
-	if (!iname)
-		iname = X509_get_issuer_name(x);
+{
+    X509_NAME *iname = NULL;
+    size_t i;
+    if (dp->reasons) {
+        if (dp->reasons->length > 0)
+            dp->dp_reasons = dp->reasons->data[0];
+        if (dp->reasons->length > 1)
+            dp->dp_reasons |= (dp->reasons->data[1] << 8);
+        dp->dp_reasons &= CRLDP_ALL_REASONS;
+    } else
+        dp->dp_reasons = CRLDP_ALL_REASONS;
+    if (!dp->distpoint || (dp->distpoint->type != 1))
+        return;
+    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+        if (gen->type == GEN_DIRNAME) {
+            iname = gen->d.directoryName;
+            break;
+        }
+    }
+    if (!iname)
+        iname = X509_get_issuer_name(x);
 
-	DIST_POINT_set_dpname(dp->distpoint, iname);
+    DIST_POINT_set_dpname(dp->distpoint, iname);
 
-	}
+}
 
 static void setup_crldp(X509 *x)
-	{
-	size_t i;
-	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
-	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
-		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
-	}
+{
+    size_t i;
+    x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+        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.
- *
+/*
+ * 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. */
+ * 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;
-	PROXY_CERT_INFO_EXTENSION *pci;
-	ASN1_BIT_STRING *usage;
-	ASN1_BIT_STRING *ns;
-	EXTENDED_KEY_USAGE *extusage;
-	X509_EXTENSION *ex;
-	size_t i;
-	int j;
+    BASIC_CONSTRAINTS *bs;
+    PROXY_CERT_INFO_EXTENSION *pci;
+    ASN1_BIT_STRING *usage;
+    ASN1_BIT_STRING *ns;
+    EXTENDED_KEY_USAGE *extusage;
+    X509_EXTENSION *ex;
+    size_t i;
+    int j;
 
-	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
+    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;
-		}
+    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;
-	/* Handle basic constraints */
-	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
-		if(bs->ca) x->ex_flags |= EXFLAG_CA;
-		if(bs->pathlen) {
-			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
-						|| !bs->ca) {
-				x->ex_flags |= EXFLAG_INVALID;
-				x->ex_pathlen = 0;
-			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
-		} else x->ex_pathlen = -1;
-		BASIC_CONSTRAINTS_free(bs);
-		x->ex_flags |= EXFLAG_BCONS;
-	}
-	/* Handle proxy certificates */
-	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
-		if (x->ex_flags & EXFLAG_CA
-		    || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
-		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
-			x->ex_flags |= EXFLAG_INVALID;
-		}
-		if (pci->pcPathLengthConstraint) {
-			x->ex_pcpathlen =
-				ASN1_INTEGER_get(pci->pcPathLengthConstraint);
-		} else x->ex_pcpathlen = -1;
-		PROXY_CERT_INFO_EXTENSION_free(pci);
-		x->ex_flags |= EXFLAG_PROXY;
-	}
-	/* Handle key usage */
-	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
-		if(usage->length > 0) {
-			x->ex_kusage = usage->data[0];
-			if(usage->length > 1) 
-				x->ex_kusage |= usage->data[1] << 8;
-		} else x->ex_kusage = 0;
-		x->ex_flags |= EXFLAG_KUSAGE;
-		ASN1_BIT_STRING_free(usage);
-	}
-	x->ex_xkusage = 0;
-	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
-		x->ex_flags |= EXFLAG_XKUSAGE;
-		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
-			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
-				case NID_server_auth:
-				x->ex_xkusage |= XKU_SSL_SERVER;
-				break;
+    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+    /* V1 should mean no extensions ... */
+    if (!X509_get_version(x))
+        x->ex_flags |= EXFLAG_V1;
+    /* Handle basic constraints */
+    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
+        if (bs->ca)
+            x->ex_flags |= EXFLAG_CA;
+        if (bs->pathlen) {
+            if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
+                || !bs->ca) {
+                x->ex_flags |= EXFLAG_INVALID;
+                x->ex_pathlen = 0;
+            } else
+                x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+        } else
+            x->ex_pathlen = -1;
+        BASIC_CONSTRAINTS_free(bs);
+        x->ex_flags |= EXFLAG_BCONS;
+    }
+    /* Handle proxy certificates */
+    if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+        if (x->ex_flags & EXFLAG_CA
+            || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+            || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
+            x->ex_flags |= EXFLAG_INVALID;
+        }
+        if (pci->pcPathLengthConstraint) {
+            x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
+        } else
+            x->ex_pcpathlen = -1;
+        PROXY_CERT_INFO_EXTENSION_free(pci);
+        x->ex_flags |= EXFLAG_PROXY;
+    }
+    /* Handle key usage */
+    if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
+        if (usage->length > 0) {
+            x->ex_kusage = usage->data[0];
+            if (usage->length > 1)
+                x->ex_kusage |= usage->data[1] << 8;
+        } else
+            x->ex_kusage = 0;
+        x->ex_flags |= EXFLAG_KUSAGE;
+        ASN1_BIT_STRING_free(usage);
+    }
+    x->ex_xkusage = 0;
+    if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
+        x->ex_flags |= EXFLAG_XKUSAGE;
+        for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
+            switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
+            case NID_server_auth:
+                x->ex_xkusage |= XKU_SSL_SERVER;
+                break;
 
-				case NID_client_auth:
-				x->ex_xkusage |= XKU_SSL_CLIENT;
-				break;
+            case NID_client_auth:
+                x->ex_xkusage |= XKU_SSL_CLIENT;
+                break;
 
-				case NID_email_protect:
-				x->ex_xkusage |= XKU_SMIME;
-				break;
+            case NID_email_protect:
+                x->ex_xkusage |= XKU_SMIME;
+                break;
 
-				case NID_code_sign:
-				x->ex_xkusage |= XKU_CODE_SIGN;
-				break;
+            case NID_code_sign:
+                x->ex_xkusage |= XKU_CODE_SIGN;
+                break;
 
-				case NID_ms_sgc:
-				case NID_ns_sgc:
-				x->ex_xkusage |= XKU_SGC;
-				break;
+            case NID_ms_sgc:
+            case NID_ns_sgc:
+                x->ex_xkusage |= XKU_SGC;
+                break;
 
-				case NID_OCSP_sign:
-				x->ex_xkusage |= XKU_OCSP_SIGN;
-				break;
+            case NID_OCSP_sign:
+                x->ex_xkusage |= XKU_OCSP_SIGN;
+                break;
 
-				case NID_time_stamp:
-				x->ex_xkusage |= XKU_TIMESTAMP;
-				break;
+            case NID_time_stamp:
+                x->ex_xkusage |= XKU_TIMESTAMP;
+                break;
 
-				case NID_dvcs:
-				x->ex_xkusage |= XKU_DVCS;
-				break;
+            case NID_dvcs:
+                x->ex_xkusage |= XKU_DVCS;
+                break;
 
-				case NID_anyExtendedKeyUsage:
-				x->ex_xkusage |= XKU_ANYEKU;
-				break;
-			}
-		}
-		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
-	}
+            case NID_anyExtendedKeyUsage:
+                x->ex_xkusage |= XKU_ANYEKU;
+                break;
+            }
+        }
+        sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
+    }
 
-	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
-		if(ns->length > 0) x->ex_nscert = ns->data[0];
-		else x->ex_nscert = 0;
-		x->ex_flags |= EXFLAG_NSCERT;
-		ASN1_BIT_STRING_free(ns);
-	}
-	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
-	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
-	/* Does subject name match issuer ? */
-	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
-			{
-			x->ex_flags |= EXFLAG_SI;
-			/* If SKID matches AKID also indicate self signed */
-			if (X509_check_akid(x, x->akid) == X509_V_OK &&
-				!ku_reject(x, KU_KEY_CERT_SIGN))
-				x->ex_flags |= EXFLAG_SS;
-			}
-	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
-	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
-	if (!x->nc && (j != -1))
-		x->ex_flags |= EXFLAG_INVALID;
-	setup_crldp(x);
+    if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
+        if (ns->length > 0)
+            x->ex_nscert = ns->data[0];
+        else
+            x->ex_nscert = 0;
+        x->ex_flags |= EXFLAG_NSCERT;
+        ASN1_BIT_STRING_free(ns);
+    }
+    x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
+    x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+    /* Does subject name match issuer ? */
+    if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
+        x->ex_flags |= EXFLAG_SI;
+        /* If SKID matches AKID also indicate self signed */
+        if (X509_check_akid(x, x->akid) == X509_V_OK &&
+            !ku_reject(x, KU_KEY_CERT_SIGN))
+            x->ex_flags |= EXFLAG_SS;
+    }
+    x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
+    if (!x->nc && (j != -1))
+        x->ex_flags |= EXFLAG_INVALID;
+    setup_crldp(x);
 
-	for (j = 0; j < X509_get_ext_count(x); j++)
-		{
-		ex = X509_get_ext(x, j);
-		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
-					== NID_freshest_crl)
-			x->ex_flags |= EXFLAG_FRESHEST;
-		if (!X509_EXTENSION_get_critical(ex))
-			continue;
-		if (!X509_supported_extension(ex))
-			{
-			x->ex_flags |= EXFLAG_CRITICAL;
-			break;
-			}
-		}
-	x->ex_flags |= EXFLAG_SET;
+    for (j = 0; j < X509_get_ext_count(x); j++) {
+        ex = X509_get_ext(x, j);
+        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+            == NID_freshest_crl)
+            x->ex_flags |= EXFLAG_FRESHEST;
+        if (!X509_EXTENSION_get_critical(ex))
+            continue;
+        if (!X509_supported_extension(ex)) {
+            x->ex_flags |= EXFLAG_CRITICAL;
+            break;
+        }
+    }
+    x->ex_flags |= EXFLAG_SET;
 
-	CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
+    CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
 }
 
-/* CA checks common to all purposes
- * return codes:
- * 0 not a CA
- * 1 is a CA
- * 2 basicConstraints absent so "maybe" a CA
- * 3 basicConstraints absent but self signed V1.
- * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
+/*
+ * CA checks common to all purposes return codes: 0 not a CA 1 is a CA 2
+ * basicConstraints absent so "maybe" a CA 3 basicConstraints absent but self
+ * signed V1. 4 basicConstraints absent but keyUsage present and keyCertSign
+ * asserted.
  */
 
 static int check_ca(const X509 *x)
 {
-	/* keyUsage if present should allow cert signing */
-	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
-	if(x->ex_flags & EXFLAG_BCONS) {
-		if(x->ex_flags & EXFLAG_CA) return 1;
-		/* If basicConstraints says not a CA then say so */
-		else return 0;
-	} else {
-		/* we support V1 roots for...  uh, I don't really know why. */
-		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
-		/* If key usage present it must have certSign so tolerate it */
-		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
-		/* Older certificates could have Netscape-specific CA types */
-		else if (x->ex_flags & EXFLAG_NSCERT
-			 && x->ex_nscert & NS_ANY_CA) return 5;
-		/* can this still be regarded a CA certificate?  I doubt it */
-		return 0;
-	}
+    /* keyUsage if present should allow cert signing */
+    if (ku_reject(x, KU_KEY_CERT_SIGN))
+        return 0;
+    if (x->ex_flags & EXFLAG_BCONS) {
+        if (x->ex_flags & EXFLAG_CA)
+            return 1;
+        /* If basicConstraints says not a CA then say so */
+        else
+            return 0;
+    } else {
+        /* we support V1 roots for...  uh, I don't really know why. */
+        if ((x->ex_flags & V1_ROOT) == V1_ROOT)
+            return 3;
+        /*
+         * If key usage present it must have certSign so tolerate it
+         */
+        else if (x->ex_flags & EXFLAG_KUSAGE)
+            return 4;
+        /* Older certificates could have Netscape-specific CA types */
+        else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA)
+            return 5;
+        /* can this still be regarded a CA certificate?  I doubt it */
+        return 0;
+    }
 }
 
 int X509_check_ca(X509 *x)
 {
-	if(!(x->ex_flags & EXFLAG_SET)) {
-		x509v3_cache_extensions(x);
-	}
+    if (!(x->ex_flags & EXFLAG_SET)) {
+        x509v3_cache_extensions(x);
+    }
 
-	return check_ca(x);
+    return check_ca(x);
 }
 
 /* Check SSL CA: common checks for SSL client and server */
 static int check_ssl_ca(const X509 *x)
 {
-	int ca_ret;
-	ca_ret = check_ca(x);
-	if(!ca_ret) return 0;
-	/* check nsCertType if present */
-	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
-	else return 0;
+    int ca_ret;
+    ca_ret = check_ca(x);
+    if (!ca_ret)
+        return 0;
+    /* check nsCertType if present */
+    if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
+        return ca_ret;
+    else
+        return 0;
 }
 
-
-static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
 {
-	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
-	if(ca) return check_ssl_ca(x);
-	/* We need to do digital signatures or key agreement */
-	if(ku_reject(x,KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) return 0;
-	/* nsCertType if present should allow SSL client use */	
-	if(ns_reject(x, NS_SSL_CLIENT)) return 0;
-	return 1;
+    if (xku_reject(x, XKU_SSL_CLIENT))
+        return 0;
+    if (ca)
+        return check_ssl_ca(x);
+    /* We need to do digital signatures or key agreement */
+    if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))
+        return 0;
+    /* nsCertType if present should allow SSL client use */
+    if (ns_reject(x, NS_SSL_CLIENT))
+        return 0;
+    return 1;
 }
-/* Key usage needed for TLS/SSL server: digital signature, encipherment or
+
+/*
+ * Key usage needed for TLS/SSL server: digital signature, encipherment or
  * key agreement. The ssl code can check this more thoroughly for individual
  * key types.
  */
 #define KU_TLS \
-	KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
+        KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
 
-static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
 {
-	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
-	if(ca) return check_ssl_ca(x);
+    if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC))
+        return 0;
+    if (ca)
+        return check_ssl_ca(x);
 
-	if(ns_reject(x, NS_SSL_SERVER)) return 0;
-	if(ku_reject(x, KU_TLS)) return 0;
-	
-	return 1;
+    if (ns_reject(x, NS_SSL_SERVER))
+        return 0;
+    if (ku_reject(x, KU_TLS))
+        return 0;
+
+    return 1;
 
 }
 
-static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca)
 {
-	int ret;
-	ret = check_purpose_ssl_server(xp, x, ca);
-	if(!ret || ca) return ret;
-	/* We need to encipher or Netscape complains */
-	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
-	return ret;
+    int ret;
+    ret = check_purpose_ssl_server(xp, x, ca);
+    if (!ret || ca)
+        return ret;
+    /* We need to encipher or Netscape complains */
+    if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+        return 0;
+    return ret;
 }
 
 /* common S/MIME checks */
 static int purpose_smime(const X509 *x, int ca)
 {
-	if(xku_reject(x,XKU_SMIME)) return 0;
-	if(ca) {
-		int ca_ret;
-		ca_ret = check_ca(x);
-		if(!ca_ret) return 0;
-		/* check nsCertType if present */
-		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
-		else return 0;
-	}
-	if(x->ex_flags & EXFLAG_NSCERT) {
-		if(x->ex_nscert & NS_SMIME) return 1;
-		/* Workaround for some buggy certificates */
-		if(x->ex_nscert & NS_SSL_CLIENT) return 2;
-		return 0;
-	}
-	return 1;
+    if (xku_reject(x, XKU_SMIME))
+        return 0;
+    if (ca) {
+        int ca_ret;
+        ca_ret = check_ca(x);
+        if (!ca_ret)
+            return 0;
+        /* check nsCertType if present */
+        if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
+            return ca_ret;
+        else
+            return 0;
+    }
+    if (x->ex_flags & EXFLAG_NSCERT) {
+        if (x->ex_nscert & NS_SMIME)
+            return 1;
+        /* Workaround for some buggy certificates */
+        if (x->ex_nscert & NS_SSL_CLIENT)
+            return 2;
+        return 0;
+    }
+    return 1;
 }
 
-static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
 {
-	int ret;
-	ret = purpose_smime(x, ca);
-	if(!ret || ca) return ret;
-	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
-	return ret;
+    int ret;
+    ret = purpose_smime(x, ca);
+    if (!ret || ca)
+        return ret;
+    if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))
+        return 0;
+    return ret;
 }
 
-static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca)
 {
-	int ret;
-	ret = purpose_smime(x, ca);
-	if(!ret || ca) return ret;
-	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
-	return ret;
+    int ret;
+    ret = purpose_smime(x, ca);
+    if (!ret || ca)
+        return ret;
+    if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+        return 0;
+    return ret;
 }
 
-static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+                                  int ca)
 {
-	if(ca) {
-		int ca_ret;
-		if((ca_ret = check_ca(x)) != 2) return ca_ret;
-		else return 0;
-	}
-	if(ku_reject(x, KU_CRL_SIGN)) return 0;
-	return 1;
+    if (ca) {
+        int ca_ret;
+        if ((ca_ret = check_ca(x)) != 2)
+            return ca_ret;
+        else
+            return 0;
+    }
+    if (ku_reject(x, KU_CRL_SIGN))
+        return 0;
+    return 1;
 }
 
-/* OCSP helper: this is *not* a full OCSP check. It just checks that
- * each CA is valid. Additional checks must be made on the chain.
+/*
+ * OCSP helper: this is *not* a full OCSP check. It just checks that each CA
+ * is valid. Additional checks must be made on the chain.
  */
 
 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
 {
-	/* Must be a valid CA.  Should we really support the "I don't know"
-	   value (2)? */
-	if(ca) return check_ca(x);
-	/* leaf certificate is checked in OCSP_verify() */
-	return 1;
+    /*
+     * Must be a valid CA.  Should we really support the "I don't know" value
+     * (2)?
+     */
+    if (ca)
+        return check_ca(x);
+    /* leaf certificate is checked in OCSP_verify() */
+    return 1;
 }
 
 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
-					int ca)
+                                        int ca)
 {
-	int i_ext;
+    int i_ext;
 
-	/* If ca is true we must return if this is a valid CA certificate. */
-	if (ca) return check_ca(x);
+    /* If ca is true we must return if this is a valid CA certificate. */
+    if (ca)
+        return check_ca(x);
 
-	/* 
-	 * Check the optional key usage field:
-	 * if Key Usage is present, it must be one of digitalSignature 
-	 * and/or nonRepudiation (other values are not consistent and shall
-	 * be rejected).
-	 */
-	if ((x->ex_flags & EXFLAG_KUSAGE)
-	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
-		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
-		return 0;
+    /*
+     * Check the optional key usage field:
+     * if Key Usage is present, it must be one of digitalSignature
+     * and/or nonRepudiation (other values are not consistent and shall
+     * be rejected).
+     */
+    if ((x->ex_flags & EXFLAG_KUSAGE)
+        && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
+            !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
+        return 0;
 
-	/* Only time stamp key usage is permitted and it's required. */
-	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
-		return 0;
+    /* Only time stamp key usage is permitted and it's required. */
+    if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
+        return 0;
 
-	/* Extended Key Usage MUST be critical */
-	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
-	if (i_ext >= 0)
-		{
-		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
-		if (!X509_EXTENSION_get_critical(ext))
-			return 0;
-		}
+    /* Extended Key Usage MUST be critical */
+    i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1);
+    if (i_ext >= 0) {
+        X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
+        if (!X509_EXTENSION_get_critical(ext))
+            return 0;
+    }
 
-	return 1;
+    return 1;
 }
 
 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
 {
-	return 1;
+    return 1;
 }
 
-/* Various checks to see if one certificate issued the second.
- * This can be used to prune a set of possible issuer certificates
- * which have been looked up using some simple method such as by
- * subject name.
- * These are:
- * 1. Check issuer_name(subject) == subject_name(issuer)
- * 2. If akid(subject) exists check it matches issuer
- * 3. If key_usage(issuer) exists check it supports certificate signing
- * returns 0 for OK, positive for reason for mismatch, reasons match
- * codes for X509_verify_cert()
+/*
+ * Various checks to see if one certificate issued the second. This can be
+ * used to prune a set of possible issuer certificates which have been looked
+ * up using some simple method such as by subject name. These are: 1. Check
+ * issuer_name(subject) == subject_name(issuer) 2. If akid(subject) exists
+ * check it matches issuer 3. If key_usage(issuer) exists check it supports
+ * certificate signing returns 0 for OK, positive for reason for mismatch,
+ * reasons match codes for X509_verify_cert()
  */
 
 int X509_check_issued(X509 *issuer, X509 *subject)
 {
-	if(X509_NAME_cmp(X509_get_subject_name(issuer),
-			X509_get_issuer_name(subject)))
-				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
-	x509v3_cache_extensions(issuer);
-	x509v3_cache_extensions(subject);
+    if (X509_NAME_cmp(X509_get_subject_name(issuer),
+                      X509_get_issuer_name(subject)))
+        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+    x509v3_cache_extensions(issuer);
+    x509v3_cache_extensions(subject);
 
-	if(subject->akid)
-		{
-		int ret = X509_check_akid(issuer, subject->akid);
-		if (ret != X509_V_OK)
-			return ret;
-		}
+    if (subject->akid) {
+        int ret = X509_check_akid(issuer, subject->akid);
+        if (ret != X509_V_OK)
+            return ret;
+    }
 
-	if(subject->ex_flags & EXFLAG_PROXY)
-		{
-		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
-			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
-		}
-	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
-		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
-	return X509_V_OK;
+    if (subject->ex_flags & EXFLAG_PROXY) {
+        if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
+            return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+    } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
+        return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+    return X509_V_OK;
 }
 
 int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
-	{
+{
 
-	if(!akid)
-		return X509_V_OK;
+    if (!akid)
+        return X509_V_OK;
 
-	/* Check key ids (if present) */
-	if(akid->keyid && issuer->skid &&
-		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
-				return X509_V_ERR_AKID_SKID_MISMATCH;
-	/* Check serial number */
-	if(akid->serial &&
-		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
-				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
-	/* Check issuer name */
-	if(akid->issuer)
-		{
-		/* Ugh, for some peculiar reason AKID includes
-		 * SEQUENCE OF GeneralName. So look for a DirName.
-		 * There may be more than one but we only take any
-		 * notice of the first.
-		 */
-		GENERAL_NAMES *gens;
-		GENERAL_NAME *gen;
-		X509_NAME *nm = NULL;
-		size_t i;
-		gens = akid->issuer;
-		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
-			{
-			gen = sk_GENERAL_NAME_value(gens, i);
-			if(gen->type == GEN_DIRNAME)
-				{
-				nm = gen->d.dirn;
-				break;
-				}
-			}
-		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
-			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
-		}
-	return X509_V_OK;
-	}
-
+    /* Check key ids (if present) */
+    if (akid->keyid && issuer->skid &&
+        ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid))
+        return X509_V_ERR_AKID_SKID_MISMATCH;
+    /* Check serial number */
+    if (akid->serial &&
+        ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
+        return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+    /* Check issuer name */
+    if (akid->issuer) {
+        /*
+         * Ugh, for some peculiar reason AKID includes SEQUENCE OF
+         * GeneralName. So look for a DirName. There may be more than one but
+         * we only take any notice of the first.
+         */
+        GENERAL_NAMES *gens;
+        GENERAL_NAME *gen;
+        X509_NAME *nm = NULL;
+        size_t i;
+        gens = akid->issuer;
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            gen = sk_GENERAL_NAME_value(gens, i);
+            if (gen->type == GEN_DIRNAME) {
+                nm = gen->d.dirn;
+                break;
+            }
+        }
+        if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+            return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+    }
+    return X509_V_OK;
+}
diff --git a/src/crypto/x509v3/v3_skey.c b/src/crypto/x509v3/v3_skey.c
index e396f05..65f8287 100644
--- a/src/crypto/x509v3/v3_skey.c
+++ b/src/crypto/x509v3/v3_skey.c
@@ -1,6 +1,7 @@
 /* v3_skey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -54,7 +55,6 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
 
-
 #include <stdio.h>
 #include <string.h>
 
@@ -63,86 +63,90 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_skey_id = {
+    NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+    (X509V3_EXT_S2I)s2i_skey_id,
+    0, 0, 0, 0,
+    NULL
+};
 
-static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
-const X509V3_EXT_METHOD v3_skey_id = { 
-NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
-0,0,0,0,
-(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
-(X509V3_EXT_S2I)s2i_skey_id,
-0,0,0,0,
-NULL};
-
-char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
-	     ASN1_OCTET_STRING *oct)
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct)
 {
-	return hex_to_string(oct->data, oct->length);
+    return hex_to_string(oct->data, oct->length);
 }
 
 ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, char *str)
+                                         X509V3_CTX *ctx, char *str)
 {
-	ASN1_OCTET_STRING *oct;
-	long length;
+    ASN1_OCTET_STRING *oct;
+    long length;
 
-	if(!(oct = M_ASN1_OCTET_STRING_new())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
+    if (!(oct = M_ASN1_OCTET_STRING_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
 
-	if(!(oct->data = string_to_hex(str, &length))) {
-		M_ASN1_OCTET_STRING_free(oct);
-		return NULL;
-	}
+    if (!(oct->data = string_to_hex(str, &length))) {
+        M_ASN1_OCTET_STRING_free(oct);
+        return NULL;
+    }
 
-	oct->length = length;
+    oct->length = length;
 
-	return oct;
+    return oct;
 
 }
 
 static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, char *str)
+                                      X509V3_CTX *ctx, char *str)
 {
-	ASN1_OCTET_STRING *oct;
-	ASN1_BIT_STRING *pk;
-	unsigned char pkey_dig[EVP_MAX_MD_SIZE];
-	unsigned int diglen;
+    ASN1_OCTET_STRING *oct;
+    ASN1_BIT_STRING *pk;
+    unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+    unsigned int diglen;
 
-	if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
+    if (strcmp(str, "hash"))
+        return s2i_ASN1_OCTET_STRING(method, ctx, str);
 
-	if(!(oct = M_ASN1_OCTET_STRING_new())) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
+    if (!(oct = M_ASN1_OCTET_STRING_new())) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
 
-	if(ctx && (ctx->flags == CTX_TEST)) return oct;
+    if (ctx && (ctx->flags == CTX_TEST))
+        return oct;
 
-	if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
-		goto err;
-	}
+    if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
+        goto err;
+    }
 
-	if(ctx->subject_req) 
-		pk = ctx->subject_req->req_info->pubkey->public_key;
-	else pk = ctx->subject_cert->cert_info->key->public_key;
+    if (ctx->subject_req)
+        pk = ctx->subject_req->req_info->pubkey->public_key;
+    else
+        pk = ctx->subject_cert->cert_info->key->public_key;
 
-	if(!pk) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
-		goto err;
-	}
+    if (!pk) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
+        goto err;
+    }
 
-	if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
-		goto err;
+    if (!EVP_Digest
+        (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
+        goto err;
 
-	if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
+    if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-	return oct;
-	
-	err:
-	M_ASN1_OCTET_STRING_free(oct);
-	return NULL;
+    return oct;
+
+ err:
+    M_ASN1_OCTET_STRING_free(oct);
+    return NULL;
 }
diff --git a/src/crypto/x509v3/v3_sxnet.c b/src/crypto/x509v3/v3_sxnet.c
index 4dd5bfc..51c5a67 100644
--- a/src/crypto/x509v3/v3_sxnet.c
+++ b/src/crypto/x509v3/v3_sxnet.c
@@ -1,6 +1,7 @@
 /* v3_sxnet.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
  */
 /* ====================================================================
  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -67,200 +68,207 @@
 #include <openssl/obj.h>
 #include <openssl/x509v3.h>
 
-
 /* Support for Thawte strong extranet extension */
 
 #define SXNET_TEST
 
-static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+                     int indent);
 #ifdef SXNET_TEST
-static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-						STACK_OF(CONF_VALUE) *nval);
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                        STACK_OF(CONF_VALUE) *nval);
 #endif
 const X509V3_EXT_METHOD v3_sxnet = {
-NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
-0,0,0,0,
-0,0,
-0, 
+    NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
+    0, 0, 0, 0,
+    0, 0,
+    0,
 #ifdef SXNET_TEST
-(X509V3_EXT_V2I)sxnet_v2i,
+    (X509V3_EXT_V2I)sxnet_v2i,
 #else
-0,
+    0,
 #endif
-(X509V3_EXT_I2R)sxnet_i2r,
-0,
-NULL
+    (X509V3_EXT_I2R)sxnet_i2r,
+    0,
+    NULL
 };
 
 ASN1_SEQUENCE(SXNETID) = {
-	ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
-	ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
+        ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
+        ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
 } ASN1_SEQUENCE_END(SXNETID)
 
 IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
 
 ASN1_SEQUENCE(SXNET) = {
-	ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
-	ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
+        ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
+        ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
 } ASN1_SEQUENCE_END(SXNET)
 
 IMPLEMENT_ASN1_FUNCTIONS(SXNET)
 
 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
-	     int indent)
+                     int indent)
 {
-	long v;
-	char *tmp;
-	SXNETID *id;
-	size_t i;
-	v = ASN1_INTEGER_get(sx->version);
-	BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
-	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
-		id = sk_SXNETID_value(sx->ids, i);
-		tmp = i2s_ASN1_INTEGER(NULL, id->zone);
-		BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
-		OPENSSL_free(tmp);
-		M_ASN1_OCTET_STRING_print(out, id->user);
-	}
-	return 1;
+    long v;
+    char *tmp;
+    SXNETID *id;
+    size_t i;
+    v = ASN1_INTEGER_get(sx->version);
+    BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
+    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+        id = sk_SXNETID_value(sx->ids, i);
+        tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+        BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
+        OPENSSL_free(tmp);
+        M_ASN1_OCTET_STRING_print(out, id->user);
+    }
+    return 1;
 }
 
 #ifdef SXNET_TEST
 
-/* NBB: this is used for testing only. It should *not* be used for anything
+/*
+ * NBB: this is used for testing only. It should *not* be used for anything
  * else because it will just take static IDs from the configuration file and
  * they should really be separate values for each user.
  */
 
-
-static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-	     STACK_OF(CONF_VALUE) *nval)
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                        STACK_OF(CONF_VALUE) *nval)
 {
-	CONF_VALUE *cnf;
-	SXNET *sx = NULL;
-	size_t i;
-	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
-								 return NULL;
-	}
-	return sx;
+    CONF_VALUE *cnf;
+    SXNET *sx = NULL;
+    size_t i;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+            return NULL;
+    }
+    return sx;
 }
-		
-	
+
 #endif
 
 /* Strong Extranet utility functions */
 
 /* Add an id given the zone as an ASCII number */
 
-int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
-	     int userlen)
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
 {
-	ASN1_INTEGER *izone = NULL;
-	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
-		return 0;
-	}
-	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+    ASN1_INTEGER *izone = NULL;
+    if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
+        return 0;
+    }
+    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
 }
 
 /* Add an id given the zone as an unsigned long */
 
 int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
-	     int userlen)
+                       int userlen)
 {
-	ASN1_INTEGER *izone = NULL;
-	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		M_ASN1_INTEGER_free(izone);
-		return 0;
-	}
-	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
-	
+    ASN1_INTEGER *izone = NULL;
+    if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        M_ASN1_INTEGER_free(izone);
+        return 0;
+    }
+    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+
 }
 
-/* Add an id given the zone as an ASN1_INTEGER.
- * Note this version uses the passed integer and doesn't make a copy so don't
- * free it up afterwards.
+/*
+ * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
+ * passed integer and doesn't make a copy so don't free it up afterwards.
  */
 
 int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
-	     int userlen)
+                         int userlen)
 {
-	SXNET *sx = NULL;
-	SXNETID *id = NULL;
-	if(!psx || !zone || !user) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
-		return 0;
-	}
-	if(userlen == -1) userlen = strlen(user);
-	if(userlen > 64) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
-		return 0;
-	}
-	if(!*psx) {
-		if(!(sx = SXNET_new())) goto err;
-		if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
-		*psx = sx;
-	} else sx = *psx;
-	if(SXNET_get_id_INTEGER(sx, zone)) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
-		return 0;
-	}
+    SXNET *sx = NULL;
+    SXNETID *id = NULL;
+    if (!psx || !zone || !user) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+        return 0;
+    }
+    if (userlen == -1)
+        userlen = strlen(user);
+    if (userlen > 64) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
+        return 0;
+    }
+    if (!*psx) {
+        if (!(sx = SXNET_new()))
+            goto err;
+        if (!ASN1_INTEGER_set(sx->version, 0))
+            goto err;
+        *psx = sx;
+    } else
+        sx = *psx;
+    if (SXNET_get_id_INTEGER(sx, zone)) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
+        return 0;
+    }
 
-	if(!(id = SXNETID_new())) goto err;
-	if(userlen == -1) userlen = strlen(user);
-		
-	if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
-	if(!sk_SXNETID_push(sx->ids, id)) goto err;
-	id->zone = zone;
-	return 1;
-	
-	err:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	SXNETID_free(id);
-	SXNET_free(sx);
-	*psx = NULL;
-	return 0;
+    if (!(id = SXNETID_new()))
+        goto err;
+    if (userlen == -1)
+        userlen = strlen(user);
+
+    if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
+        goto err;
+    if (!sk_SXNETID_push(sx->ids, id))
+        goto err;
+    id->zone = zone;
+    return 1;
+
+ err:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    SXNETID_free(id);
+    SXNET_free(sx);
+    *psx = NULL;
+    return 0;
 }
 
 ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
 {
-	ASN1_INTEGER *izone = NULL;
-	ASN1_OCTET_STRING *oct;
-	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
-		return NULL;
-	}
-	oct = SXNET_get_id_INTEGER(sx, izone);
-	M_ASN1_INTEGER_free(izone);
-	return oct;
+    ASN1_INTEGER *izone = NULL;
+    ASN1_OCTET_STRING *oct;
+    if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
+        return NULL;
+    }
+    oct = SXNET_get_id_INTEGER(sx, izone);
+    M_ASN1_INTEGER_free(izone);
+    return oct;
 }
 
 ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
 {
-	ASN1_INTEGER *izone = NULL;
-	ASN1_OCTET_STRING *oct;
-	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		M_ASN1_INTEGER_free(izone);
-		return NULL;
-	}
-	oct = SXNET_get_id_INTEGER(sx, izone);
-	M_ASN1_INTEGER_free(izone);
-	return oct;
+    ASN1_INTEGER *izone = NULL;
+    ASN1_OCTET_STRING *oct;
+    if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        M_ASN1_INTEGER_free(izone);
+        return NULL;
+    }
+    oct = SXNET_get_id_INTEGER(sx, izone);
+    M_ASN1_INTEGER_free(izone);
+    return oct;
 }
 
 ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
 {
-	SXNETID *id;
-	size_t i;
-	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
-		id = sk_SXNETID_value(sx->ids, i);
-		if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
-	}
-	return NULL;
+    SXNETID *id;
+    size_t i;
+    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+        id = sk_SXNETID_value(sx->ids, i);
+        if (!M_ASN1_INTEGER_cmp(id->zone, zone))
+            return id->user;
+    }
+    return NULL;
 }
 
 IMPLEMENT_ASN1_SET_OF(SXNETID)
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 6bcb6da..a238a20 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -1,5 +1,6 @@
 /* v3_utl.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -57,7 +58,6 @@
  */
 /* X509 v3 extension utilities */
 
-
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
@@ -72,10 +72,10 @@
 
 #include "../conf/internal.h"
 
-
 static char *strip_spaces(char *name);
 static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
-static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+                                           GENERAL_NAMES *gens);
 static void str_free(OPENSSL_STRING str);
 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
 
@@ -87,1236 +87,1241 @@
 /* Add a CONF_VALUE name value pair to stack */
 
 int X509V3_add_value(const char *name, const char *value,
-						STACK_OF(CONF_VALUE) **extlist)
+                     STACK_OF(CONF_VALUE) **extlist)
 {
-	CONF_VALUE *vtmp = NULL;
-	char *tname = NULL, *tvalue = NULL;
-	if(name && !(tname = BUF_strdup(name))) goto err;
-	if(value && !(tvalue = BUF_strdup(value))) goto err;
-	if(!(vtmp = CONF_VALUE_new())) goto err;
-	if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
-	vtmp->section = NULL;
-	vtmp->name = tname;
-	vtmp->value = tvalue;
-	if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
-	return 1;
-	err:
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	if(vtmp) OPENSSL_free(vtmp);
-	if(tname) OPENSSL_free(tname);
-	if(tvalue) OPENSSL_free(tvalue);
-	return 0;
+    CONF_VALUE *vtmp = NULL;
+    char *tname = NULL, *tvalue = NULL;
+    if (name && !(tname = BUF_strdup(name)))
+        goto err;
+    if (value && !(tvalue = BUF_strdup(value)))
+        goto err;
+    if (!(vtmp = CONF_VALUE_new()))
+        goto err;
+    if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
+        goto err;
+    vtmp->section = NULL;
+    vtmp->name = tname;
+    vtmp->value = tvalue;
+    if (!sk_CONF_VALUE_push(*extlist, vtmp))
+        goto err;
+    return 1;
+ err:
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    if (vtmp)
+        OPENSSL_free(vtmp);
+    if (tname)
+        OPENSSL_free(tname);
+    if (tvalue)
+        OPENSSL_free(tvalue);
+    return 0;
 }
 
 int X509V3_add_value_uchar(const char *name, const unsigned char *value,
-			   STACK_OF(CONF_VALUE) **extlist)
-    {
-    return X509V3_add_value(name,(const char *)value,extlist);
-    }
+                           STACK_OF(CONF_VALUE) **extlist)
+{
+    return X509V3_add_value(name, (const char *)value, extlist);
+}
 
 /* Free function for STACK_OF(CONF_VALUE) */
 
 void X509V3_conf_free(CONF_VALUE *conf)
 {
-	if(!conf) return;
-	if(conf->name) OPENSSL_free(conf->name);
-	if(conf->value) OPENSSL_free(conf->value);
-	if(conf->section) OPENSSL_free(conf->section);
-	OPENSSL_free(conf);
+    if (!conf)
+        return;
+    if (conf->name)
+        OPENSSL_free(conf->name);
+    if (conf->value)
+        OPENSSL_free(conf->value);
+    if (conf->section)
+        OPENSSL_free(conf->section);
+    OPENSSL_free(conf);
 }
 
 int X509V3_add_value_bool(const char *name, int asn1_bool,
-						STACK_OF(CONF_VALUE) **extlist)
+                          STACK_OF(CONF_VALUE) **extlist)
 {
-	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
-	return X509V3_add_value(name, "FALSE", extlist);
+    if (asn1_bool)
+        return X509V3_add_value(name, "TRUE", extlist);
+    return X509V3_add_value(name, "FALSE", extlist);
 }
 
 int X509V3_add_value_bool_nf(char *name, int asn1_bool,
-						STACK_OF(CONF_VALUE) **extlist)
+                             STACK_OF(CONF_VALUE) **extlist)
 {
-	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
-	return 1;
+    if (asn1_bool)
+        return X509V3_add_value(name, "TRUE", extlist);
+    return 1;
 }
 
-
 char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
 {
-	BIGNUM *bntmp = NULL;
-	char *strtmp = NULL;
-	if(!a) return NULL;
-	if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
-	    !(strtmp = BN_bn2dec(bntmp)) )
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	BN_free(bntmp);
-	return strtmp;
+    BIGNUM *bntmp = NULL;
+    char *strtmp = NULL;
+    if (!a)
+        return NULL;
+    if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
+        !(strtmp = BN_bn2dec(bntmp)))
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    BN_free(bntmp);
+    return strtmp;
 }
 
 char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
 {
-	BIGNUM *bntmp = NULL;
-	char *strtmp = NULL;
-	if(!a) return NULL;
-	if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
-	    !(strtmp = BN_bn2dec(bntmp)) )
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	BN_free(bntmp);
-	return strtmp;
+    BIGNUM *bntmp = NULL;
+    char *strtmp = NULL;
+    if (!a)
+        return NULL;
+    if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
+        !(strtmp = BN_bn2dec(bntmp)))
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    BN_free(bntmp);
+    return strtmp;
 }
 
 ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
 {
-	BIGNUM *bn = NULL;
-	ASN1_INTEGER *aint;
-	int isneg, ishex;
-	int ret;
-	if (!value) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
-		return 0;
-	}
-	bn = BN_new();
-	if (value[0] == '-') {
-		value++;
-		isneg = 1;
-	} else isneg = 0;
+    BIGNUM *bn = NULL;
+    ASN1_INTEGER *aint;
+    int isneg, ishex;
+    int ret;
+    if (!value) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+        return 0;
+    }
+    bn = BN_new();
+    if (value[0] == '-') {
+        value++;
+        isneg = 1;
+    } else
+        isneg = 0;
 
-	if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
-		value += 2;
-		ishex = 1;
-	} else ishex = 0;
+    if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+        value += 2;
+        ishex = 1;
+    } else
+        ishex = 0;
 
-	if (ishex) ret = BN_hex2bn(&bn, value);
-	else ret = BN_dec2bn(&bn, value);
+    if (ishex)
+        ret = BN_hex2bn(&bn, value);
+    else
+        ret = BN_dec2bn(&bn, value);
 
-	if (!ret || value[ret]) {
-		BN_free(bn);
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
-		return 0;
-	}
+    if (!ret || value[ret]) {
+        BN_free(bn);
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
+        return 0;
+    }
 
-	if (isneg && BN_is_zero(bn)) isneg = 0;
+    if (isneg && BN_is_zero(bn))
+        isneg = 0;
 
-	aint = BN_to_ASN1_INTEGER(bn, NULL);
-	BN_free(bn);
-	if (!aint) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
-		return 0;
-	}
-	if (isneg) aint->type |= V_ASN1_NEG;
-	return aint;
+    aint = BN_to_ASN1_INTEGER(bn, NULL);
+    BN_free(bn);
+    if (!aint) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+        return 0;
+    }
+    if (isneg)
+        aint->type |= V_ASN1_NEG;
+    return aint;
 }
 
 int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
-	     STACK_OF(CONF_VALUE) **extlist)
+                         STACK_OF(CONF_VALUE) **extlist)
 {
-	char *strtmp;
-	int ret;
-	if(!aint) return 1;
-	if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
-	ret = X509V3_add_value(name, strtmp, extlist);
-	OPENSSL_free(strtmp);
-	return ret;
+    char *strtmp;
+    int ret;
+    if (!aint)
+        return 1;
+    if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
+        return 0;
+    ret = X509V3_add_value(name, strtmp, extlist);
+    OPENSSL_free(strtmp);
+    return ret;
 }
 
 int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
 {
-	char *btmp;
-	if(!(btmp = value->value)) goto err;
-	if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
-		 || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
-		|| !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
-		*asn1_bool = 0xff;
-		return 1;
-	} else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
-		 || !strcmp(btmp, "N") || !strcmp(btmp, "n")
-		|| !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
-		*asn1_bool = 0;
-		return 1;
-	}
-	err:
-	OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
-	X509V3_conf_err(value);
-	return 0;
+    char *btmp;
+    if (!(btmp = value->value))
+        goto err;
+    if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
+        || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
+        || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
+        *asn1_bool = 0xff;
+        return 1;
+    } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
+               || !strcmp(btmp, "N") || !strcmp(btmp, "n")
+               || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
+        *asn1_bool = 0;
+        return 1;
+    }
+ err:
+    OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
+    X509V3_conf_err(value);
+    return 0;
 }
 
 int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
 {
-	ASN1_INTEGER *itmp;
-	if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
-		X509V3_conf_err(value);
-		return 0;
-	}
-	*aint = itmp;
-	return 1;
+    ASN1_INTEGER *itmp;
+    if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
+        X509V3_conf_err(value);
+        return 0;
+    }
+    *aint = itmp;
+    return 1;
 }
 
-#define HDR_NAME	1
-#define HDR_VALUE	2
+#define HDR_NAME        1
+#define HDR_VALUE       2
 
-/*#define DEBUG*/
+/*
+ * #define DEBUG
+ */
 
 STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
 {
-	char *p, *q, c;
-	char *ntmp, *vtmp;
-	STACK_OF(CONF_VALUE) *values = NULL;
-	char *linebuf;
-	int state;
-	/* We are going to modify the line so copy it first */
-	linebuf = BUF_strdup(line);
-	if (linebuf == NULL)
-		{
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	state = HDR_NAME;
-	ntmp = NULL;
-	/* Go through all characters */
-	for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
+    char *p, *q, c;
+    char *ntmp, *vtmp;
+    STACK_OF(CONF_VALUE) *values = NULL;
+    char *linebuf;
+    int state;
+    /* We are going to modify the line so copy it first */
+    linebuf = BUF_strdup(line);
+    if (linebuf == NULL) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    state = HDR_NAME;
+    ntmp = NULL;
+    /* Go through all characters */
+    for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+         p++) {
 
-		switch(state) {
-			case HDR_NAME:
-			if(c == ':') {
-				state = HDR_VALUE;
-				*p = 0;
-				ntmp = strip_spaces(q);
-				if(!ntmp) {
-					OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
-					goto err;
-				}
-				q = p + 1;
-			} else if(c == ',') {
-				*p = 0;
-				ntmp = strip_spaces(q);
-				q = p + 1;
+        switch (state) {
+        case HDR_NAME:
+            if (c == ':') {
+                state = HDR_VALUE;
+                *p = 0;
+                ntmp = strip_spaces(q);
+                if (!ntmp) {
+                    OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+                    goto err;
+                }
+                q = p + 1;
+            } else if (c == ',') {
+                *p = 0;
+                ntmp = strip_spaces(q);
+                q = p + 1;
 #if 0
-				printf("%s\n", ntmp);
+                printf("%s\n", ntmp);
 #endif
-				if(!ntmp) {
-					OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
-					goto err;
-				}
-				X509V3_add_value(ntmp, NULL, &values);
-			}
-			break ;
+                if (!ntmp) {
+                    OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+                    goto err;
+                }
+                X509V3_add_value(ntmp, NULL, &values);
+            }
+            break;
 
-			case HDR_VALUE:
-			if(c == ',') {
-				state = HDR_NAME;
-				*p = 0;
-				vtmp = strip_spaces(q);
+        case HDR_VALUE:
+            if (c == ',') {
+                state = HDR_NAME;
+                *p = 0;
+                vtmp = strip_spaces(q);
 #if 0
-				printf("%s\n", ntmp);
+                printf("%s\n", ntmp);
 #endif
-				if(!vtmp) {
-					OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
-					goto err;
-				}
-				X509V3_add_value(ntmp, vtmp, &values);
-				ntmp = NULL;
-				q = p + 1;
-			}
+                if (!vtmp) {
+                    OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+                    goto err;
+                }
+                X509V3_add_value(ntmp, vtmp, &values);
+                ntmp = NULL;
+                q = p + 1;
+            }
 
-		}
-	}
+        }
+    }
 
-	if(state == HDR_VALUE) {
-		vtmp = strip_spaces(q);
+    if (state == HDR_VALUE) {
+        vtmp = strip_spaces(q);
 #if 0
-		printf("%s=%s\n", ntmp, vtmp);
+        printf("%s=%s\n", ntmp, vtmp);
 #endif
-		if(!vtmp) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
-			goto err;
-		}
-		X509V3_add_value(ntmp, vtmp, &values);
-	} else {
-		ntmp = strip_spaces(q);
+        if (!vtmp) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+            goto err;
+        }
+        X509V3_add_value(ntmp, vtmp, &values);
+    } else {
+        ntmp = strip_spaces(q);
 #if 0
-		printf("%s\n", ntmp);
+        printf("%s\n", ntmp);
 #endif
-		if(!ntmp) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
-			goto err;
-		}
-		X509V3_add_value(ntmp, NULL, &values);
-	}
-OPENSSL_free(linebuf);
-return values;
+        if (!ntmp) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+            goto err;
+        }
+        X509V3_add_value(ntmp, NULL, &values);
+    }
+    OPENSSL_free(linebuf);
+    return values;
 
-err:
-OPENSSL_free(linebuf);
-sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
-return NULL;
+ err:
+    OPENSSL_free(linebuf);
+    sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
+    return NULL;
 
 }
 
 /* Delete leading and trailing spaces from a string */
 static char *strip_spaces(char *name)
 {
-	char *p, *q;
-	/* Skip over leading spaces */
-	p = name;
-	while(*p && isspace((unsigned char)*p)) p++;
-	if(!*p) return NULL;
-	q = p + strlen(p) - 1;
-	while((q != p) && isspace((unsigned char)*q)) q--;
-	if(p != q) q[1] = 0;
-	if(!*p) return NULL;
-	return p;
+    char *p, *q;
+    /* Skip over leading spaces */
+    p = name;
+    while (*p && isspace((unsigned char)*p))
+        p++;
+    if (!*p)
+        return NULL;
+    q = p + strlen(p) - 1;
+    while ((q != p) && isspace((unsigned char)*q))
+        q--;
+    if (p != q)
+        q[1] = 0;
+    if (!*p)
+        return NULL;
+    return p;
 }
 
 /* hex string utilities */
 
-/* Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
- * hex representation
- * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
+/*
+ * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
+ * hex representation @@@ (Contents of buffer are always kept in ASCII, also
+ * on EBCDIC machines)
  */
 
 char *hex_to_string(const unsigned char *buffer, long len)
 {
-	char *tmp, *q;
-	const unsigned char *p;
-	int i;
-	static const char hexdig[] = "0123456789ABCDEF";
-	if(!buffer || !len) return NULL;
-	if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
-		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-		return NULL;
-	}
-	q = tmp;
-	for(i = 0, p = buffer; i < len; i++,p++) {
-		*q++ = hexdig[(*p >> 4) & 0xf];
-		*q++ = hexdig[*p & 0xf];
-		*q++ = ':';
-	}
-	q[-1] = 0;
+    char *tmp, *q;
+    const unsigned char *p;
+    int i;
+    static const char hexdig[] = "0123456789ABCDEF";
+    if (!buffer || !len)
+        return NULL;
+    if (!(tmp = OPENSSL_malloc(len * 3 + 1))) {
+        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    q = tmp;
+    for (i = 0, p = buffer; i < len; i++, p++) {
+        *q++ = hexdig[(*p >> 4) & 0xf];
+        *q++ = hexdig[*p & 0xf];
+        *q++ = ':';
+    }
+    q[-1] = 0;
 
-	return tmp;
+    return tmp;
 }
 
-/* Give a string of hex digits convert to
- * a buffer
+/*
+ * Give a string of hex digits convert to a buffer
  */
 
 unsigned char *string_to_hex(const char *str, long *len)
 {
-	unsigned char *hexbuf, *q;
-	unsigned char ch, cl, *p;
-	if(!str) {
-		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
-		return NULL;
-	}
-	if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
-	for(p = (unsigned char *)str, q = hexbuf; *p;) {
-		ch = *p++;
-		if(ch == ':') continue;
-		cl = *p++;
-		if(!cl) {
-			OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
-			OPENSSL_free(hexbuf);
-			return NULL;
-		}
-		if(isupper(ch)) ch = tolower(ch);
-		if(isupper(cl)) cl = tolower(cl);
+    unsigned char *hexbuf, *q;
+    unsigned char ch, cl, *p;
+    if (!str) {
+        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+        return NULL;
+    }
+    if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1)))
+        goto err;
+    for (p = (unsigned char *)str, q = hexbuf; *p;) {
+        ch = *p++;
+        if (ch == ':')
+            continue;
+        cl = *p++;
+        if (!cl) {
+            OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
+            OPENSSL_free(hexbuf);
+            return NULL;
+        }
+        if (isupper(ch))
+            ch = tolower(ch);
+        if (isupper(cl))
+            cl = tolower(cl);
 
-		if((ch >= '0') && (ch <= '9')) ch -= '0';
-		else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
-		else goto badhex;
+        if ((ch >= '0') && (ch <= '9'))
+            ch -= '0';
+        else if ((ch >= 'a') && (ch <= 'f'))
+            ch -= 'a' - 10;
+        else
+            goto badhex;
 
-		if((cl >= '0') && (cl <= '9')) cl -= '0';
-		else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
-		else goto badhex;
+        if ((cl >= '0') && (cl <= '9'))
+            cl -= '0';
+        else if ((cl >= 'a') && (cl <= 'f'))
+            cl -= 'a' - 10;
+        else
+            goto badhex;
 
-		*q++ = (ch << 4) | cl;
-	}
+        *q++ = (ch << 4) | cl;
+    }
 
-	if(len) *len = q - hexbuf;
+    if (len)
+        *len = q - hexbuf;
 
-	return hexbuf;
+    return hexbuf;
 
-	err:
-	if(hexbuf) OPENSSL_free(hexbuf);
-	OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-	return NULL;
+ err:
+    if (hexbuf)
+        OPENSSL_free(hexbuf);
+    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+    return NULL;
 
-	badhex:
-	OPENSSL_free(hexbuf);
-	OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
-	return NULL;
+ badhex:
+    OPENSSL_free(hexbuf);
+    OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
+    return NULL;
 
 }
 
-/* V2I name comparison function: returns zero if 'name' matches
- * cmp or cmp.*
+/*
+ * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
  */
 
 int name_cmp(const char *name, const char *cmp)
 {
-	int len, ret;
-	char c;
-	len = strlen(cmp);
-	if((ret = strncmp(name, cmp, len))) return ret;
-	c = name[len];
-	if(!c || (c=='.')) return 0;
-	return 1;
+    int len, ret;
+    char c;
+    len = strlen(cmp);
+    if ((ret = strncmp(name, cmp, len)))
+        return ret;
+    c = name[len];
+    if (!c || (c == '.'))
+        return 0;
+    return 1;
 }
 
 static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
 {
-	return strcmp(*a, *b);
+    return strcmp(*a, *b);
 }
 
 STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
 {
-	GENERAL_NAMES *gens;
-	STACK_OF(OPENSSL_STRING) *ret;
+    GENERAL_NAMES *gens;
+    STACK_OF(OPENSSL_STRING) *ret;
 
-	gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
-	ret = get_email(X509_get_subject_name(x), gens);
-	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-	return ret;
+    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    ret = get_email(X509_get_subject_name(x), gens);
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return ret;
 }
 
 STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
 {
-	AUTHORITY_INFO_ACCESS *info;
-	STACK_OF(OPENSSL_STRING) *ret = NULL;
-	size_t i;
+    AUTHORITY_INFO_ACCESS *info;
+    STACK_OF(OPENSSL_STRING) *ret = NULL;
+    size_t i;
 
-	info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
-	if (!info)
-		return NULL;
-	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++)
-		{
-		ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
-		if (OBJ_obj2nid(ad->method) == NID_ad_OCSP)
-			{
-			if (ad->location->type == GEN_URI)
-				{
-				if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier))
-					break;
-				}
-			}
-		}
-	AUTHORITY_INFO_ACCESS_free(info);
-	return ret;
+    info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+    if (!info)
+        return NULL;
+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+        ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
+        if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
+            if (ad->location->type == GEN_URI) {
+                if (!append_ia5
+                    (&ret, ad->location->d.uniformResourceIdentifier))
+                    break;
+            }
+        }
+    }
+    AUTHORITY_INFO_ACCESS_free(info);
+    return ret;
 }
 
 STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
 {
-	GENERAL_NAMES *gens;
-	STACK_OF(X509_EXTENSION) *exts;
-	STACK_OF(OPENSSL_STRING) *ret;
+    GENERAL_NAMES *gens;
+    STACK_OF(X509_EXTENSION) *exts;
+    STACK_OF(OPENSSL_STRING) *ret;
 
-	exts = X509_REQ_get_extensions(x);
-	gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
-	ret = get_email(X509_REQ_get_subject_name(x), gens);
-	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
-	return ret;
+    exts = X509_REQ_get_extensions(x);
+    gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+    ret = get_email(X509_REQ_get_subject_name(x), gens);
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+    return ret;
 }
 
-
-static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+                                           GENERAL_NAMES *gens)
 {
-	STACK_OF(OPENSSL_STRING) *ret = NULL;
-	X509_NAME_ENTRY *ne;
-	ASN1_IA5STRING *email;
-	GENERAL_NAME *gen;
-	int i;
-	size_t j;
-	/* Now add any email address(es) to STACK */
-	i = -1;
-	/* First supplied X509_NAME */
-	while((i = X509_NAME_get_index_by_NID(name,
-					 NID_pkcs9_emailAddress, i)) >= 0) {
-		ne = X509_NAME_get_entry(name, i);
-		email = X509_NAME_ENTRY_get_data(ne);
-		if(!append_ia5(&ret, email)) return NULL;
-	}
-	for(j = 0; j < sk_GENERAL_NAME_num(gens); j++)
-	{
-		gen = sk_GENERAL_NAME_value(gens, j);
-		if(gen->type != GEN_EMAIL) continue;
-		if(!append_ia5(&ret, gen->d.ia5)) return NULL;
-	}
-	return ret;
+    STACK_OF(OPENSSL_STRING) *ret = NULL;
+    X509_NAME_ENTRY *ne;
+    ASN1_IA5STRING *email;
+    GENERAL_NAME *gen;
+    int i;
+    size_t j;
+    /* Now add any email address(es) to STACK */
+    i = -1;
+    /* First supplied X509_NAME */
+    while ((i = X509_NAME_get_index_by_NID(name,
+                                           NID_pkcs9_emailAddress, i)) >= 0) {
+        ne = X509_NAME_get_entry(name, i);
+        email = X509_NAME_ENTRY_get_data(ne);
+        if (!append_ia5(&ret, email))
+            return NULL;
+    }
+    for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
+        gen = sk_GENERAL_NAME_value(gens, j);
+        if (gen->type != GEN_EMAIL)
+            continue;
+        if (!append_ia5(&ret, gen->d.ia5))
+            return NULL;
+    }
+    return ret;
 }
 
 static void str_free(OPENSSL_STRING str)
 {
-	OPENSSL_free(str);
+    OPENSSL_free(str);
 }
 
 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
 {
-	char *emtmp;
-	/* First some sanity checks */
-	if(email->type != V_ASN1_IA5STRING) return 1;
-	if(!email->data || !email->length) return 1;
-	if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
-	if(!*sk) return 0;
-	/* Don't add duplicates */
-	if(sk_OPENSSL_STRING_find(*sk, NULL, (char *)email->data)) return 1;
-	emtmp = BUF_strdup((char *)email->data);
-	if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
-		X509_email_free(*sk);
-		*sk = NULL;
-		return 0;
-	}
-	return 1;
+    char *emtmp;
+    /* First some sanity checks */
+    if (email->type != V_ASN1_IA5STRING)
+        return 1;
+    if (!email->data || !email->length)
+        return 1;
+    if (!*sk)
+        *sk = sk_OPENSSL_STRING_new(sk_strcmp);
+    if (!*sk)
+        return 0;
+    /* Don't add duplicates */
+    if (sk_OPENSSL_STRING_find(*sk, NULL, (char *)email->data))
+        return 1;
+    emtmp = BUF_strdup((char *)email->data);
+    if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
+        X509_email_free(*sk);
+        *sk = NULL;
+        return 0;
+    }
+    return 1;
 }
 
 void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
 {
-	sk_OPENSSL_STRING_pop_free(sk, str_free);
+    sk_OPENSSL_STRING_pop_free(sk, str_free);
 }
 
-typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len,
-			const unsigned char *subject, size_t subject_len,
-			unsigned int flags);
+typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
+                         const unsigned char *subject, size_t subject_len,
+                         unsigned int flags);
 
 /* Skip pattern prefix to match "wildcard" subject */
 static void skip_prefix(const unsigned char **p, size_t *plen,
-			const unsigned char *subject, size_t subject_len,
-			unsigned int flags)
-	{
-	const unsigned char *pattern = *p;
-	size_t pattern_len = *plen;
+                        const unsigned char *subject, size_t subject_len,
+                        unsigned int flags)
+{
+    const unsigned char *pattern = *p;
+    size_t pattern_len = *plen;
 
-	/*
-	 * If subject starts with a leading '.' followed by more octets, and
-	 * pattern is longer, compare just an equal-length suffix with the
-	 * full subject (starting at the '.'), provided the prefix contains
-	 * no NULs.
-	 */
-	if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
-		return;
+    /*
+     * If subject starts with a leading '.' followed by more octets, and
+     * pattern is longer, compare just an equal-length suffix with the
+     * full subject (starting at the '.'), provided the prefix contains
+     * no NULs.
+     */
+    if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
+        return;
 
-	while (pattern_len > subject_len && *pattern)
-		{
-		if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
-		    *pattern == '.')
-			break;
-		++pattern;
-		--pattern_len;
-		}
+    while (pattern_len > subject_len && *pattern) {
+        if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
+            *pattern == '.')
+            break;
+        ++pattern;
+        --pattern_len;
+    }
 
-	/* Skip if entire prefix acceptable */
-	if (pattern_len == subject_len)
-		{
-		*p = pattern;
-		*plen = pattern_len;
-		}
-	}
+    /* Skip if entire prefix acceptable */
+    if (pattern_len == subject_len) {
+        *p = pattern;
+        *plen = pattern_len;
+    }
+}
 
 /* Compare while ASCII ignoring case. */
 static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
-			const unsigned char *subject, size_t subject_len,
-			unsigned int flags)
-	{
-	skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
-	if (pattern_len != subject_len)
-		return 0;
-	while (pattern_len)
-		{
-		unsigned char l = *pattern;
-		unsigned char r = *subject;
-		/* The pattern must not contain NUL characters. */
-		if (l == 0)
-			return 0;
-		if (l != r)
-			{
-			if ('A' <= l && l <= 'Z')
-				l = (l - 'A') + 'a';
-			if ('A' <= r && r <= 'Z')
-				r = (r - 'A') + 'a';
-			if (l != r)
-				return 0;
-			}
-		++pattern;
-		++subject;
-		--pattern_len;
-		}
-	return 1;
-	}
+                        const unsigned char *subject, size_t subject_len,
+                        unsigned int flags)
+{
+    skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+    if (pattern_len != subject_len)
+        return 0;
+    while (pattern_len) {
+        unsigned char l = *pattern;
+        unsigned char r = *subject;
+        /* The pattern must not contain NUL characters. */
+        if (l == 0)
+            return 0;
+        if (l != r) {
+            if ('A' <= l && l <= 'Z')
+                l = (l - 'A') + 'a';
+            if ('A' <= r && r <= 'Z')
+                r = (r - 'A') + 'a';
+            if (l != r)
+                return 0;
+        }
+        ++pattern;
+        ++subject;
+        --pattern_len;
+    }
+    return 1;
+}
 
 /* Compare using memcmp. */
 static int equal_case(const unsigned char *pattern, size_t pattern_len,
-		      const unsigned char *subject, size_t subject_len,
-		      unsigned int flags)
+                      const unsigned char *subject, size_t subject_len,
+                      unsigned int flags)
 {
-	skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
-	if (pattern_len != subject_len)
-		return 0;
-	return !memcmp(pattern, subject, pattern_len);
+    skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+    if (pattern_len != subject_len)
+        return 0;
+    return !memcmp(pattern, subject, pattern_len);
 }
 
-/* RFC 5280, section 7.5, requires that only the domain is compared in
-   a case-insensitive manner. */
+/*
+ * RFC 5280, section 7.5, requires that only the domain is compared in a
+ * case-insensitive manner.
+ */
 static int equal_email(const unsigned char *a, size_t a_len,
-		       const unsigned char *b, size_t b_len,
-		       unsigned int unused_flags)
-	{
-	size_t i = a_len;
-	if (a_len != b_len)
-		return 0;
-	/* We search backwards for the '@' character, so that we do
-	   not have to deal with quoted local-parts.  The domain part
-	   is compared in a case-insensitive manner. */
-	while (i > 0)
-		{
-		--i;
-		if (a[i] == '@' || b[i] == '@')
-			{
-			if (!equal_nocase(a + i, a_len - i,
-					  b + i, a_len - i, 0))
-				return 0;
-			break;
-			}
-		}
-	if (i == 0)
-		i = a_len;
-	return equal_case(a, i, b, i, 0);
-	}
+                       const unsigned char *b, size_t b_len,
+                       unsigned int unused_flags)
+{
+    size_t i = a_len;
+    if (a_len != b_len)
+        return 0;
+    /*
+     * We search backwards for the '@' character, so that we do not have to
+     * deal with quoted local-parts.  The domain part is compared in a
+     * case-insensitive manner.
+     */
+    while (i > 0) {
+        --i;
+        if (a[i] == '@' || b[i] == '@') {
+            if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
+                return 0;
+            break;
+        }
+    }
+    if (i == 0)
+        i = a_len;
+    return equal_case(a, i, b, i, 0);
+}
 
-/* Compare the prefix and suffix with the subject, and check that the
-   characters in-between are valid. */
+/*
+ * Compare the prefix and suffix with the subject, and check that the
+ * characters in-between are valid.
+ */
 static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
-			  const unsigned char *suffix, size_t suffix_len,
-			  const unsigned char *subject, size_t subject_len,
-			  unsigned int flags)
-	{
-	const unsigned char *wildcard_start;
-	const unsigned char *wildcard_end;
-	const unsigned char *p;
-	int allow_multi = 0;
-	int allow_idna = 0;
+                          const unsigned char *suffix, size_t suffix_len,
+                          const unsigned char *subject, size_t subject_len,
+                          unsigned int flags)
+{
+    const unsigned char *wildcard_start;
+    const unsigned char *wildcard_end;
+    const unsigned char *p;
+    int allow_multi = 0;
+    int allow_idna = 0;
 
-	if (subject_len < prefix_len + suffix_len)
-		return 0;
-	if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
-		return 0;
-	wildcard_start = subject + prefix_len;
-	wildcard_end = subject + (subject_len - suffix_len);
-	if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
-		return 0;
-	/*
-	 * If the wildcard makes up the entire first label, it must match at
-	 * least one character.
-	 */
-	if (prefix_len == 0 && *suffix == '.')
-		{
-		if (wildcard_start == wildcard_end)
-			return 0;
-		allow_idna = 1;
-		if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
-			allow_multi = 1;
-		}
-	/* IDNA labels cannot match partial wildcards */
-	if (!allow_idna &&
-	    subject_len >= 4 && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0)
-		return 0;
-	/* The wildcard may match a literal '*' */
-	if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
-		return 1;
-	/*
-	 * Check that the part matched by the wildcard contains only
-	 * permitted characters and only matches a single label unless
-	 * allow_multi is set.
-	 */
-	for (p = wildcard_start; p != wildcard_end; ++p)
-		if (!(('0' <= *p && *p <= '9') ||
-		      ('A' <= *p && *p <= 'Z') ||
-		      ('a' <= *p && *p <= 'z') ||
-		      *p == '-' || (allow_multi && *p == '.')))
-			return 0;
-	return 1;
-	}
+    if (subject_len < prefix_len + suffix_len)
+        return 0;
+    if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
+        return 0;
+    wildcard_start = subject + prefix_len;
+    wildcard_end = subject + (subject_len - suffix_len);
+    if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
+        return 0;
+    /*
+     * If the wildcard makes up the entire first label, it must match at
+     * least one character.
+     */
+    if (prefix_len == 0 && *suffix == '.') {
+        if (wildcard_start == wildcard_end)
+            return 0;
+        allow_idna = 1;
+        if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
+            allow_multi = 1;
+    }
+    /* IDNA labels cannot match partial wildcards */
+    if (!allow_idna &&
+        subject_len >= 4
+        && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0)
+        return 0;
+    /* The wildcard may match a literal '*' */
+    if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
+        return 1;
+    /*
+     * Check that the part matched by the wildcard contains only
+     * permitted characters and only matches a single label unless
+     * allow_multi is set.
+     */
+    for (p = wildcard_start; p != wildcard_end; ++p)
+        if (!(('0' <= *p && *p <= '9') ||
+              ('A' <= *p && *p <= 'Z') ||
+              ('a' <= *p && *p <= 'z') ||
+              *p == '-' || (allow_multi && *p == '.')))
+            return 0;
+    return 1;
+}
 
-#define LABEL_START	(1 << 0)
-#define LABEL_END	(1 << 1)
-#define LABEL_HYPHEN	(1 << 2)
-#define LABEL_IDNA	(1 << 3)
+#define LABEL_START     (1 << 0)
+#define LABEL_END       (1 << 1)
+#define LABEL_HYPHEN    (1 << 2)
+#define LABEL_IDNA      (1 << 3)
 
 static const unsigned char *valid_star(const unsigned char *p, size_t len,
-						unsigned int flags)
-	{
-	const unsigned char *star = 0;
-	size_t i;
-	int state = LABEL_START;
-	int dots = 0;
-	for (i = 0; i < len; ++i)
-		{
-		/*
-		 * Locate first and only legal wildcard, either at the start
-		 * or end of a non-IDNA first and not final label.
-		 */
-		if (p[i] == '*')
-			{
-			int atstart = (state & LABEL_START);
-			int atend = (i == len - 1 || p[i+1] == '.');
-			/*
-			 * At most one wildcard per pattern.
-			 * No wildcards in IDNA labels.
-			 * No wildcards after the first label.
-			 */
-			if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
-				return NULL;
-			/* Only full-label '*.example.com' wildcards? */
-			if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
-			    && (!atstart || !atend))
-				return NULL;
-			/* No 'foo*bar' wildcards */
-			if (!atstart && !atend)
-				return NULL;
-			star = &p[i];
-			state &= ~LABEL_START;
-			}
-		else if ((state & LABEL_START) != 0)
-			{
-			/*
-			 * At the start of a label, skip any "xn--" and
-			 * remain in the LABEL_START state, but set the
-			 * IDNA label state
-			 */
-			if ((state & LABEL_IDNA) == 0 && len - i >= 4
-			    && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0)
-				{
-				i += 3;
-				state |= LABEL_IDNA;
-				continue;
-				}
-			/* Labels must start with a letter or digit */
-			state &= ~LABEL_START;
-			if (('a' <= p[i] && p[i] <= 'z')
-			    || ('A' <= p[i] && p[i] <= 'Z')
-			    || ('0' <= p[i] && p[i] <= '9'))
-				continue;
-			return NULL;
-			}
-		else if (('a' <= p[i] && p[i] <= 'z')
-			 || ('A' <= p[i] && p[i] <= 'Z')
-			 || ('0' <= p[i] && p[i] <= '9'))
-			{
-			state &= LABEL_IDNA;
-			continue;
-			}
-		else if (p[i] == '.')
-			{
-			if (state & (LABEL_HYPHEN | LABEL_START))
-				return NULL;
-			state = LABEL_START;
-			++dots;
-			}
-		else if (p[i] == '-')
-			{
-			if (state & LABEL_HYPHEN)
-				return NULL;
-			state |= LABEL_HYPHEN;
-			}
-		else
-			return NULL;
-		}
+                                       unsigned int flags)
+{
+    const unsigned char *star = 0;
+    size_t i;
+    int state = LABEL_START;
+    int dots = 0;
+    for (i = 0; i < len; ++i) {
+        /*
+         * Locate first and only legal wildcard, either at the start
+         * or end of a non-IDNA first and not final label.
+         */
+        if (p[i] == '*') {
+            int atstart = (state & LABEL_START);
+            int atend = (i == len - 1 || p[i + 1] == '.');
+            /*
+             * At most one wildcard per pattern.
+             * No wildcards in IDNA labels.
+             * No wildcards after the first label.
+             */
+            if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
+                return NULL;
+            /* Only full-label '*.example.com' wildcards? */
+            if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
+                && (!atstart || !atend))
+                return NULL;
+            /* No 'foo*bar' wildcards */
+            if (!atstart && !atend)
+                return NULL;
+            star = &p[i];
+            state &= ~LABEL_START;
+        } else if ((state & LABEL_START) != 0) {
+            /*
+             * At the start of a label, skip any "xn--" and
+             * remain in the LABEL_START state, but set the
+             * IDNA label state
+             */
+            if ((state & LABEL_IDNA) == 0 && len - i >= 4
+                && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) {
+                i += 3;
+                state |= LABEL_IDNA;
+                continue;
+            }
+            /* Labels must start with a letter or digit */
+            state &= ~LABEL_START;
+            if (('a' <= p[i] && p[i] <= 'z')
+                || ('A' <= p[i] && p[i] <= 'Z')
+                || ('0' <= p[i] && p[i] <= '9'))
+                continue;
+            return NULL;
+        } else if (('a' <= p[i] && p[i] <= 'z')
+                   || ('A' <= p[i] && p[i] <= 'Z')
+                   || ('0' <= p[i] && p[i] <= '9')) {
+            state &= LABEL_IDNA;
+            continue;
+        } else if (p[i] == '.') {
+            if (state & (LABEL_HYPHEN | LABEL_START))
+                return NULL;
+            state = LABEL_START;
+            ++dots;
+        } else if (p[i] == '-') {
+            /* no domain/subdomain starts with '-' */
+            if ((state & LABEL_START) != 0)
+                return NULL;
+            state |= LABEL_HYPHEN;
+        } else
+            return NULL;
+    }
 
-	/*
-	 * The final label must not end in a hyphen or ".", and
-	 * there must be at least two dots after the star.
-	 */
-	if ((state & (LABEL_START | LABEL_HYPHEN)) != 0
-	    || dots < 2)
-		return NULL;
-	return star;
-	}
+    /*
+     * The final label must not end in a hyphen or ".", and
+     * there must be at least two dots after the star.
+     */
+    if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
+        return NULL;
+    return star;
+}
 
 /* Compare using wildcards. */
 static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
-			  const unsigned char *subject, size_t subject_len,
-			  unsigned int flags)
-	{
-	const unsigned char *star = NULL;
+                          const unsigned char *subject, size_t subject_len,
+                          unsigned int flags)
+{
+    const unsigned char *star = NULL;
 
-	/*
-	 * Subject names starting with '.' can only match a wildcard pattern
-	 * via a subject sub-domain pattern suffix match.
-	 */
-	if (!(subject_len > 1 && subject[0] == '.'))
-		star = valid_star(pattern, pattern_len, flags);
-	if (star == NULL)
-		return equal_nocase(pattern, pattern_len,
-				    subject, subject_len, flags);
-	return wildcard_match(pattern, star - pattern,
-			      star + 1, (pattern + pattern_len) - star - 1,
-			      subject, subject_len, flags);
-	}
+    /*
+     * Subject names starting with '.' can only match a wildcard pattern
+     * via a subject sub-domain pattern suffix match.
+     */
+    if (!(subject_len > 1 && subject[0] == '.'))
+        star = valid_star(pattern, pattern_len, flags);
+    if (star == NULL)
+        return equal_nocase(pattern, pattern_len,
+                            subject, subject_len, flags);
+    return wildcard_match(pattern, star - pattern,
+                          star + 1, (pattern + pattern_len) - star - 1,
+                          subject, subject_len, flags);
+}
 
-/* Compare an ASN1_STRING to a supplied string. If they match
- * return 1. If cmp_type > 0 only compare if string matches the
- * type, otherwise convert it to UTF8.
+/*
+ * Compare an ASN1_STRING to a supplied string. If they match return 1. If
+ * cmp_type > 0 only compare if string matches the type, otherwise convert it
+ * to UTF8.
  */
 
 static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
-				unsigned int flags, const char *b, size_t blen,
-				char **peername)
-	{
-	int rv = 0;
+                           unsigned int flags, const char *b, size_t blen,
+                           char **peername)
+{
+    int rv = 0;
 
-	if (!a->data || !a->length)
-		return 0;
-	if (cmp_type > 0)
-		{
-		if (cmp_type != a->type)
-			return 0;
-		if (cmp_type == V_ASN1_IA5STRING)
-			rv = equal(a->data, a->length,
-				   (unsigned char *)b, blen, flags);
-		else if (a->length == (int)blen && !memcmp(a->data, b, blen))
-			rv = 1;
-		if (rv > 0 && peername)
-			*peername = BUF_strndup((char *)a->data, a->length);
-		}
-	else
-		{
-		int astrlen;
-		unsigned char *astr;
-		astrlen = ASN1_STRING_to_UTF8(&astr, a);
-		if (astrlen < 0)
-			return -1;
-		rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
-		if (rv > 0 && peername)
-			*peername = BUF_strndup((char *)astr, astrlen);
-		OPENSSL_free(astr);
-		}
-	return rv;
-	}
+    if (!a->data || !a->length)
+        return 0;
+    if (cmp_type > 0) {
+        if (cmp_type != a->type)
+            return 0;
+        if (cmp_type == V_ASN1_IA5STRING)
+            rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
+        else if (a->length == (int)blen && !memcmp(a->data, b, blen))
+            rv = 1;
+        if (rv > 0 && peername)
+            *peername = BUF_strndup((char *)a->data, a->length);
+    } else {
+        int astrlen;
+        unsigned char *astr;
+        astrlen = ASN1_STRING_to_UTF8(&astr, a);
+        if (astrlen < 0)
+            return -1;
+        rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
+        if (rv > 0 && peername)
+            *peername = BUF_strndup((char *)astr, astrlen);
+        OPENSSL_free(astr);
+    }
+    return rv;
+}
 
 static int do_x509_check(X509 *x, const char *chk, size_t chklen,
-					unsigned int flags, int check_type,
-					char **peername)
-	{
-	GENERAL_NAMES *gens = NULL;
-	X509_NAME *name = NULL;
-	size_t i;
-	int j;
-	int cnid = NID_undef;
-	int alt_type;
-	int san_present = 0;
-	int rv = 0;
-	equal_fn equal;
+                         unsigned int flags, int check_type, char **peername)
+{
+    GENERAL_NAMES *gens = NULL;
+    X509_NAME *name = NULL;
+    size_t i;
+    int j;
+    int cnid = NID_undef;
+    int alt_type;
+    int san_present = 0;
+    int rv = 0;
+    equal_fn equal;
 
-	/* See below, this flag is internal-only */
-	flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
-	if (check_type == GEN_EMAIL)
-		{
-		cnid = NID_pkcs9_emailAddress;
-		alt_type = V_ASN1_IA5STRING;
-		equal = equal_email;
-		}
-	else if (check_type == GEN_DNS)
-		{
-		cnid = NID_commonName;
-		/* Implicit client-side DNS sub-domain pattern */
-		if (chklen > 1 && chk[0] == '.')
-			flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
-		alt_type = V_ASN1_IA5STRING;
-		if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
-			equal = equal_nocase;
-		else
-			equal = equal_wildcard;
-		}
-	else
-		{
-		alt_type = V_ASN1_OCTET_STRING;
-		equal = equal_case;
-		}
+    /* See below, this flag is internal-only */
+    flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
+    if (check_type == GEN_EMAIL) {
+        cnid = NID_pkcs9_emailAddress;
+        alt_type = V_ASN1_IA5STRING;
+        equal = equal_email;
+    } else if (check_type == GEN_DNS) {
+        cnid = NID_commonName;
+        /* Implicit client-side DNS sub-domain pattern */
+        if (chklen > 1 && chk[0] == '.')
+            flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
+        alt_type = V_ASN1_IA5STRING;
+        if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
+            equal = equal_nocase;
+        else
+            equal = equal_wildcard;
+    } else {
+        alt_type = V_ASN1_OCTET_STRING;
+        equal = equal_case;
+    }
 
-	gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
-	if (gens)
-		{
-		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
-			{
-			GENERAL_NAME *gen;
-			ASN1_STRING *cstr;
-			gen = sk_GENERAL_NAME_value(gens, i);
-			if (gen->type != check_type)
-				continue;
-			san_present = 1;
-			if (check_type == GEN_EMAIL)
-				cstr = gen->d.rfc822Name;
-			else if (check_type == GEN_DNS)
-				cstr = gen->d.dNSName;
-			else
-				cstr = gen->d.iPAddress;
-			/* Positive on success, negative on error! */
-			if ((rv = do_check_string(cstr, alt_type, equal, flags,
-						  chk, chklen, peername)) != 0)
-				break;
-			}
-		GENERAL_NAMES_free(gens);
-		if (rv != 0)
-			return rv;
-		if (cnid == NID_undef
-		    || (san_present
-		        && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
-			return 0;
-		}
+    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    if (gens) {
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            GENERAL_NAME *gen;
+            ASN1_STRING *cstr;
+            gen = sk_GENERAL_NAME_value(gens, i);
+            if (gen->type != check_type)
+                continue;
+            san_present = 1;
+            if (check_type == GEN_EMAIL)
+                cstr = gen->d.rfc822Name;
+            else if (check_type == GEN_DNS)
+                cstr = gen->d.dNSName;
+            else
+                cstr = gen->d.iPAddress;
+            /* Positive on success, negative on error! */
+            if ((rv = do_check_string(cstr, alt_type, equal, flags,
+                                      chk, chklen, peername)) != 0)
+                break;
+        }
+        GENERAL_NAMES_free(gens);
+        if (rv != 0)
+            return rv;
+        if (cnid == NID_undef
+            || (san_present
+                && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
+            return 0;
+    }
 
-	/* We're done if CN-ID is not pertinent */
-	if (cnid == NID_undef)
-		return 0;
+    /* We're done if CN-ID is not pertinent */
+    if (cnid == NID_undef)
+        return 0;
 
-	j = -1;
-	name = X509_get_subject_name(x);
-	while((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0)
-		{
-		X509_NAME_ENTRY *ne;
-		ASN1_STRING *str;
-		ne = X509_NAME_get_entry(name, j);
-		str = X509_NAME_ENTRY_get_data(ne);
-		/* Positive on success, negative on error! */
-		if ((rv = do_check_string(str, -1, equal, flags,
-					  chk, chklen, peername)) != 0)
-			return rv;
-		}
-	return 0;
-	}
+    j = -1;
+    name = X509_get_subject_name(x);
+    while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) {
+        X509_NAME_ENTRY *ne;
+        ASN1_STRING *str;
+        ne = X509_NAME_get_entry(name, j);
+        str = X509_NAME_ENTRY_get_data(ne);
+        /* Positive on success, negative on error! */
+        if ((rv = do_check_string(str, -1, equal, flags,
+                                  chk, chklen, peername)) != 0)
+            return rv;
+    }
+    return 0;
+}
 
 int X509_check_host(X509 *x, const char *chk, size_t chklen,
-			unsigned int flags, char **peername)
-	{
-	if (chk == NULL)
-		return -2;
-	if (memchr(chk, '\0', chklen))
-		return -2;
-	return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
-	}
+                    unsigned int flags, char **peername)
+{
+    if (chk == NULL)
+        return -2;
+    if (memchr(chk, '\0', chklen))
+        return -2;
+    return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
+}
 
 int X509_check_email(X509 *x, const char *chk, size_t chklen,
-			unsigned int flags)
-	{
-	if (chk == NULL)
-		return -2;
-	if (memchr(chk, '\0', chklen))
-		return -2;
-	return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
-	}
+                     unsigned int flags)
+{
+    if (chk == NULL)
+        return -2;
+    if (memchr(chk, '\0', chklen))
+        return -2;
+    return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
+}
 
 int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
-					unsigned int flags)
-	{
-	if (chk == NULL)
-		return -2;
-	return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
-	}
+                  unsigned int flags)
+{
+    if (chk == NULL)
+        return -2;
+    return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
+}
 
 int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
-	{
-	unsigned char ipout[16];
-	size_t iplen;
+{
+    unsigned char ipout[16];
+    size_t iplen;
 
-	if (ipasc == NULL)
-		return -2;
-	iplen = (size_t) a2i_ipadd(ipout, ipasc);
-	if (iplen == 0)
-		return -2;
-	return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
-	}
+    if (ipasc == NULL)
+        return -2;
+    iplen = (size_t)a2i_ipadd(ipout, ipasc);
+    if (iplen == 0)
+        return -2;
+    return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
+}
 
-/* Convert IP addresses both IPv4 and IPv6 into an 
- * OCTET STRING compatible with RFC3280.
+/*
+ * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
+ * with RFC3280.
  */
 
 ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
-	{
-	unsigned char ipout[16];
-	ASN1_OCTET_STRING *ret;
-	int iplen;
+{
+    unsigned char ipout[16];
+    ASN1_OCTET_STRING *ret;
+    int iplen;
 
-	/* If string contains a ':' assume IPv6 */
+    /* If string contains a ':' assume IPv6 */
 
-	iplen = a2i_ipadd(ipout, ipasc);
+    iplen = a2i_ipadd(ipout, ipasc);
 
-	if (!iplen)
-		return NULL;
+    if (!iplen)
+        return NULL;
 
-	ret = ASN1_OCTET_STRING_new();
-	if (!ret)
-		return NULL;
-	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen))
-		{
-		ASN1_OCTET_STRING_free(ret);
-		return NULL;
-		}
-	return ret;
-	}
+    ret = ASN1_OCTET_STRING_new();
+    if (!ret)
+        return NULL;
+    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
+        ASN1_OCTET_STRING_free(ret);
+        return NULL;
+    }
+    return ret;
+}
 
 ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
-	{
-	ASN1_OCTET_STRING *ret = NULL;
-	unsigned char ipout[32];
-	char *iptmp = NULL, *p;
-	int iplen1, iplen2;
-	p = strchr(ipasc,'/');
-	if (!p)
-		return NULL;
-	iptmp = BUF_strdup(ipasc);
-	if (!iptmp)
-		return NULL;
-	p = iptmp + (p - ipasc);
-	*p++ = 0;
+{
+    ASN1_OCTET_STRING *ret = NULL;
+    unsigned char ipout[32];
+    char *iptmp = NULL, *p;
+    int iplen1, iplen2;
+    p = strchr(ipasc, '/');
+    if (!p)
+        return NULL;
+    iptmp = BUF_strdup(ipasc);
+    if (!iptmp)
+        return NULL;
+    p = iptmp + (p - ipasc);
+    *p++ = 0;
 
-	iplen1 = a2i_ipadd(ipout, iptmp);
+    iplen1 = a2i_ipadd(ipout, iptmp);
 
-	if (!iplen1)
-		goto err;
+    if (!iplen1)
+        goto err;
 
-	iplen2 = a2i_ipadd(ipout + iplen1, p);
+    iplen2 = a2i_ipadd(ipout + iplen1, p);
 
-	OPENSSL_free(iptmp);
-	iptmp = NULL;
+    OPENSSL_free(iptmp);
+    iptmp = NULL;
 
-	if (!iplen2 || (iplen1 != iplen2))
-		goto err;
+    if (!iplen2 || (iplen1 != iplen2))
+        goto err;
 
-	ret = ASN1_OCTET_STRING_new();
-	if (!ret)
-		goto err;
-	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
-		goto err;
+    ret = ASN1_OCTET_STRING_new();
+    if (!ret)
+        goto err;
+    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
+        goto err;
 
-	return ret;
+    return ret;
 
-	err:
-	if (iptmp)
-		OPENSSL_free(iptmp);
-	if (ret)
-		ASN1_OCTET_STRING_free(ret);
-	return NULL;
-	}
-	
+ err:
+    if (iptmp)
+        OPENSSL_free(iptmp);
+    if (ret)
+        ASN1_OCTET_STRING_free(ret);
+    return NULL;
+}
 
 int a2i_ipadd(unsigned char *ipout, const char *ipasc)
-	{
-	/* If string contains a ':' assume IPv6 */
+{
+    /* If string contains a ':' assume IPv6 */
 
-	if (strchr(ipasc, ':'))
-		{
-		if (!ipv6_from_asc(ipout, ipasc))
-			return 0;
-		return 16;
-		}
-	else
-		{
-		if (!ipv4_from_asc(ipout, ipasc))
-			return 0;
-		return 4;
-		}
-	}
+    if (strchr(ipasc, ':')) {
+        if (!ipv6_from_asc(ipout, ipasc))
+            return 0;
+        return 16;
+    } else {
+        if (!ipv4_from_asc(ipout, ipasc))
+            return 0;
+        return 4;
+    }
+}
 
 static int ipv4_from_asc(unsigned char *v4, const char *in)
-	{
-	int a0, a1, a2, a3;
-	if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
-		return 0;
-	if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
-		|| (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
-		return 0;
-	v4[0] = a0;
-	v4[1] = a1;
-	v4[2] = a2;
-	v4[3] = a3;
-	return 1;
-	}
+{
+    int a0, a1, a2, a3;
+    if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+        return 0;
+    if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+        || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
+        return 0;
+    v4[0] = a0;
+    v4[1] = a1;
+    v4[2] = a2;
+    v4[3] = a3;
+    return 1;
+}
 
 typedef struct {
-		/* Temporary store for IPV6 output */
-		unsigned char tmp[16];
-		/* Total number of bytes in tmp */
-		int total;
-		/* The position of a zero (corresponding to '::') */
-		int zero_pos;
-		/* Number of zeroes */
-		int zero_cnt;
-	} IPV6_STAT;
-
+    /* Temporary store for IPV6 output */
+    unsigned char tmp[16];
+    /* Total number of bytes in tmp */
+    int total;
+    /* The position of a zero (corresponding to '::') */
+    int zero_pos;
+    /* Number of zeroes */
+    int zero_cnt;
+} IPV6_STAT;
 
 static int ipv6_from_asc(unsigned char *v6, const char *in)
-	{
-	IPV6_STAT v6stat;
-	v6stat.total = 0;
-	v6stat.zero_pos = -1;
-	v6stat.zero_cnt = 0;
-	/* Treat the IPv6 representation as a list of values
-	 * separated by ':'. The presence of a '::' will parse
- 	 * as one, two or three zero length elements.
-	 */
-	if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
-		return 0;
+{
+    IPV6_STAT v6stat;
+    v6stat.total = 0;
+    v6stat.zero_pos = -1;
+    v6stat.zero_cnt = 0;
+    /*
+     * Treat the IPv6 representation as a list of values separated by ':'.
+     * The presence of a '::' will parse as one, two or three zero length
+     * elements.
+     */
+    if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
+        return 0;
 
-	/* Now for some sanity checks */
+    /* Now for some sanity checks */
 
-	if (v6stat.zero_pos == -1)
-		{
-		/* If no '::' must have exactly 16 bytes */
-		if (v6stat.total != 16)
-			return 0;
-		}
-	else 
-		{
-		/* If '::' must have less than 16 bytes */
-		if (v6stat.total == 16)
-			return 0;
-		/* More than three zeroes is an error */
-		if (v6stat.zero_cnt > 3)
-			return 0;
-		/* Can only have three zeroes if nothing else present */
-		else if (v6stat.zero_cnt == 3)
-			{
-			if (v6stat.total > 0)
-				return 0;
-			}
-		/* Can only have two zeroes if at start or end */
-		else if (v6stat.zero_cnt == 2)
-			{
-			if ((v6stat.zero_pos != 0)
-				&& (v6stat.zero_pos != v6stat.total))
-				return 0;
-			}
-		else 
-		/* Can only have one zero if *not* start or end */
-			{
-			if ((v6stat.zero_pos == 0)
-				|| (v6stat.zero_pos == v6stat.total))
-				return 0;
-			}
-		}
+    if (v6stat.zero_pos == -1) {
+        /* If no '::' must have exactly 16 bytes */
+        if (v6stat.total != 16)
+            return 0;
+    } else {
+        /* If '::' must have less than 16 bytes */
+        if (v6stat.total == 16)
+            return 0;
+        /* More than three zeroes is an error */
+        if (v6stat.zero_cnt > 3)
+            return 0;
+        /* Can only have three zeroes if nothing else present */
+        else if (v6stat.zero_cnt == 3) {
+            if (v6stat.total > 0)
+                return 0;
+        }
+        /* Can only have two zeroes if at start or end */
+        else if (v6stat.zero_cnt == 2) {
+            if ((v6stat.zero_pos != 0)
+                && (v6stat.zero_pos != v6stat.total))
+                return 0;
+        } else
+            /* Can only have one zero if *not* start or end */
+        {
+            if ((v6stat.zero_pos == 0)
+                || (v6stat.zero_pos == v6stat.total))
+                return 0;
+        }
+    }
 
-	/* Format result */
+    /* Format result */
 
-	if (v6stat.zero_pos >= 0)
-		{
-		/* Copy initial part */
-		memcpy(v6, v6stat.tmp, v6stat.zero_pos);
-		/* Zero middle */
-		memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
-		/* Copy final part */
-		if (v6stat.total != v6stat.zero_pos)
-			memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
-				v6stat.tmp + v6stat.zero_pos,
-				v6stat.total - v6stat.zero_pos);
-		}
-	else
-		memcpy(v6, v6stat.tmp, 16);
+    if (v6stat.zero_pos >= 0) {
+        /* Copy initial part */
+        memcpy(v6, v6stat.tmp, v6stat.zero_pos);
+        /* Zero middle */
+        memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
+        /* Copy final part */
+        if (v6stat.total != v6stat.zero_pos)
+            memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+                   v6stat.tmp + v6stat.zero_pos,
+                   v6stat.total - v6stat.zero_pos);
+    } else
+        memcpy(v6, v6stat.tmp, 16);
 
-	return 1;
-	}
+    return 1;
+}
 
 static int ipv6_cb(const char *elem, int len, void *usr)
-	{
-	IPV6_STAT *s = usr;
-	/* Error if 16 bytes written */
-	if (s->total == 16)
-		return 0;
-	if (len == 0)
-		{
-		/* Zero length element, corresponds to '::' */
-		if (s->zero_pos == -1)
-			s->zero_pos = s->total;
-		/* If we've already got a :: its an error */
-		else if (s->zero_pos != s->total)
-			return 0;
-		s->zero_cnt++;
-		}
-	else 
-		{
-		/* If more than 4 characters could be final a.b.c.d form */
-		if (len > 4)
-			{
-			/* Need at least 4 bytes left */
-			if (s->total > 12)
-				return 0;
-			/* Must be end of string */
-			if (elem[len])
-				return 0;
-			if (!ipv4_from_asc(s->tmp + s->total, elem))
-				return 0;
-			s->total += 4;
-			}
-		else
-			{
-			if (!ipv6_hex(s->tmp + s->total, elem, len))
-				return 0;
-			s->total += 2;
-			}
-		}
-	return 1;
-	}
+{
+    IPV6_STAT *s = usr;
+    /* Error if 16 bytes written */
+    if (s->total == 16)
+        return 0;
+    if (len == 0) {
+        /* Zero length element, corresponds to '::' */
+        if (s->zero_pos == -1)
+            s->zero_pos = s->total;
+        /* If we've already got a :: its an error */
+        else if (s->zero_pos != s->total)
+            return 0;
+        s->zero_cnt++;
+    } else {
+        /* If more than 4 characters could be final a.b.c.d form */
+        if (len > 4) {
+            /* Need at least 4 bytes left */
+            if (s->total > 12)
+                return 0;
+            /* Must be end of string */
+            if (elem[len])
+                return 0;
+            if (!ipv4_from_asc(s->tmp + s->total, elem))
+                return 0;
+            s->total += 4;
+        } else {
+            if (!ipv6_hex(s->tmp + s->total, elem, len))
+                return 0;
+            s->total += 2;
+        }
+    }
+    return 1;
+}
 
-/* Convert a string of up to 4 hex digits into the corresponding
- * IPv6 form.
+/*
+ * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
  */
 
 static int ipv6_hex(unsigned char *out, const char *in, int inlen)
-	{
-	unsigned char c;
-	unsigned int num = 0;
-	if (inlen > 4)
-		return 0;
-	while(inlen--)
-		{
-		c = *in++;
-		num <<= 4;
-		if ((c >= '0') && (c <= '9'))
-			num |= c - '0';
-		else if ((c >= 'A') && (c <= 'F'))
-			num |= c - 'A' + 10;
-		else if ((c >= 'a') && (c <= 'f'))
-			num |=  c - 'a' + 10;
-		else
-			return 0;
-		}
-	out[0] = num >> 8;
-	out[1] = num & 0xff;
-	return 1;
-	}
+{
+    unsigned char c;
+    unsigned int num = 0;
+    if (inlen > 4)
+        return 0;
+    while (inlen--) {
+        c = *in++;
+        num <<= 4;
+        if ((c >= '0') && (c <= '9'))
+            num |= c - '0';
+        else if ((c >= 'A') && (c <= 'F'))
+            num |= c - 'A' + 10;
+        else if ((c >= 'a') && (c <= 'f'))
+            num |= c - 'a' + 10;
+        else
+            return 0;
+    }
+    out[0] = num >> 8;
+    out[1] = num & 0xff;
+    return 1;
+}
 
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF (CONF_VALUE) * dn_sk,
+                             unsigned long chtype)
+{
+    CONF_VALUE *v;
+    int mval;
+    size_t i;
+    char *p, *type;
+    if (!nm)
+        return 0;
 
-int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
-						unsigned long chtype)
-	{
-	CONF_VALUE *v;
-	int mval;
-	size_t i;
-	char *p, *type;
-	if (!nm)
-		return 0;
+    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
+        v = sk_CONF_VALUE_value(dn_sk, i);
+        type = v->name;
+        /*
+         * Skip past any leading X. X: X, etc to allow for multiple instances
+         */
+        for (p = type; *p; p++)
+            if ((*p == ':') || (*p == ',') || (*p == '.')) {
+                p++;
+                if (*p)
+                    type = p;
+                break;
+            }
+        if (*type == '+') {
+            mval = -1;
+            type++;
+        } else
+            mval = 0;
+        if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
+                                        (unsigned char *)v->value, -1, -1,
+                                        mval))
+            return 0;
 
-	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
-		{
-		v=sk_CONF_VALUE_value(dn_sk,i);
-		type=v->name;
-		/* Skip past any leading X. X: X, etc to allow for
-		 * multiple instances 
-		 */
-		for(p = type; *p ; p++) 
-			if ((*p == ':') || (*p == ',') || (*p == '.'))
-				{
-				p++;
-				if(*p) type = p;
-				break;
-				}
-		if (*type == '+')
-			{
-			mval = -1;
-			type++;
-			}
-		else
-			mval = 0;
-		if (!X509_NAME_add_entry_by_txt(nm,type, chtype,
-				(unsigned char *) v->value,-1,-1,mval))
-					return 0;
-
-		}
-	return 1;
-	}
+    }
+    return 1;
+}
diff --git a/src/crypto/x509v3/v3name_test.c b/src/crypto/x509v3/v3name_test.c
index f9f7087..dadf488 100644
--- a/src/crypto/x509v3/v3name_test.c
+++ b/src/crypto/x509v3/v3name_test.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
 /* ====================================================================
  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
  *
@@ -8,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -60,363 +62,349 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
+static const char *const names[] = {
+    "a", "b", ".", "*", "@",
+    ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
+    "-example.com", "example-.com",
+    "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
+    "*@example.com", "test@*.example.com", "example.com", "www.example.com",
+    "test.www.example.com", "*.example.com", "*.www.example.com",
+    "test.*.example.com", "www.*.com",
+    ".www.example.com", "*www.example.com",
+    "example.net", "xn--rger-koa.example.com",
+    "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com",
+    "*.good--example.com", "www.good--example.com",
+    "*.xn--bar.com", "xn--foo.xn--bar.com",
+    "a.example.com", "b.example.com",
+    "postmaster@example.com", "Postmaster@example.com",
+    "postmaster@EXAMPLE.COM",
+    NULL
+};
 
-static const char *const names[] =
-	{
-	"a", "b", ".", "*", "@",
-	".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
-	"@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
-	"*@example.com", "test@*.example.com", "example.com", "www.example.com",
-	"test.www.example.com", "*.example.com", "*.www.example.com",
-	"test.*.example.com", "www.*.com",
-	".www.example.com", "*www.example.com",
-	"example.net", "xn--rger-koa.example.com",
-	"a.example.com", "b.example.com",
-	"postmaster@example.com", "Postmaster@example.com",
-	"postmaster@EXAMPLE.COM",
-	NULL
-	};
-
-static const char *const exceptions[] =
-	{
-	"set CN: host: [*.example.com] matches [a.example.com]",
-	"set CN: host: [*.example.com] matches [b.example.com]",
-	"set CN: host: [*.example.com] matches [www.example.com]",
-	"set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
-	"set CN: host: [*.www.example.com] matches [test.www.example.com]",
-	"set CN: host: [*.www.example.com] matches [.www.example.com]",
-	"set CN: host: [*www.example.com] matches [www.example.com]",
-	"set CN: host: [test.www.example.com] matches [.www.example.com]",
-	"set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
-	"set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
-	"set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
-	"set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
-	"set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
-	"set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
-	"set dnsName: host: [*.example.com] matches [www.example.com]",
-	"set dnsName: host: [*.example.com] matches [a.example.com]",
-	"set dnsName: host: [*.example.com] matches [b.example.com]",
-	"set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
-	"set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
-	"set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
-	"set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
-	"set dnsName: host: [*.www.example.com] matches [.www.example.com]",
-	"set dnsName: host: [*www.example.com] matches [www.example.com]",
-	"set dnsName: host: [test.www.example.com] matches [.www.example.com]",
-	"set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
-	"set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
-	"set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
-	"set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
-	NULL
-	};
+static const char *const exceptions[] = {
+    "set CN: host: [*.example.com] matches [a.example.com]",
+    "set CN: host: [*.example.com] matches [b.example.com]",
+    "set CN: host: [*.example.com] matches [www.example.com]",
+    "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
+    "set CN: host: [*.www.example.com] matches [test.www.example.com]",
+    "set CN: host: [*.www.example.com] matches [.www.example.com]",
+    "set CN: host: [*www.example.com] matches [www.example.com]",
+    "set CN: host: [test.www.example.com] matches [.www.example.com]",
+    "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
+    "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
+    "set CN: host: [*.good--example.com] matches [www.good--example.com]",
+    "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
+    "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
+    "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
+    "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
+    "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
+    "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
+    "set dnsName: host: [*.example.com] matches [www.example.com]",
+    "set dnsName: host: [*.example.com] matches [a.example.com]",
+    "set dnsName: host: [*.example.com] matches [b.example.com]",
+    "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
+    "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
+    "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
+    "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
+    "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
+    "set dnsName: host: [*www.example.com] matches [www.example.com]",
+    "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
+    "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
+    "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
+    "set dnsName: host: [*.good--example.com] matches [www.good--example.com]",
+    "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
+    "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
+    "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
+    "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
+    NULL
+};
 
 static int is_exception(const char *msg)
-	{
-	const char *const *p;
-	for (p = exceptions; *p; ++p)
-		if (strcmp(msg, *p) == 0)
-			return 1;
-	return 0;
-	}
+{
+    const char *const *p;
+    for (p = exceptions; *p; ++p)
+        if (strcmp(msg, *p) == 0)
+            return 1;
+    return 0;
+}
 
 static int set_cn(X509 *crt, ...)
-	{
-	int ret = 0;
-	X509_NAME *n = NULL;
-	va_list ap;
-	va_start(ap, crt);
-	n = X509_NAME_new();
-	if (n == NULL)
-		goto out;
-	while (1) {
-		int nid;
-		const char *name;
-		nid = va_arg(ap, int);
-		if (nid == 0)
-			break;
-		name = va_arg(ap, const char *);
-		if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
-							(unsigned char *)name,
-						-1, -1, 1))
-			goto out;
-	}
-	if (!X509_set_subject_name(crt, n))
-		goto out;
-	ret = 1;
+{
+    int ret = 0;
+    X509_NAME *n = NULL;
+    va_list ap;
+    va_start(ap, crt);
+    n = X509_NAME_new();
+    if (n == NULL)
+        goto out;
+    while (1) {
+        int nid;
+        const char *name;
+        nid = va_arg(ap, int);
+        if (nid == 0)
+            break;
+        name = va_arg(ap, const char *);
+        if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
+                                        (unsigned char *)name, -1, -1, 1))
+            goto out;
+    }
+    if (!X509_set_subject_name(crt, n))
+        goto out;
+    ret = 1;
  out:
-	X509_NAME_free(n);
-	va_end(ap);
-	return ret;
-	}
+    X509_NAME_free(n);
+    va_end(ap);
+    return ret;
+}
 
 /*
-int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
-			int nid, int crit, ASN1_OCTET_STRING *data);
-int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-*/
+ * int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); X509_EXTENSION
+ * *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit,
+ * ASN1_OCTET_STRING *data); int X509_add_ext(X509 *x, X509_EXTENSION *ex,
+ * int loc);
+ */
 
 static int set_altname(X509 *crt, ...)
-	{
-	int ret = 0;
-	GENERAL_NAMES *gens = NULL;
-	GENERAL_NAME *gen = NULL;
-	ASN1_IA5STRING *ia5 = NULL;
-	va_list ap;
-	va_start(ap, crt);
-	gens = sk_GENERAL_NAME_new_null();
-	if (gens == NULL)
-		goto out;
-	while (1) {
-		int type;
-		const char *name;
-		type = va_arg(ap, int);
-		if (type == 0)
-			break;
-		name = va_arg(ap, const char *);
+{
+    int ret = 0;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    ASN1_IA5STRING *ia5 = NULL;
+    va_list ap;
+    va_start(ap, crt);
+    gens = sk_GENERAL_NAME_new_null();
+    if (gens == NULL)
+        goto out;
+    while (1) {
+        int type;
+        const char *name;
+        type = va_arg(ap, int);
+        if (type == 0)
+            break;
+        name = va_arg(ap, const char *);
 
-		gen = GENERAL_NAME_new();
-		if (gen == NULL)
-			goto out;
-		ia5 = ASN1_IA5STRING_new();
-		if (ia5 == NULL)
-			goto out;
-		if (!ASN1_STRING_set(ia5, name, -1))
-			goto out;
-		switch (type)
-			{
-			case GEN_EMAIL:
-			case GEN_DNS:
-				GENERAL_NAME_set0_value(gen, type, ia5);
-				ia5 = NULL;
-				break;
-			default:
-				abort();
-			}
-		sk_GENERAL_NAME_push(gens, gen);
-		gen = NULL;
-	}
-	if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
-		goto out;
-	ret = 1;
+        gen = GENERAL_NAME_new();
+        if (gen == NULL)
+            goto out;
+        ia5 = ASN1_IA5STRING_new();
+        if (ia5 == NULL)
+            goto out;
+        if (!ASN1_STRING_set(ia5, name, -1))
+            goto out;
+        switch (type) {
+        case GEN_EMAIL:
+        case GEN_DNS:
+            GENERAL_NAME_set0_value(gen, type, ia5);
+            ia5 = NULL;
+            break;
+        default:
+            abort();
+        }
+        sk_GENERAL_NAME_push(gens, gen);
+        gen = NULL;
+    }
+    if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
+        goto out;
+    ret = 1;
  out:
-	ASN1_IA5STRING_free(ia5);
-	GENERAL_NAME_free(gen);
-	GENERAL_NAMES_free(gens);
-	va_end(ap);
-	return ret;
-	}
+    ASN1_IA5STRING_free(ia5);
+    GENERAL_NAME_free(gen);
+    GENERAL_NAMES_free(gens);
+    va_end(ap);
+    return ret;
+}
 
 static int set_cn1(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_commonName, name, 0);
-	}
-
+{
+    return set_cn(crt, NID_commonName, name, 0);
+}
 
 static int set_cn_and_email(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_commonName, name,
-		      NID_pkcs9_emailAddress, "dummy@example.com", 0);
-	}
+{
+    return set_cn(crt, NID_commonName, name,
+                  NID_pkcs9_emailAddress, "dummy@example.com", 0);
+}
 
 static int set_cn2(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_commonName, "dummy value",
-		      NID_commonName, name, 0);
-	}
+{
+    return set_cn(crt, NID_commonName, "dummy value",
+                  NID_commonName, name, 0);
+}
 
 static int set_cn3(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_commonName, name,
-		      NID_commonName, "dummy value", 0);
-	}
+{
+    return set_cn(crt, NID_commonName, name,
+                  NID_commonName, "dummy value", 0);
+}
 
 static int set_email1(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
-	}
+{
+    return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
+}
 
 static int set_email2(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
-		      NID_pkcs9_emailAddress, name, 0);
-	}
+{
+    return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
+                  NID_pkcs9_emailAddress, name, 0);
+}
 
 static int set_email3(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_pkcs9_emailAddress, name,
-		      NID_pkcs9_emailAddress, "dummy@example.com", 0);
-	}
+{
+    return set_cn(crt, NID_pkcs9_emailAddress, name,
+                  NID_pkcs9_emailAddress, "dummy@example.com", 0);
+}
 
 static int set_email_and_cn(X509 *crt, const char *name)
-	{
-	return set_cn(crt, NID_pkcs9_emailAddress, name,
-		      NID_commonName, "www.example.org", 0);
-	}
+{
+    return set_cn(crt, NID_pkcs9_emailAddress, name,
+                  NID_commonName, "www.example.org", 0);
+}
 
 static int set_altname_dns(X509 *crt, const char *name)
-	{
-	return set_altname(crt, GEN_DNS, name, 0);
-	}
+{
+    return set_altname(crt, GEN_DNS, name, 0);
+}
 
 static int set_altname_email(X509 *crt, const char *name)
-	{
-	return set_altname(crt, GEN_EMAIL, name, 0);
-	}
+{
+    return set_altname(crt, GEN_EMAIL, name, 0);
+}
 
-struct set_name_fn
-	{
-	int (*fn)(X509 *, const char *);
-	const char *name;
-	int host;
-	int email;
-	};
+struct set_name_fn {
+    int (*fn) (X509 *, const char *);
+    const char *name;
+    int host;
+    int email;
+};
 
-static const struct set_name_fn name_fns[] =
-	{
-	{set_cn1, "set CN", 1, 0},
-	{set_cn2, "set CN", 1, 0},
-	{set_cn3, "set CN", 1, 0},
-	{set_cn_and_email, "set CN", 1, 0},
-	{set_email1, "set emailAddress", 0, 1},
-	{set_email2, "set emailAddress", 0, 1},
-	{set_email3, "set emailAddress", 0, 1},
-	{set_email_and_cn, "set emailAddress", 0, 1},
-	{set_altname_dns, "set dnsName", 1, 0},
-	{set_altname_email, "set rfc822Name", 0, 1},
-	{NULL, NULL, 0, 0},
-	};
+static const struct set_name_fn name_fns[] = {
+    {set_cn1, "set CN", 1, 0},
+    {set_cn2, "set CN", 1, 0},
+    {set_cn3, "set CN", 1, 0},
+    {set_cn_and_email, "set CN", 1, 0},
+    {set_email1, "set emailAddress", 0, 1},
+    {set_email2, "set emailAddress", 0, 1},
+    {set_email3, "set emailAddress", 0, 1},
+    {set_email_and_cn, "set emailAddress", 0, 1},
+    {set_altname_dns, "set dnsName", 1, 0},
+    {set_altname_email, "set rfc822Name", 0, 1},
+    {NULL, NULL, 0, 0},
+};
 
 static X509 *make_cert(void)
-	{
-	X509 *ret = NULL;
-	X509 *crt = NULL;
-	X509_NAME *issuer = NULL;
-	crt = X509_new();
-	if (crt == NULL)
-		goto out;
-	if (!X509_set_version(crt, 3))
-		goto out;
-	ret = crt;
-	crt = NULL;
+{
+    X509 *ret = NULL;
+    X509 *crt = NULL;
+    X509_NAME *issuer = NULL;
+    crt = X509_new();
+    if (crt == NULL)
+        goto out;
+    if (!X509_set_version(crt, 3))
+        goto out;
+    ret = crt;
+    crt = NULL;
  out:
-	X509_NAME_free(issuer);
-	return ret;
-	}
+    X509_NAME_free(issuer);
+    return ret;
+}
 
 static int errors;
 
 static void check_message(const struct set_name_fn *fn, const char *op,
-			  const char *nameincert, int match, const char *name)
-	{
-	char msg[1024];
-	if (match < 0)
-		return;
-	BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
-		 fn->name, op, nameincert,
-		 match ? "matches" : "does not match", name);
-	if (is_exception(msg))
-		return;
-	puts(msg);
-	++errors;
-	}
+                          const char *nameincert, int match, const char *name)
+{
+    char msg[1024];
+    if (match < 0)
+        return;
+    BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
+                 fn->name, op, nameincert,
+                 match ? "matches" : "does not match", name);
+    if (is_exception(msg))
+        return;
+    puts(msg);
+    ++errors;
+}
 
 static void run_cert(X509 *crt, const char *nameincert,
-		     const struct set_name_fn *fn)
-	{
-	const char *const *pname = names;
-	while (*pname)
-		{
-		int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
-		size_t namelen = strlen(*pname);
-		char *name = malloc(namelen);
-		int match, ret;
-		memcpy(name, *pname, namelen);
+                     const struct set_name_fn *fn)
+{
+    const char *const *pname = names;
+    while (*pname) {
+        int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
+        size_t namelen = strlen(*pname);
+        char *name = malloc(namelen);
+        int match, ret;
+        memcpy(name, *pname, namelen);
 
-		ret = X509_check_host(crt, name, namelen, 0, NULL);
-		match = -1;
-		if (ret < 0)
-			{
-			fprintf(stderr, "internal error in X509_check_host");
-			++errors;
-			}
-		else if (fn->host)
-			{
-			if (ret == 1 && !samename)
-				match = 1;
-			if (ret == 0 && samename)
-				match = 0;
-			}
-		else if (ret == 1)
-			match = 1;
-		check_message(fn, "host", nameincert, match, *pname);
+        ret = X509_check_host(crt, name, namelen, 0, NULL);
+        match = -1;
+        if (ret < 0) {
+            fprintf(stderr, "internal error in X509_check_host");
+            ++errors;
+        } else if (fn->host) {
+            if (ret == 1 && !samename)
+                match = 1;
+            if (ret == 0 && samename)
+                match = 0;
+        } else if (ret == 1)
+            match = 1;
+        check_message(fn, "host", nameincert, match, *pname);
 
-		ret = X509_check_host(crt, name, namelen,
-				      X509_CHECK_FLAG_NO_WILDCARDS, NULL);
-		match = -1;
-		if (ret < 0)
-			{
-			fprintf(stderr, "internal error in X509_check_host");
-			++errors;
-			}
-		else if (fn->host)
-			{
-			if (ret == 1 && !samename)
-				match = 1;
-			if (ret == 0 && samename)
-				match = 0;
-			}
-		else if (ret == 1)
-			match = 1;
-		check_message(fn, "host-no-wildcards",
-			      nameincert, match, *pname);
+        ret = X509_check_host(crt, name, namelen,
+                              X509_CHECK_FLAG_NO_WILDCARDS, NULL);
+        match = -1;
+        if (ret < 0) {
+            fprintf(stderr, "internal error in X509_check_host");
+            ++errors;
+        } else if (fn->host) {
+            if (ret == 1 && !samename)
+                match = 1;
+            if (ret == 0 && samename)
+                match = 0;
+        } else if (ret == 1)
+            match = 1;
+        check_message(fn, "host-no-wildcards", nameincert, match, *pname);
 
-		ret = X509_check_email(crt, name, namelen, 0);
-		match = -1;
-		if (fn->email)
-			{
-			if (ret && !samename)
-				match = 1;
-			if (!ret && samename && strchr(nameincert, '@') != NULL)
-				match = 0;
-			}
-		else if (ret)
-			match = 1;
-		check_message(fn, "email", nameincert, match, *pname);
-		++pname;
-		free(name);
-		}
-	}
+        ret = X509_check_email(crt, name, namelen, 0);
+        match = -1;
+        if (fn->email) {
+            if (ret && !samename)
+                match = 1;
+            if (!ret && samename && strchr(nameincert, '@') != NULL)
+                match = 0;
+        } else if (ret)
+            match = 1;
+        check_message(fn, "email", nameincert, match, *pname);
+        ++pname;
+        free(name);
+    }
+}
 
-int
-main(void)
-	{
-	CRYPTO_library_init();
+int main(void)
+{
+    CRYPTO_library_init();
 
-	const struct set_name_fn *pfn = name_fns;
-	while (pfn->name) {
-		const char *const *pname = names;
-		while (*pname)
-			{
-			X509 *crt = make_cert();
-			if (crt == NULL)
-				{
-				fprintf(stderr, "make_cert failed\n");
-				return 1;
-				}
-			if (!pfn->fn(crt, *pname))
-				{
-				fprintf(stderr, "X509 name setting failed\n");
-				return 1;
-				}
-			run_cert(crt, *pname, pfn);
-			X509_free(crt);
-			++pname;
-			}
-		++pfn;
-	}
-	if (errors == 0) {
-	  printf("PASS\n");
-	}
-	return errors > 0 ? 1 : 0;
-	}
+    const struct set_name_fn *pfn = name_fns;
+    while (pfn->name) {
+        const char *const *pname = names;
+        while (*pname) {
+            X509 *crt = make_cert();
+            if (crt == NULL) {
+                fprintf(stderr, "make_cert failed\n");
+                return 1;
+            }
+            if (!pfn->fn(crt, *pname)) {
+                fprintf(stderr, "X509 name setting failed\n");
+                return 1;
+            }
+            run_cert(crt, *pname, pfn);
+            X509_free(crt);
+            ++pname;
+        }
+        ++pfn;
+    }
+    if (errors == 0) {
+        printf("PASS\n");
+    }
+    return errors > 0 ? 1 : 0;
+}
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index 0773f9a..6a5462c 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -2,7 +2,15 @@
 add_subdirectory(blowfish)
 add_subdirectory(cast)
 add_subdirectory(des)
+add_subdirectory(dh)
+add_subdirectory(dsa)
+add_subdirectory(evp)
+add_subdirectory(obj)
+add_subdirectory(rc4)
+add_subdirectory(ripemd)
 add_subdirectory(rsa)
+add_subdirectory(ssl)
+add_subdirectory(x509)
 add_subdirectory(xts)
 
 add_library(
@@ -12,8 +20,16 @@
   $<TARGET_OBJECTS:blowfish>
   $<TARGET_OBJECTS:cast>
   $<TARGET_OBJECTS:des_decrepit>
+  $<TARGET_OBJECTS:dh_decrepit>
+  $<TARGET_OBJECTS:dsa_decrepit>
+  $<TARGET_OBJECTS:evp_decrepit>
+  $<TARGET_OBJECTS:obj_decrepit>
+  $<TARGET_OBJECTS:rc4_decrepit>
+  $<TARGET_OBJECTS:ripemd_decrepit>
   $<TARGET_OBJECTS:rsa_decrepit>
+  $<TARGET_OBJECTS:ssl_decrepit>
+  $<TARGET_OBJECTS:x509_decrepit>
   $<TARGET_OBJECTS:xts>
 )
 
-target_link_libraries(decrepit crypto)
+target_link_libraries(decrepit crypto ssl)
diff --git a/src/decrepit/dh/CMakeLists.txt b/src/decrepit/dh/CMakeLists.txt
new file mode 100644
index 0000000..fb862b5
--- /dev/null
+++ b/src/decrepit/dh/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  dh_decrepit
+
+  OBJECT
+
+  dh_decrepit.c
+)
diff --git a/src/decrepit/dh/dh_decrepit.c b/src/decrepit/dh/dh_decrepit.c
new file mode 100644
index 0000000..1d38c12
--- /dev/null
+++ b/src/decrepit/dh/dh_decrepit.c
@@ -0,0 +1,103 @@
+/* ====================================================================
+ * Copyright (c) 1998-2002 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). */
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+
+struct wrapped_callback {
+  void (*callback)(int, int, void *);
+  void *arg;
+};
+
+/* callback_wrapper converts an “old” style generation callback to the newer
+ * |BN_GENCB| form. */
+static int callback_wrapper(int event, int n, BN_GENCB *gencb) {
+  struct wrapped_callback *wrapped = (struct wrapped_callback *) gencb->arg;
+  wrapped->callback(event, n, wrapped->arg);
+  return 1;
+}
+
+DH *DH_generate_parameters(int prime_len, int generator,
+                           void (*callback)(int, int, void *), void *cb_arg) {
+  if (prime_len < 0 || generator < 0) {
+      return NULL;
+  }
+
+  DH *ret = DH_new();
+  if (ret == NULL) {
+      return NULL;
+  }
+
+  BN_GENCB gencb_storage;
+  BN_GENCB *cb = NULL;
+
+  struct wrapped_callback wrapped;
+
+  if (callback != NULL) {
+    wrapped.callback = callback;
+    wrapped.arg = cb_arg;
+
+    cb = &gencb_storage;
+    BN_GENCB_set(cb, callback_wrapper, &wrapped);
+  }
+
+  if (!DH_generate_parameters_ex(ret, prime_len, generator, cb)) {
+    goto err;
+  }
+
+  return ret;
+
+err:
+  DH_free(ret);
+  return NULL;
+}
diff --git a/src/decrepit/dsa/CMakeLists.txt b/src/decrepit/dsa/CMakeLists.txt
new file mode 100644
index 0000000..cc64b60
--- /dev/null
+++ b/src/decrepit/dsa/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  dsa_decrepit
+
+  OBJECT
+
+  dsa_decrepit.c
+)
diff --git a/src/decrepit/dsa/dsa_decrepit.c b/src/decrepit/dsa/dsa_decrepit.c
new file mode 100644
index 0000000..aef8056
--- /dev/null
+++ b/src/decrepit/dsa/dsa_decrepit.c
@@ -0,0 +1,105 @@
+/* ====================================================================
+ * Copyright (c) 1998-2002 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). */
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+
+
+struct wrapped_callback {
+  void (*callback)(int, int, void *);
+  void *arg;
+};
+
+/* callback_wrapper converts an “old” style generation callback to the newer
+ * |BN_GENCB| form. */
+static int callback_wrapper(int event, int n, BN_GENCB *gencb) {
+  struct wrapped_callback *wrapped = (struct wrapped_callback *) gencb->arg;
+  wrapped->callback(event, n, wrapped->arg);
+  return 1;
+}
+
+DSA *DSA_generate_parameters(int bits, uint8_t *seed_in, int seed_len,
+                             int *counter_ret, unsigned long *h_ret,
+                             void (*callback)(int, int, void *), void *cb_arg) {
+  if (bits < 0 || seed_len < 0) {
+      return NULL;
+  }
+
+  DSA *ret = DSA_new();
+  if (ret == NULL) {
+      return NULL;
+  }
+
+  BN_GENCB gencb_storage;
+  BN_GENCB *cb = NULL;
+
+  struct wrapped_callback wrapped;
+
+  if (callback != NULL) {
+    wrapped.callback = callback;
+    wrapped.arg = cb_arg;
+
+    cb = &gencb_storage;
+    BN_GENCB_set(cb, callback_wrapper, &wrapped);
+  }
+
+  if (!DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, counter_ret,
+                                  h_ret, cb)) {
+    goto err;
+  }
+
+  return ret;
+
+err:
+  DSA_free(ret);
+  return NULL;
+}
diff --git a/src/decrepit/evp/CMakeLists.txt b/src/decrepit/evp/CMakeLists.txt
new file mode 100644
index 0000000..ee3bf33
--- /dev/null
+++ b/src/decrepit/evp/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  evp_decrepit
+
+  OBJECT
+
+  evp_do_all.c
+)
diff --git a/src/decrepit/evp/evp_do_all.c b/src/decrepit/evp/evp_do_all.c
new file mode 100644
index 0000000..621c0b1
--- /dev/null
+++ b/src/decrepit/evp/evp_do_all.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/evp.h>
+
+
+void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
+                                               const char *name,
+                                               const char *unused, void *arg),
+                              void *arg) {
+  callback(EVP_aes_128_cbc(), "AES-128-CBC", NULL, arg);
+  callback(EVP_aes_128_ctr(), "AES-128-CTR", NULL, arg);
+  callback(EVP_aes_128_ecb(), "AES-128-ECB", NULL, arg);
+  callback(EVP_aes_128_ofb(), "AES-128-OFB", NULL, arg);
+  callback(EVP_aes_256_cbc(), "AES-256-CBC", NULL, arg);
+  callback(EVP_aes_256_ctr(), "AES-256-CTR", NULL, arg);
+  callback(EVP_aes_256_ecb(), "AES-256-ECB", NULL, arg);
+  callback(EVP_aes_256_ofb(), "AES-256-OFB", NULL, arg);
+  callback(EVP_aes_256_xts(), "AES-256-XTS", NULL, arg);
+  callback(EVP_des_cbc(), "DES-CBC", NULL, arg);
+  callback(EVP_des_ecb(), "DES-ECB", NULL, arg);
+  callback(EVP_des_ede(), "DES-EDE", NULL, arg);
+  callback(EVP_des_ede_cbc(), "DES-EDE-CBC", NULL, arg);
+  callback(EVP_des_ede3_cbc(), "DES-EDE3-CBC", NULL, arg);
+  callback(EVP_rc2_cbc(), "RC2-CBC", NULL, arg);
+  callback(EVP_rc4(), "RC4", NULL, arg);
+
+  /* OpenSSL returns everything twice, the second time in lower case. */
+  callback(EVP_aes_128_cbc(), "aes-128-cbc", NULL, arg);
+  callback(EVP_aes_128_ctr(), "aes-128-ctr", NULL, arg);
+  callback(EVP_aes_128_ecb(), "aes-128-ecb", NULL, arg);
+  callback(EVP_aes_128_ofb(), "aes-128-ofb", NULL, arg);
+  callback(EVP_aes_256_cbc(), "aes-256-cbc", NULL, arg);
+  callback(EVP_aes_256_ctr(), "aes-256-ctr", NULL, arg);
+  callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
+  callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
+  callback(EVP_aes_256_xts(), "aes-256-xts", NULL, arg);
+  callback(EVP_des_cbc(), "des-cbc", NULL, arg);
+  callback(EVP_des_ecb(), "des-ecb", NULL, arg);
+  callback(EVP_des_ede(), "des-ede", NULL, arg);
+  callback(EVP_des_ede_cbc(), "des-ede-cbc", NULL, arg);
+  callback(EVP_des_ede3_cbc(), "des-ede3-cbc", NULL, arg);
+  callback(EVP_rc2_cbc(), "rc2-cbc", NULL, arg);
+  callback(EVP_rc4(), "rc4", NULL, arg);
+}
+
+void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
+                                           const char *name, const char *unused,
+                                           void *arg),
+                          void *arg) {
+  callback(EVP_md4(), "MD4", NULL, arg);
+  callback(EVP_md5(), "MD5", NULL, arg);
+  callback(EVP_sha1(), "SHA1", NULL, arg);
+  callback(EVP_sha224(), "SHA224", NULL, arg);
+  callback(EVP_sha256(), "SHA256", NULL, arg);
+  callback(EVP_sha384(), "SHA384", NULL, arg);
+  callback(EVP_sha512(), "SHA512", NULL, arg);
+
+  callback(EVP_md4(), "md4", NULL, arg);
+  callback(EVP_md5(), "md5", NULL, arg);
+  callback(EVP_sha1(), "sha1", NULL, arg);
+  callback(EVP_sha224(), "sha224", NULL, arg);
+  callback(EVP_sha256(), "sha256", NULL, arg);
+  callback(EVP_sha384(), "sha384", NULL, arg);
+  callback(EVP_sha512(), "sha512", NULL, arg);
+}
diff --git a/src/decrepit/obj/CMakeLists.txt b/src/decrepit/obj/CMakeLists.txt
new file mode 100644
index 0000000..caaecd3
--- /dev/null
+++ b/src/decrepit/obj/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  obj_decrepit
+
+  OBJECT
+
+  obj_decrepit.c
+)
diff --git a/src/decrepit/obj/obj_decrepit.c b/src/decrepit/obj/obj_decrepit.c
new file mode 100644
index 0000000..06051f1
--- /dev/null
+++ b/src/decrepit/obj/obj_decrepit.c
@@ -0,0 +1,71 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/obj.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+
+
+struct wrapped_callback {
+  void (*callback)(const OBJ_NAME *, void *arg);
+  void *arg;
+};
+
+static void cipher_callback(const EVP_CIPHER *cipher, const char *name,
+                            const char *unused, void *arg) {
+  const struct wrapped_callback *wrapped = (struct wrapped_callback *)arg;
+  OBJ_NAME obj_name;
+
+  memset(&obj_name, 0, sizeof(obj_name));
+  obj_name.type = OBJ_NAME_TYPE_CIPHER_METH;
+  obj_name.name = name;
+
+  wrapped->callback(&obj_name, wrapped->arg);
+}
+
+static void md_callback(const EVP_MD *md, const char *name, const char *unused,
+                        void *arg) {
+  const struct wrapped_callback *wrapped = (struct wrapped_callback*) arg;
+  OBJ_NAME obj_name;
+
+  memset(&obj_name, 0, sizeof(obj_name));
+  obj_name.type = OBJ_NAME_TYPE_MD_METH;
+  obj_name.name = name;
+
+  wrapped->callback(&obj_name, wrapped->arg);
+}
+
+void OBJ_NAME_do_all_sorted(int type,
+                            void (*callback)(const OBJ_NAME *, void *arg),
+                            void *arg) {
+  struct wrapped_callback wrapped;
+  wrapped.callback = callback;
+  wrapped.arg = arg;
+
+  if (type == OBJ_NAME_TYPE_CIPHER_METH) {
+    EVP_CIPHER_do_all_sorted(cipher_callback, &wrapped);
+  } else if (type == OBJ_NAME_TYPE_MD_METH) {
+    EVP_MD_do_all_sorted(md_callback, &wrapped);
+  } else {
+    assert(0);
+  }
+}
+
+void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, void *arg),
+                     void *arg) {
+  OBJ_NAME_do_all_sorted(type, callback, arg);
+}
diff --git a/src/decrepit/rc4/CMakeLists.txt b/src/decrepit/rc4/CMakeLists.txt
new file mode 100644
index 0000000..459b24e
--- /dev/null
+++ b/src/decrepit/rc4/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  rc4_decrepit
+
+  OBJECT
+
+  rc4_decrepit.c
+)
diff --git a/src/crypto/dsa/internal.h b/src/decrepit/rc4/rc4_decrepit.c
similarity index 86%
rename from src/crypto/dsa/internal.h
rename to src/decrepit/rc4/rc4_decrepit.c
index ef99158..140e15d 100644
--- a/src/crypto/dsa/internal.h
+++ b/src/decrepit/rc4/rc4_decrepit.c
@@ -52,27 +52,11 @@
  * 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.]
- *
- * The DSS routines are based on patches supplied by
- * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
+ * [including the GNU Public Licence.] */
 
-#ifndef OPENSSL_HEADER_DSA_INTERNAL_H
-#define OPENSSL_HEADER_DSA_INTERNAL_H
-
-#include <openssl/base.h>
-
-#include <openssl/bn.h>
-#include <openssl/ex_data.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
+#include <openssl/rc4.h>
 
 
-
-#if defined(__cplusplus)
-}  /* extern C */
-#endif
-
-#endif  /* OPENSSL_HEADER_DSA_INTERNAL_H */
+const char *RC4_options(void) {
+  return "rc4(ptr,int)";
+}
diff --git a/src/decrepit/ripemd/CMakeLists.txt b/src/decrepit/ripemd/CMakeLists.txt
new file mode 100644
index 0000000..0714a8f
--- /dev/null
+++ b/src/decrepit/ripemd/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(../../include)
+
+add_library(
+  ripemd_decrepit
+
+  OBJECT
+
+  ripemd.c
+)
+
+add_executable(
+  ripemd_test
+
+  ripemd_test.cc
+
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(ripemd_test crypto)
+target_link_libraries(ripemd_test decrepit)
+add_dependencies(all_tests ripemd_test)
diff --git a/src/decrepit/ripemd/internal.h b/src/decrepit/ripemd/internal.h
new file mode 100644
index 0000000..c4db4b2
--- /dev/null
+++ b/src/decrepit/ripemd/internal.h
@@ -0,0 +1,493 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_BN_INTERNAL_H
+#define OPENSSL_HEADER_BN_INTERNAL_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
+                                       size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG uint32_t
+#define HASH_CTX RIPEMD160_CTX
+#define HASH_CBLOCK RIPEMD160_CBLOCK
+#define HASH_UPDATE RIPEMD160_Update
+#define HASH_TRANSFORM RIPEMD160_Transform
+#define HASH_FINAL RIPEMD160_Final
+#define HASH_MAKE_STRING(c, s) \
+  do {                         \
+    unsigned long ll;          \
+    ll = (c)->h[0];            \
+    (void)HOST_l2c(ll, (s));   \
+    ll = (c)->h[1];            \
+    (void)HOST_l2c(ll, (s));   \
+    ll = (c)->h[2];            \
+    (void)HOST_l2c(ll, (s));   \
+    ll = (c)->h[3];            \
+    (void)HOST_l2c(ll, (s));   \
+    ll = (c)->h[4];            \
+    (void)HOST_l2c(ll, (s));   \
+  } while (0)
+#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
+
+#include "../../crypto/digest/md32_common.h"
+
+/* Transformed F2 and F4 are courtesy of Wei Dai <weidai@eskimo.com> */
+#define F1(x, y, z) ((x) ^ (y) ^ (z))
+#define F2(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
+#define F3(x, y, z) (((~(y)) | (x)) ^ (z))
+#define F4(x, y, z) ((((x) ^ (y)) & (z)) ^ (y))
+#define F5(x, y, z) (((~(z)) | (y)) ^ (x))
+
+#define RIPEMD160_A 0x67452301L
+#define RIPEMD160_B 0xEFCDAB89L
+#define RIPEMD160_C 0x98BADCFEL
+#define RIPEMD160_D 0x10325476L
+#define RIPEMD160_E 0xC3D2E1F0L
+
+#define ROTATE(a, n) (((a) << (n)) | (((a)&0xffffffff) >> (32 - (n))))
+
+#define RIP1(a, b, c, d, e, w, s) \
+  {                               \
+    a += F1(b, c, d) + X(w);      \
+    a = ROTATE(a, s) + e;         \
+    c = ROTATE(c, 10);            \
+  }
+
+#define RIP2(a, b, c, d, e, w, s, K) \
+  {                                  \
+    a += F2(b, c, d) + X(w) + K;     \
+    a = ROTATE(a, s) + e;            \
+    c = ROTATE(c, 10);               \
+  }
+
+#define RIP3(a, b, c, d, e, w, s, K) \
+  {                                  \
+    a += F3(b, c, d) + X(w) + K;     \
+    a = ROTATE(a, s) + e;            \
+    c = ROTATE(c, 10);               \
+  }
+
+#define RIP4(a, b, c, d, e, w, s, K) \
+  {                                  \
+    a += F4(b, c, d) + X(w) + K;     \
+    a = ROTATE(a, s) + e;            \
+    c = ROTATE(c, 10);               \
+  }
+
+#define RIP5(a, b, c, d, e, w, s, K) \
+  {                                  \
+    a += F5(b, c, d) + X(w) + K;     \
+    a = ROTATE(a, s) + e;            \
+    c = ROTATE(c, 10);               \
+  }
+
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00  0
+#define SL00 11
+#define WL01  1
+#define SL01 14
+#define WL02  2
+#define SL02 15
+#define WL03  3
+#define SL03 12
+#define WL04  4
+#define SL04  5
+#define WL05  5
+#define SL05  8
+#define WL06  6
+#define SL06  7
+#define WL07  7
+#define SL07  9
+#define WL08  8
+#define SL08 11
+#define WL09  9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12  6
+#define WL13 13
+#define SL13  7
+#define WL14 14
+#define SL14  9
+#define WL15 15
+#define SL15  8
+
+#define WL16  7
+#define SL16  7
+#define WL17  4
+#define SL17  6
+#define WL18 13
+#define SL18  8
+#define WL19  1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21  6
+#define SL21  9
+#define WL22 15
+#define SL22  7
+#define WL23  3
+#define SL23 15
+#define WL24 12
+#define SL24  7
+#define WL25  0
+#define SL25 12
+#define WL26  9
+#define SL26 15
+#define WL27  5
+#define SL27  9
+#define WL28  2
+#define SL28 11
+#define WL29 14
+#define SL29  7
+#define WL30 11
+#define SL30 13
+#define WL31  8
+#define SL31 12
+
+#define WL32  3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34  6
+#define WL35  4
+#define SL35  7
+#define WL36  9
+#define SL36 14
+#define WL37 15
+#define SL37  9
+#define WL38  8
+#define SL38 13
+#define WL39  1
+#define SL39 15
+#define WL40  2
+#define SL40 14
+#define WL41  7
+#define SL41  8
+#define WL42  0
+#define SL42 13
+#define WL43  6
+#define SL43  6
+#define WL44 13
+#define SL44  5
+#define WL45 11
+#define SL45 12
+#define WL46  5
+#define SL46  7
+#define WL47 12
+#define SL47  5
+
+#define WL48  1
+#define SL48 11
+#define WL49  9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52  0
+#define SL52 14
+#define WL53  8
+#define SL53 15
+#define WL54 12
+#define SL54  9
+#define WL55  4
+#define SL55  8
+#define WL56 13
+#define SL56  9
+#define WL57  3
+#define SL57 14
+#define WL58  7
+#define SL58  5
+#define WL59 15
+#define SL59  6
+#define WL60 14
+#define SL60  8
+#define WL61  5
+#define SL61  6
+#define WL62  6
+#define SL62  5
+#define WL63  2
+#define SL63 12
+
+#define WL64  4
+#define SL64  9
+#define WL65  0
+#define SL65 15
+#define WL66  5
+#define SL66  5
+#define WL67  9
+#define SL67 11
+#define WL68  7
+#define SL68  6
+#define WL69 12
+#define SL69  8
+#define WL70  2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72  5
+#define WL73  1
+#define SL73 12
+#define WL74  3
+#define SL74 13
+#define WL75  8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77  6
+#define SL77  8
+#define WL78 15
+#define SL78  5
+#define WL79 13
+#define SL79  6
+
+#define WR00  5
+#define SR00  8
+#define WR01 14
+#define SR01  9
+#define WR02  7
+#define SR02  9
+#define WR03  0
+#define SR03 11
+#define WR04  9
+#define SR04 13
+#define WR05  2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07  4
+#define SR07  5
+#define WR08 13
+#define SR08  7
+#define WR09  6
+#define SR09  7
+#define WR10 15
+#define SR10  8
+#define WR11  8
+#define SR11 11
+#define WR12  1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14  3
+#define SR14 12
+#define WR15 12
+#define SR15  6
+
+#define WR16  6
+#define SR16  9
+#define WR17 11
+#define SR17 13
+#define WR18  3
+#define SR18 15
+#define WR19  7
+#define SR19  7
+#define WR20  0
+#define SR20 12
+#define WR21 13
+#define SR21  8
+#define WR22  5
+#define SR22  9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24  7
+#define WR25 15
+#define SR25  7
+#define WR26  8
+#define SR26 12
+#define WR27 12
+#define SR27  7
+#define WR28  4
+#define SR28  6
+#define WR29  9
+#define SR29 15
+#define WR30  1
+#define SR30 13
+#define WR31  2
+#define SR31 11
+
+#define WR32 15
+#define SR32  9
+#define WR33  5
+#define SR33  7
+#define WR34  1
+#define SR34 15
+#define WR35  3
+#define SR35 11
+#define WR36  7
+#define SR36  8
+#define WR37 14
+#define SR37  6
+#define WR38  6
+#define SR38  6
+#define WR39  9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41  8
+#define SR41 13
+#define WR42 12
+#define SR42  5
+#define WR43  2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45  0
+#define SR45 13
+#define WR46  4
+#define SR46  7
+#define WR47 13
+#define SR47  5
+
+#define WR48  8
+#define SR48 15
+#define WR49  6
+#define SR49  5
+#define WR50  4
+#define SR50  8
+#define WR51  1
+#define SR51 11
+#define WR52  3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54  6
+#define WR55  0
+#define SR55 14
+#define WR56  5
+#define SR56  6
+#define WR57 12
+#define SR57  9
+#define WR58  2
+#define SR58 12
+#define WR59 13
+#define SR59  9
+#define WR60  9
+#define SR60 12
+#define WR61  7
+#define SR61  5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63  8
+
+#define WR64 12
+#define SR64  8
+#define WR65 15
+#define SR65  5
+#define WR66 10
+#define SR66 12
+#define WR67  4
+#define SR67  9
+#define WR68  1
+#define SR68 12
+#define WR69  5
+#define SR69  5
+#define WR70  8
+#define SR70 14
+#define WR71  7
+#define SR71  6
+#define WR72  6
+#define SR72  8
+#define WR73  2
+#define SR73 13
+#define WR74 13
+#define SR74  6
+#define WR75 14
+#define SR75  5
+#define WR76  0
+#define SR76 15
+#define WR77  3
+#define SR77 13
+#define WR78  9
+#define SR78 11
+#define WR79 11
+#define SR79 11
+
+
+#if defined(__cplusplus)
+}  /* extern C */
+#endif
+
+#endif  /* OPENSSL_HEADER_BN_INTERNAL_H */
diff --git a/src/decrepit/ripemd/ripemd.c b/src/decrepit/ripemd/ripemd.c
new file mode 100644
index 0000000..6ed7816
--- /dev/null
+++ b/src/decrepit/ripemd/ripemd.c
@@ -0,0 +1,324 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/ripemd.h>
+
+#include <string.h>
+
+#include "internal.h"
+
+
+int RIPEMD160_Init(RIPEMD160_CTX *ctx) {
+  memset(ctx, 0, sizeof(*ctx));
+  ctx->h[0] = RIPEMD160_A;
+  ctx->h[1] = RIPEMD160_B;
+  ctx->h[2] = RIPEMD160_C;
+  ctx->h[3] = RIPEMD160_D;
+  ctx->h[4] = RIPEMD160_E;
+  return 1;
+}
+
+static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
+                                       size_t num) {
+  uint32_t A, B, C, D, E;
+  uint32_t a, b, c, d, e, l;
+  uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12,
+      XX13, XX14, XX15;
+#define X(i) XX##i
+
+  for (; num--;) {
+    A = h[0];
+    B = h[1];
+    C = h[2];
+    D = h[3];
+    E = h[4];
+
+    (void)HOST_c2l(data, l);
+    X(0) = l;
+    (void)HOST_c2l(data, l);
+    X(1) = l;
+    RIP1(A, B, C, D, E, WL00, SL00);
+    (void)HOST_c2l(data, l);
+    X(2) = l;
+    RIP1(E, A, B, C, D, WL01, SL01);
+    (void)HOST_c2l(data, l);
+    X(3) = l;
+    RIP1(D, E, A, B, C, WL02, SL02);
+    (void)HOST_c2l(data, l);
+    X(4) = l;
+    RIP1(C, D, E, A, B, WL03, SL03);
+    (void)HOST_c2l(data, l);
+    X(5) = l;
+    RIP1(B, C, D, E, A, WL04, SL04);
+    (void)HOST_c2l(data, l);
+    X(6) = l;
+    RIP1(A, B, C, D, E, WL05, SL05);
+    (void)HOST_c2l(data, l);
+    X(7) = l;
+    RIP1(E, A, B, C, D, WL06, SL06);
+    (void)HOST_c2l(data, l);
+    X(8) = l;
+    RIP1(D, E, A, B, C, WL07, SL07);
+    (void)HOST_c2l(data, l);
+    X(9) = l;
+    RIP1(C, D, E, A, B, WL08, SL08);
+    (void)HOST_c2l(data, l);
+    X(10) = l;
+    RIP1(B, C, D, E, A, WL09, SL09);
+    (void)HOST_c2l(data, l);
+    X(11) = l;
+    RIP1(A, B, C, D, E, WL10, SL10);
+    (void)HOST_c2l(data, l);
+    X(12) = l;
+    RIP1(E, A, B, C, D, WL11, SL11);
+    (void)HOST_c2l(data, l);
+    X(13) = l;
+    RIP1(D, E, A, B, C, WL12, SL12);
+    (void)HOST_c2l(data, l);
+    X(14) = l;
+    RIP1(C, D, E, A, B, WL13, SL13);
+    (void)HOST_c2l(data, l);
+    X(15) = l;
+    RIP1(B, C, D, E, A, WL14, SL14);
+    RIP1(A, B, C, D, E, WL15, SL15);
+
+    RIP2(E, A, B, C, D, WL16, SL16, KL1);
+    RIP2(D, E, A, B, C, WL17, SL17, KL1);
+    RIP2(C, D, E, A, B, WL18, SL18, KL1);
+    RIP2(B, C, D, E, A, WL19, SL19, KL1);
+    RIP2(A, B, C, D, E, WL20, SL20, KL1);
+    RIP2(E, A, B, C, D, WL21, SL21, KL1);
+    RIP2(D, E, A, B, C, WL22, SL22, KL1);
+    RIP2(C, D, E, A, B, WL23, SL23, KL1);
+    RIP2(B, C, D, E, A, WL24, SL24, KL1);
+    RIP2(A, B, C, D, E, WL25, SL25, KL1);
+    RIP2(E, A, B, C, D, WL26, SL26, KL1);
+    RIP2(D, E, A, B, C, WL27, SL27, KL1);
+    RIP2(C, D, E, A, B, WL28, SL28, KL1);
+    RIP2(B, C, D, E, A, WL29, SL29, KL1);
+    RIP2(A, B, C, D, E, WL30, SL30, KL1);
+    RIP2(E, A, B, C, D, WL31, SL31, KL1);
+
+    RIP3(D, E, A, B, C, WL32, SL32, KL2);
+    RIP3(C, D, E, A, B, WL33, SL33, KL2);
+    RIP3(B, C, D, E, A, WL34, SL34, KL2);
+    RIP3(A, B, C, D, E, WL35, SL35, KL2);
+    RIP3(E, A, B, C, D, WL36, SL36, KL2);
+    RIP3(D, E, A, B, C, WL37, SL37, KL2);
+    RIP3(C, D, E, A, B, WL38, SL38, KL2);
+    RIP3(B, C, D, E, A, WL39, SL39, KL2);
+    RIP3(A, B, C, D, E, WL40, SL40, KL2);
+    RIP3(E, A, B, C, D, WL41, SL41, KL2);
+    RIP3(D, E, A, B, C, WL42, SL42, KL2);
+    RIP3(C, D, E, A, B, WL43, SL43, KL2);
+    RIP3(B, C, D, E, A, WL44, SL44, KL2);
+    RIP3(A, B, C, D, E, WL45, SL45, KL2);
+    RIP3(E, A, B, C, D, WL46, SL46, KL2);
+    RIP3(D, E, A, B, C, WL47, SL47, KL2);
+
+    RIP4(C, D, E, A, B, WL48, SL48, KL3);
+    RIP4(B, C, D, E, A, WL49, SL49, KL3);
+    RIP4(A, B, C, D, E, WL50, SL50, KL3);
+    RIP4(E, A, B, C, D, WL51, SL51, KL3);
+    RIP4(D, E, A, B, C, WL52, SL52, KL3);
+    RIP4(C, D, E, A, B, WL53, SL53, KL3);
+    RIP4(B, C, D, E, A, WL54, SL54, KL3);
+    RIP4(A, B, C, D, E, WL55, SL55, KL3);
+    RIP4(E, A, B, C, D, WL56, SL56, KL3);
+    RIP4(D, E, A, B, C, WL57, SL57, KL3);
+    RIP4(C, D, E, A, B, WL58, SL58, KL3);
+    RIP4(B, C, D, E, A, WL59, SL59, KL3);
+    RIP4(A, B, C, D, E, WL60, SL60, KL3);
+    RIP4(E, A, B, C, D, WL61, SL61, KL3);
+    RIP4(D, E, A, B, C, WL62, SL62, KL3);
+    RIP4(C, D, E, A, B, WL63, SL63, KL3);
+
+    RIP5(B, C, D, E, A, WL64, SL64, KL4);
+    RIP5(A, B, C, D, E, WL65, SL65, KL4);
+    RIP5(E, A, B, C, D, WL66, SL66, KL4);
+    RIP5(D, E, A, B, C, WL67, SL67, KL4);
+    RIP5(C, D, E, A, B, WL68, SL68, KL4);
+    RIP5(B, C, D, E, A, WL69, SL69, KL4);
+    RIP5(A, B, C, D, E, WL70, SL70, KL4);
+    RIP5(E, A, B, C, D, WL71, SL71, KL4);
+    RIP5(D, E, A, B, C, WL72, SL72, KL4);
+    RIP5(C, D, E, A, B, WL73, SL73, KL4);
+    RIP5(B, C, D, E, A, WL74, SL74, KL4);
+    RIP5(A, B, C, D, E, WL75, SL75, KL4);
+    RIP5(E, A, B, C, D, WL76, SL76, KL4);
+    RIP5(D, E, A, B, C, WL77, SL77, KL4);
+    RIP5(C, D, E, A, B, WL78, SL78, KL4);
+    RIP5(B, C, D, E, A, WL79, SL79, KL4);
+
+    a = A;
+    b = B;
+    c = C;
+    d = D;
+    e = E;
+    /* Do other half */
+    A = h[0];
+    B = h[1];
+    C = h[2];
+    D = h[3];
+    E = h[4];
+
+    RIP5(A, B, C, D, E, WR00, SR00, KR0);
+    RIP5(E, A, B, C, D, WR01, SR01, KR0);
+    RIP5(D, E, A, B, C, WR02, SR02, KR0);
+    RIP5(C, D, E, A, B, WR03, SR03, KR0);
+    RIP5(B, C, D, E, A, WR04, SR04, KR0);
+    RIP5(A, B, C, D, E, WR05, SR05, KR0);
+    RIP5(E, A, B, C, D, WR06, SR06, KR0);
+    RIP5(D, E, A, B, C, WR07, SR07, KR0);
+    RIP5(C, D, E, A, B, WR08, SR08, KR0);
+    RIP5(B, C, D, E, A, WR09, SR09, KR0);
+    RIP5(A, B, C, D, E, WR10, SR10, KR0);
+    RIP5(E, A, B, C, D, WR11, SR11, KR0);
+    RIP5(D, E, A, B, C, WR12, SR12, KR0);
+    RIP5(C, D, E, A, B, WR13, SR13, KR0);
+    RIP5(B, C, D, E, A, WR14, SR14, KR0);
+    RIP5(A, B, C, D, E, WR15, SR15, KR0);
+
+    RIP4(E, A, B, C, D, WR16, SR16, KR1);
+    RIP4(D, E, A, B, C, WR17, SR17, KR1);
+    RIP4(C, D, E, A, B, WR18, SR18, KR1);
+    RIP4(B, C, D, E, A, WR19, SR19, KR1);
+    RIP4(A, B, C, D, E, WR20, SR20, KR1);
+    RIP4(E, A, B, C, D, WR21, SR21, KR1);
+    RIP4(D, E, A, B, C, WR22, SR22, KR1);
+    RIP4(C, D, E, A, B, WR23, SR23, KR1);
+    RIP4(B, C, D, E, A, WR24, SR24, KR1);
+    RIP4(A, B, C, D, E, WR25, SR25, KR1);
+    RIP4(E, A, B, C, D, WR26, SR26, KR1);
+    RIP4(D, E, A, B, C, WR27, SR27, KR1);
+    RIP4(C, D, E, A, B, WR28, SR28, KR1);
+    RIP4(B, C, D, E, A, WR29, SR29, KR1);
+    RIP4(A, B, C, D, E, WR30, SR30, KR1);
+    RIP4(E, A, B, C, D, WR31, SR31, KR1);
+
+    RIP3(D, E, A, B, C, WR32, SR32, KR2);
+    RIP3(C, D, E, A, B, WR33, SR33, KR2);
+    RIP3(B, C, D, E, A, WR34, SR34, KR2);
+    RIP3(A, B, C, D, E, WR35, SR35, KR2);
+    RIP3(E, A, B, C, D, WR36, SR36, KR2);
+    RIP3(D, E, A, B, C, WR37, SR37, KR2);
+    RIP3(C, D, E, A, B, WR38, SR38, KR2);
+    RIP3(B, C, D, E, A, WR39, SR39, KR2);
+    RIP3(A, B, C, D, E, WR40, SR40, KR2);
+    RIP3(E, A, B, C, D, WR41, SR41, KR2);
+    RIP3(D, E, A, B, C, WR42, SR42, KR2);
+    RIP3(C, D, E, A, B, WR43, SR43, KR2);
+    RIP3(B, C, D, E, A, WR44, SR44, KR2);
+    RIP3(A, B, C, D, E, WR45, SR45, KR2);
+    RIP3(E, A, B, C, D, WR46, SR46, KR2);
+    RIP3(D, E, A, B, C, WR47, SR47, KR2);
+
+    RIP2(C, D, E, A, B, WR48, SR48, KR3);
+    RIP2(B, C, D, E, A, WR49, SR49, KR3);
+    RIP2(A, B, C, D, E, WR50, SR50, KR3);
+    RIP2(E, A, B, C, D, WR51, SR51, KR3);
+    RIP2(D, E, A, B, C, WR52, SR52, KR3);
+    RIP2(C, D, E, A, B, WR53, SR53, KR3);
+    RIP2(B, C, D, E, A, WR54, SR54, KR3);
+    RIP2(A, B, C, D, E, WR55, SR55, KR3);
+    RIP2(E, A, B, C, D, WR56, SR56, KR3);
+    RIP2(D, E, A, B, C, WR57, SR57, KR3);
+    RIP2(C, D, E, A, B, WR58, SR58, KR3);
+    RIP2(B, C, D, E, A, WR59, SR59, KR3);
+    RIP2(A, B, C, D, E, WR60, SR60, KR3);
+    RIP2(E, A, B, C, D, WR61, SR61, KR3);
+    RIP2(D, E, A, B, C, WR62, SR62, KR3);
+    RIP2(C, D, E, A, B, WR63, SR63, KR3);
+
+    RIP1(B, C, D, E, A, WR64, SR64);
+    RIP1(A, B, C, D, E, WR65, SR65);
+    RIP1(E, A, B, C, D, WR66, SR66);
+    RIP1(D, E, A, B, C, WR67, SR67);
+    RIP1(C, D, E, A, B, WR68, SR68);
+    RIP1(B, C, D, E, A, WR69, SR69);
+    RIP1(A, B, C, D, E, WR70, SR70);
+    RIP1(E, A, B, C, D, WR71, SR71);
+    RIP1(D, E, A, B, C, WR72, SR72);
+    RIP1(C, D, E, A, B, WR73, SR73);
+    RIP1(B, C, D, E, A, WR74, SR74);
+    RIP1(A, B, C, D, E, WR75, SR75);
+    RIP1(E, A, B, C, D, WR76, SR76);
+    RIP1(D, E, A, B, C, WR77, SR77);
+    RIP1(C, D, E, A, B, WR78, SR78);
+    RIP1(B, C, D, E, A, WR79, SR79);
+
+    D = h[1] + c + D;
+    h[1] = h[2] + d + E;
+    h[2] = h[3] + e + A;
+    h[3] = h[4] + a + B;
+    h[4] = h[0] + b + C;
+    h[0] = D;
+  }
+
+#undef X
+}
+
+uint8_t *RIPEMD160(const uint8_t *data, size_t len, unsigned char *out) {
+  RIPEMD160_CTX ctx;
+
+  if (!RIPEMD160_Init(&ctx)) {
+    return NULL;
+  }
+
+  RIPEMD160_Update(&ctx, data, len);
+  RIPEMD160_Final(out, &ctx);
+  return out;
+}
diff --git a/src/decrepit/ripemd/ripemd_test.cc b/src/decrepit/ripemd/ripemd_test.cc
new file mode 100644
index 0000000..ebcabdf
--- /dev/null
+++ b/src/decrepit/ripemd/ripemd_test.cc
@@ -0,0 +1,119 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ripemd.h>
+
+#include <memory>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../crypto/test/test_util.h"
+
+
+struct RIPEMDTestCase {
+  const char *input;
+  uint8_t expected[RIPEMD160_DIGEST_LENGTH];
+};
+
+static const RIPEMDTestCase kRIPEMDTestCases[] = {
+    {"", {0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
+          0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31}},
+    {"a", {0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
+           0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe}},
+    {"abc", {0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
+             0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc}},
+    {"message digest",
+     {0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
+      0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36}},
+    {"abcdefghijklmnopqrstuvwxyz",
+     {0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
+      0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc}},
+    {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+     {0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
+      0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b}},
+    {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+     {0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
+      0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89}},
+    {"1234567890123456789012345678901234567890123456789012345678901234567890123"
+     "4567890",
+     {0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
+      0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb}},
+};
+
+int main(void) {
+  unsigned test_num = 0;
+  int ok = 1;
+
+  for (const auto &test : kRIPEMDTestCases) {
+    test_num++;
+
+    const size_t input_len = strlen(test.input);
+
+    for (size_t stride = 0; stride <= input_len; stride++) {
+      uint8_t digest[RIPEMD160_DIGEST_LENGTH];
+
+      if (stride == 0) {
+        RIPEMD160(reinterpret_cast<const uint8_t *>(test.input), input_len,
+                  digest);
+      } else {
+        RIPEMD160_CTX ctx;
+        RIPEMD160_Init(&ctx);
+
+        for (size_t done = 0; done < input_len;) {
+          const size_t remaining = input_len - done;
+          size_t todo = stride;
+          if (todo > remaining) {
+            todo = remaining;
+          }
+
+          RIPEMD160_Update(&ctx, &test.input[done], todo);
+          done += todo;
+        }
+
+        RIPEMD160_Final(digest, &ctx);
+      }
+
+      if (memcmp(digest, test.expected, sizeof(digest)) != 0) {
+        fprintf(stderr, "#%u: bad result with stride %u: ", test_num,
+                static_cast<unsigned>(stride));
+        hexdump(stderr, "", digest, sizeof(digest));
+        ok = 0;
+      }
+    }
+  }
+
+  static const size_t kLargeBufSize = 1000000;
+  std::unique_ptr<uint8_t[]> buf(new uint8_t[kLargeBufSize]);
+  memset(buf.get(), 'a', kLargeBufSize);
+  uint8_t digest[RIPEMD160_DIGEST_LENGTH];
+  RIPEMD160(buf.get(), kLargeBufSize, digest);
+
+  static const uint8_t kMillionADigest[RIPEMD160_DIGEST_LENGTH] = {
+      0x52, 0x78, 0x32, 0x43, 0xc1, 0x69, 0x7b, 0xdb, 0xe1, 0x6d,
+      0x37, 0xf9, 0x7f, 0x68, 0xf0, 0x83, 0x25, 0xdc, 0x15, 0x28};
+
+  if (memcmp(digest, kMillionADigest, sizeof(digest)) != 0) {
+    fprintf(stderr, "Digest incorrect for “million a's” test: ");
+    hexdump(stderr, "", digest, sizeof(digest));
+    ok = 0;
+  }
+
+  if (!ok) {
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/decrepit/rsa/rsa_decrepit.c b/src/decrepit/rsa/rsa_decrepit.c
index c238f46..0d7c5f6 100644
--- a/src/decrepit/rsa/rsa_decrepit.c
+++ b/src/decrepit/rsa/rsa_decrepit.c
@@ -84,3 +84,20 @@
   RSA_free(rsa);
   return NULL;
 }
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM, const uint8_t *mHash,
+                              const EVP_MD *Hash, int sLen) {
+  return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+}
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash, const EVP_MD *Hash,
+                         const uint8_t *EM, int sLen) {
+  return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+}
+
+int RSA_padding_add_PKCS1_OAEP(uint8_t *to, unsigned to_len,
+                               const uint8_t *from, unsigned from_len,
+                               const uint8_t *param, unsigned param_len) {
+  return RSA_padding_add_PKCS1_OAEP_mgf1(to, to_len, from, from_len, param,
+                                         param_len, NULL, NULL);
+}
diff --git a/src/decrepit/ssl/CMakeLists.txt b/src/decrepit/ssl/CMakeLists.txt
new file mode 100644
index 0000000..fba0234
--- /dev/null
+++ b/src/decrepit/ssl/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  ssl_decrepit
+
+  OBJECT
+
+  ssl_decrepit.c
+)
diff --git a/src/decrepit/ssl/ssl_decrepit.c b/src/decrepit/ssl/ssl_decrepit.c
new file mode 100644
index 0000000..e25cbf3
--- /dev/null
+++ b/src/decrepit/ssl/ssl_decrepit.c
@@ -0,0 +1,225 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 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).
+ *
+ */
+
+#include <openssl/ssl.h>
+
+#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL)
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+
+typedef struct {
+  DIR *dir;
+  struct dirent dirent;
+} OPENSSL_DIR_CTX;
+
+static const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
+                                    const char *directory) {
+  struct dirent *dirent;
+
+  if (ctx == NULL || directory == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  errno = 0;
+  if (*ctx == NULL) {
+    *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
+    if (*ctx == NULL) {
+      errno = ENOMEM;
+      return 0;
+    }
+    memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
+
+    (*ctx)->dir = opendir(directory);
+    if ((*ctx)->dir == NULL) {
+      int save_errno = errno; /* Probably not needed, but I'm paranoid */
+      free(*ctx);
+      *ctx = NULL;
+      errno = save_errno;
+      return 0;
+    }
+  }
+
+  if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 ||
+      dirent == NULL) {
+    return 0;
+  }
+
+  return (*ctx)->dirent.d_name;
+}
+
+static int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
+  if (ctx != NULL && *ctx != NULL) {
+    int r = closedir((*ctx)->dir);
+    free(*ctx);
+    *ctx = NULL;
+    return r == 0;
+  }
+
+  errno = EINVAL;
+  return 0;
+}
+
+
+/* Add a directory of certs to a stack.
+ *
+ * \param stack the stack to append to.
+ * \param dir the directory to append from. All files in this directory will be
+ *     examined as potential certs. Any that are acceptable to
+ *     SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
+ *     be included.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ *     certs may have been added to \c stack. */
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+                                       const char *dir) {
+  OPENSSL_DIR_CTX *d = NULL;
+  const char *filename;
+  int ret = 0;
+
+  /* Note that a side effect is that the CAs will be sorted by name */
+  while ((filename = OPENSSL_DIR_read(&d, dir))) {
+    char buf[1024];
+    int r;
+
+    if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
+      goto err;
+    }
+
+    r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
+    if (r <= 0 || r >= (int)sizeof(buf) ||
+        !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
+      goto err;
+    }
+  }
+
+  if (errno) {
+    OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+    ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+    goto err;
+  }
+
+  ret = 1;
+
+err:
+  if (d) {
+    OPENSSL_DIR_end(&d);
+  }
+  return ret;
+}
+
+#endif /* !WINDOWS && !PNACL */
diff --git a/src/decrepit/x509/CMakeLists.txt b/src/decrepit/x509/CMakeLists.txt
new file mode 100644
index 0000000..930912d
--- /dev/null
+++ b/src/decrepit/x509/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+  x509_decrepit
+
+  OBJECT
+
+  x509_decrepit.c
+)
diff --git a/src/decrepit/x509/x509_decrepit.c b/src/decrepit/x509/x509_decrepit.c
new file mode 100644
index 0000000..5714b40
--- /dev/null
+++ b/src/decrepit/x509/x509_decrepit.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+                                    X509V3_CTX *ctx, int ext_nid, char *value) {
+  CONF *nconf = NULL;
+  LHASH_OF(CONF_VALUE) *orig_data = NULL;
+
+  if (conf != NULL) {
+    nconf = NCONF_new(NULL /* no method */);
+    if (nconf == NULL) {
+      return NULL;
+    }
+
+    orig_data = nconf->data;
+    nconf->data = conf;
+  }
+
+  X509_EXTENSION *ret = X509V3_EXT_nconf_nid(nconf, ctx, ext_nid, value);
+
+  if (nconf != NULL) {
+    nconf->data = orig_data;
+    NCONF_free(nconf);
+  }
+
+  return ret;
+}
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index 092d2f6..d9a640c 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -135,49 +135,6 @@
 OPENSSL_EXPORT int EVP_has_aes_hardware(void);
 
 
-/* TLS-specific AEAD algorithms.
- *
- * These AEAD primitives do not meet the definition of generic AEADs. They are
- * all specific to TLS and should not be used outside of that context. They must
- * be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may
- * not be used concurrently. Any nonces are used as IVs, so they must be
- * unpredictable. They only accept an |ad| parameter of length 11 (the standard
- * TLS one with length omitted). */
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_tls(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void);
-
-
-/* SSLv3-specific AEAD algorithms.
- *
- * These AEAD primitives do not meet the definition of generic AEADs. They are
- * all specific to SSLv3 and should not be used outside of that context. They
- * must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful,
- * and may not be used concurrently. They only accept an |ad| parameter of
- * length 9 (the standard TLS one with length and version omitted). */
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void);
-
-
 /* Utility functions. */
 
 /* EVP_AEAD_key_length returns the length, in bytes, of the keys used by
@@ -226,12 +183,6 @@
  * be used. */
 #define EVP_AEAD_DEFAULT_TAG_LENGTH 0
 
-/* evp_aead_direction_t denotes the direction of an AEAD operation. */
-enum evp_aead_direction_t {
-  evp_aead_open,
-  evp_aead_seal,
-};
-
 /* EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be
  * initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not
  * necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for
@@ -251,13 +202,6 @@
                                      const uint8_t *key, size_t key_len,
                                      size_t tag_len, ENGINE *impl);
 
-/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal
- * AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a
- * given direction. */
-OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
-    EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
-    size_t tag_len, enum evp_aead_direction_t dir);
-
 /* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to
  * call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to
  * all zeros. */
@@ -315,8 +259,64 @@
                                      const uint8_t *ad, size_t ad_len);
 
 
+/* TLS-specific AEAD algorithms.
+ *
+ * These AEAD primitives do not meet the definition of generic AEADs. They are
+ * all specific to TLS and should not be used outside of that context. They must
+ * be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may
+ * not be used concurrently. Any nonces are used as IVs, so they must be
+ * unpredictable. They only accept an |ad| parameter of length 11 (the standard
+ * TLS one with length omitted). */
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_tls(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void);
+
+
+/* SSLv3-specific AEAD algorithms.
+ *
+ * These AEAD primitives do not meet the definition of generic AEADs. They are
+ * all specific to SSLv3 and should not be used outside of that context. They
+ * must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful,
+ * and may not be used concurrently. They only accept an |ad| parameter of
+ * length 9 (the standard TLS one with length and version omitted). */
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void);
+
+
 /* Obscure functions. */
 
+/* evp_aead_direction_t denotes the direction of an AEAD operation. */
+enum evp_aead_direction_t {
+  evp_aead_open,
+  evp_aead_seal,
+};
+
+/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal
+ * AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a
+ * given direction. */
+OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
+    EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
+    size_t tag_len, enum evp_aead_direction_t dir);
+
 /* EVP_AEAD_CTX_get_rc4_state sets |*out_key| to point to an RC4 key structure.
  * It returns one on success or zero if |ctx| doesn't have an RC4 key. */
 OPENSSL_EXPORT int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx,
@@ -331,14 +331,6 @@
                                        const uint8_t **out_iv, size_t *out_len);
 
 
-/* Deprecated functions. */
-
-/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|.
- *
- * TODO(davidben): Remove this. */
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
-
-
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/include/openssl/arm_arch.h b/src/include/openssl/arm_arch.h
index 1471db9..e7010f4 100644
--- a/src/include/openssl/arm_arch.h
+++ b/src/include/openssl/arm_arch.h
@@ -105,12 +105,6 @@
 /* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
 #define ARMV7_NEON (1 << 0)
 
-/* ARMV7_NEON_FUNCTIONAL is true when the NEON unit doesn't contain subtle bugs.
- * The Poly1305 NEON code is known to trigger bugs in the NEON units of some
- * phones. If this bit isn't set then the Poly1305 NEON code won't be used.
- * See https://code.google.com/p/chromium/issues/detail?id=341598. */
-#define ARMV7_NEON_FUNCTIONAL (1 << 10)
-
 /* ARMV8_AES indicates support for hardware AES instructions. */
 #define ARMV8_AES (1 << 2)
 
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 63bde18..22b6282 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -85,6 +85,9 @@
 #define V_ASN1_ANY			-4	/* used in ASN1 template code */
 
 #define V_ASN1_NEG			0x100	/* negative flag */
+/* No supported universal tags may exceed this value, to avoid ambiguity with
+ * V_ASN1_NEG. */
+#define V_ASN1_MAX_UNIVERSAL		0xff
 
 #define V_ASN1_UNDEF			-1
 #define V_ASN1_EOC			0
@@ -966,7 +969,6 @@
 OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
 OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
 OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
-OPENSSL_EXPORT int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, int off);
 OPENSSL_EXPORT int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
 OPENSSL_EXPORT int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
 OPENSSL_EXPORT const char *ASN1_tag2str(int tag);
@@ -1084,84 +1086,89 @@
 #define ASN1_R_BN_LIB 105
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
 #define ASN1_R_BUFFER_TOO_SMALL 107
-#define ASN1_R_DECODE_ERROR 108
-#define ASN1_R_DEPTH_EXCEEDED 109
-#define ASN1_R_ENCODE_ERROR 110
-#define ASN1_R_ERROR_GETTING_TIME 111
-#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 112
-#define ASN1_R_EXPECTING_AN_INTEGER 113
-#define ASN1_R_EXPECTING_AN_OBJECT 114
-#define ASN1_R_EXPECTING_A_BOOLEAN 115
-#define ASN1_R_EXPECTING_A_TIME 116
-#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 117
-#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 118
-#define ASN1_R_FIELD_MISSING 119
-#define ASN1_R_FIRST_NUM_TOO_LARGE 120
-#define ASN1_R_HEADER_TOO_LONG 121
-#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 122
-#define ASN1_R_ILLEGAL_BOOLEAN 123
-#define ASN1_R_ILLEGAL_CHARACTERS 124
-#define ASN1_R_ILLEGAL_FORMAT 125
-#define ASN1_R_ILLEGAL_HEX 126
-#define ASN1_R_ILLEGAL_IMPLICIT_TAG 127
-#define ASN1_R_ILLEGAL_INTEGER 128
-#define ASN1_R_ILLEGAL_NESTED_TAGGING 129
-#define ASN1_R_ILLEGAL_NULL 130
-#define ASN1_R_ILLEGAL_NULL_VALUE 131
-#define ASN1_R_ILLEGAL_OBJECT 132
-#define ASN1_R_ILLEGAL_OPTIONAL_ANY 133
-#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 134
-#define ASN1_R_ILLEGAL_TAGGED_ANY 135
-#define ASN1_R_ILLEGAL_TIME_VALUE 136
-#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 137
-#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 138
-#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 139
-#define ASN1_R_INVALID_BMPSTRING_LENGTH 140
-#define ASN1_R_INVALID_DIGIT 141
-#define ASN1_R_INVALID_MODIFIER 142
-#define ASN1_R_INVALID_NUMBER 143
-#define ASN1_R_INVALID_OBJECT_ENCODING 144
-#define ASN1_R_INVALID_SEPARATOR 145
-#define ASN1_R_INVALID_TIME_FORMAT 146
-#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 147
-#define ASN1_R_INVALID_UTF8STRING 148
-#define ASN1_R_LIST_ERROR 149
-#define ASN1_R_MISSING_ASN1_EOS 150
-#define ASN1_R_MISSING_EOC 151
-#define ASN1_R_MISSING_SECOND_NUMBER 152
-#define ASN1_R_MISSING_VALUE 153
-#define ASN1_R_MSTRING_NOT_UNIVERSAL 154
-#define ASN1_R_MSTRING_WRONG_TAG 155
-#define ASN1_R_NESTED_ASN1_ERROR 156
-#define ASN1_R_NESTED_ASN1_STRING 157
-#define ASN1_R_NON_HEX_CHARACTERS 158
-#define ASN1_R_NOT_ASCII_FORMAT 159
-#define ASN1_R_NOT_ENOUGH_DATA 160
-#define ASN1_R_NO_MATCHING_CHOICE_TYPE 161
-#define ASN1_R_NULL_IS_WRONG_LENGTH 162
-#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 163
-#define ASN1_R_ODD_NUMBER_OF_CHARS 164
-#define ASN1_R_SECOND_NUMBER_TOO_LARGE 165
-#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 166
-#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 167
-#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 168
-#define ASN1_R_SHORT_LINE 169
-#define ASN1_R_STREAMING_NOT_SUPPORTED 170
-#define ASN1_R_STRING_TOO_LONG 171
-#define ASN1_R_STRING_TOO_SHORT 172
-#define ASN1_R_TAG_VALUE_TOO_HIGH 173
-#define ASN1_R_TIME_NOT_ASCII_FORMAT 174
-#define ASN1_R_TOO_LONG 175
-#define ASN1_R_TYPE_NOT_CONSTRUCTED 176
-#define ASN1_R_TYPE_NOT_PRIMITIVE 177
-#define ASN1_R_UNEXPECTED_EOC 178
-#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 179
-#define ASN1_R_UNKNOWN_FORMAT 180
-#define ASN1_R_UNKNOWN_TAG 181
-#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 182
-#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 183
-#define ASN1_R_UNSUPPORTED_TYPE 184
-#define ASN1_R_WRONG_TAG 185
-#define ASN1_R_WRONG_TYPE 186
+#define ASN1_R_CONTEXT_NOT_INITIALISED 108
+#define ASN1_R_DECODE_ERROR 109
+#define ASN1_R_DEPTH_EXCEEDED 110
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 111
+#define ASN1_R_ENCODE_ERROR 112
+#define ASN1_R_ERROR_GETTING_TIME 113
+#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 114
+#define ASN1_R_EXPECTING_AN_INTEGER 115
+#define ASN1_R_EXPECTING_AN_OBJECT 116
+#define ASN1_R_EXPECTING_A_BOOLEAN 117
+#define ASN1_R_EXPECTING_A_TIME 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120
+#define ASN1_R_FIELD_MISSING 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE 122
+#define ASN1_R_HEADER_TOO_LONG 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 124
+#define ASN1_R_ILLEGAL_BOOLEAN 125
+#define ASN1_R_ILLEGAL_CHARACTERS 126
+#define ASN1_R_ILLEGAL_FORMAT 127
+#define ASN1_R_ILLEGAL_HEX 128
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG 129
+#define ASN1_R_ILLEGAL_INTEGER 130
+#define ASN1_R_ILLEGAL_NESTED_TAGGING 131
+#define ASN1_R_ILLEGAL_NULL 132
+#define ASN1_R_ILLEGAL_NULL_VALUE 133
+#define ASN1_R_ILLEGAL_OBJECT 134
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY 135
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 136
+#define ASN1_R_ILLEGAL_TAGGED_ANY 137
+#define ASN1_R_ILLEGAL_TIME_VALUE 138
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 139
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 140
+#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 141
+#define ASN1_R_INVALID_BMPSTRING_LENGTH 142
+#define ASN1_R_INVALID_DIGIT 143
+#define ASN1_R_INVALID_MODIFIER 144
+#define ASN1_R_INVALID_NUMBER 145
+#define ASN1_R_INVALID_OBJECT_ENCODING 146
+#define ASN1_R_INVALID_SEPARATOR 147
+#define ASN1_R_INVALID_TIME_FORMAT 148
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 149
+#define ASN1_R_INVALID_UTF8STRING 150
+#define ASN1_R_LIST_ERROR 151
+#define ASN1_R_MISSING_ASN1_EOS 152
+#define ASN1_R_MISSING_EOC 153
+#define ASN1_R_MISSING_SECOND_NUMBER 154
+#define ASN1_R_MISSING_VALUE 155
+#define ASN1_R_MSTRING_NOT_UNIVERSAL 156
+#define ASN1_R_MSTRING_WRONG_TAG 157
+#define ASN1_R_NESTED_ASN1_ERROR 158
+#define ASN1_R_NESTED_ASN1_STRING 159
+#define ASN1_R_NON_HEX_CHARACTERS 160
+#define ASN1_R_NOT_ASCII_FORMAT 161
+#define ASN1_R_NOT_ENOUGH_DATA 162
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE 163
+#define ASN1_R_NULL_IS_WRONG_LENGTH 164
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 165
+#define ASN1_R_ODD_NUMBER_OF_CHARS 166
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE 167
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 168
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 169
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 170
+#define ASN1_R_SHORT_LINE 171
+#define ASN1_R_STREAMING_NOT_SUPPORTED 172
+#define ASN1_R_STRING_TOO_LONG 173
+#define ASN1_R_STRING_TOO_SHORT 174
+#define ASN1_R_TAG_VALUE_TOO_HIGH 175
+#define ASN1_R_TIME_NOT_ASCII_FORMAT 176
+#define ASN1_R_TOO_LONG 177
+#define ASN1_R_TYPE_NOT_CONSTRUCTED 178
+#define ASN1_R_TYPE_NOT_PRIMITIVE 179
+#define ASN1_R_UNEXPECTED_EOC 180
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 181
+#define ASN1_R_UNKNOWN_FORMAT 182
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 183
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 184
+#define ASN1_R_UNKNOWN_TAG 185
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 186
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 187
+#define ASN1_R_UNSUPPORTED_TYPE 188
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 189
+#define ASN1_R_WRONG_TAG 190
+#define ASN1_R_WRONG_TYPE 191
 
 #endif
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 47b3ccb..2211920 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -60,7 +60,11 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <openssl/opensslfeatures.h>
+#include <openssl/opensslconf.h>
+
+#if defined(BORINGSSL_PREFIX)
+#include <boringssl_prefix_symbols.h>
+#endif
 
 #if defined(__cplusplus)
 extern "C" {
@@ -108,7 +112,8 @@
 #endif
 
 #define OPENSSL_IS_BORINGSSL
-#define BORINGSSL_201510
+#define BORINGSSL_201512
+#define BORINGSSL_201603
 #define OPENSSL_VERSION_NUMBER 0x10002000
 #define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
 
@@ -138,6 +143,15 @@
 
 #endif  /* defined(BORINGSSL_SHARED_LIBRARY) */
 
+
+#if defined(__GNUC__)
+#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \
+        __attribute__((__format__(__printf__, string_index, first_to_check)))
+#else
+#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check)
+#endif
+
+
 /* CRYPTO_THREADID is a dummy value. */
 typedef int CRYPTO_THREADID;
 
@@ -173,6 +187,7 @@
 typedef struct PBE2PARAM_st PBE2PARAM;
 typedef struct PBEPARAM_st PBEPARAM;
 typedef struct PBKDF2PARAM_st PBKDF2PARAM;
+typedef struct RIPEMD160state_st RIPEMD160_CTX;
 typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
 typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
 typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
@@ -221,6 +236,7 @@
 typedef struct hmac_ctx_st HMAC_CTX;
 typedef struct md4_state_st MD4_CTX;
 typedef struct md5_state_st MD5_CTX;
+typedef struct newhope_poly_st NEWHOPE_POLY;
 typedef struct pkcs12_st PKCS12;
 typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
 typedef struct private_key_st X509_PKEY;
@@ -231,6 +247,7 @@
 typedef struct sha256_state_st SHA256_CTX;
 typedef struct sha512_state_st SHA512_CTX;
 typedef struct sha_state_st SHA_CTX;
+typedef struct spake2_ctx_st SPAKE2_CTX;
 typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE;
 typedef struct ssl_cipher_st SSL_CIPHER;
 typedef struct ssl_ctx_st SSL_CTX;
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index c88a3e1..a7fe261 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -61,6 +61,7 @@
 
 #include <stdio.h>  /* For FILE */
 
+#include <openssl/buffer.h>
 #include <openssl/err.h> /* for ERR_print_errors_fp */
 #include <openssl/ex_data.h>
 #include <openssl/stack.h>
@@ -308,18 +309,12 @@
 OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio);
 
 
-/* Printf functions.
- *
- * These functions are versions of printf functions that output to a BIO rather
- * than a FILE. */
-#ifdef __GNUC__
-#define __bio_h__attr__ __attribute__
-#else
-#define __bio_h__attr__(x)
-#endif
+/* Printf functions. */
+
+/* BIO_printf behaves like |printf| but outputs to |bio| rather than a |FILE|.
+ * It returns the number of bytes written or a negative number on error. */
 OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...)
-    __bio_h__attr__((__format__(__printf__, 2, 3)));
-#undef __bio_h__attr__
+    OPENSSL_PRINTF_FORMAT_FUNC(2, 3);
 
 
 /* Utility functions. */
@@ -374,12 +369,12 @@
 /* BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. */
 OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void);
 
-/* BIO_new_mem_buf creates BIO that reads and writes from |len| bytes at |buf|.
+/* BIO_new_mem_buf creates read-only BIO that reads from |len| bytes at |buf|.
  * It does not take ownership of |buf|. It returns the BIO or NULL on error.
  *
  * If |len| is negative, then |buf| is treated as a NUL-terminated string, but
  * don't depend on this in new code. */
-OPENSSL_EXPORT BIO *BIO_new_mem_buf(void *buf, int len);
+OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len);
 
 /* BIO_mem_contents sets |*out_contents| to point to the current contents of
  * |bio| and |*out_len| to contain the length of that data. It returns one on
@@ -441,12 +436,18 @@
 
 /* BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is
  * non-zero then |fd| will be closed when |bio| is. It returns one on success
- * or zero on error. */
+ * or zero on error.
+ *
+ * This function may also be used with socket BIOs (see |BIO_s_socket| and
+ * |BIO_new_socket|). */
 OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
 
 /* BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if
  * |bio| does not wrap a file descriptor. If there is a file descriptor and
- * |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. */
+ * |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor.
+ *
+ * This function may also be used with socket BIOs (see |BIO_s_socket| and
+ * |BIO_new_socket|). */
 OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
 
 
@@ -526,7 +527,17 @@
 OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
 
 
-/* Socket BIOs. */
+/* Socket BIOs.
+ *
+ * Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap
+ * the system's |recv| and |send| functions instead of |read| and |write|. On
+ * Windows, file descriptors are provided by C runtime and are not
+ * interchangeable with sockets.
+ *
+ * Socket BIOs may be used with |BIO_set_fd| and |BIO_get_fd|.
+ *
+ * TODO(davidben): Add separate APIs and fix the internals to use |SOCKET|s
+ * around rather than rely on int casts. */
 
 OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void);
 
@@ -567,6 +578,10 @@
  * returns one on success and zero otherwise. */
 OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on);
 
+/* BIO_do_connect connects |bio| if it has not been connected yet. It returns
+ * one on success and <= 0 otherwise. */
+OPENSSL_EXPORT int BIO_do_connect(BIO *bio);
+
 
 /* Datagram BIOs.
  *
@@ -717,6 +732,11 @@
 #define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
 #define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
 
+/* These are never used, but exist to allow code to compile more easily. */
+#define BIO_CTRL_DUP	100
+#define BIO_CTRL_PUSH	101
+#define BIO_CTRL_POP	102
+
 
 /* Android compatibility section.
  *
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 6e971e4..1dea3c5 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -303,17 +303,17 @@
 
 /* ASN.1 functions. */
 
-/* BN_cbs2unsigned parses a non-negative DER INTEGER from |cbs| writes the
- * result to |ret|. It returns one on success and zero on failure. */
-OPENSSL_EXPORT int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret);
+/* BN_parse_asn1_unsigned parses a non-negative DER INTEGER from |cbs| writes
+ * the result to |ret|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret);
 
-/* BN_cbs2unsigned_buggy acts like |BN_cbs2unsigned| but tolerates some invalid
- * encodings. Do not use this function. */
-OPENSSL_EXPORT int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret);
+/* BN_parse_asn1_unsigned_buggy acts like |BN_parse_asn1_unsigned| but tolerates
+ * some invalid encodings. Do not use this function. */
+OPENSSL_EXPORT int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret);
 
-/* BN_bn2cbb marshals |bn| as a non-negative DER INTEGER and appends the result
- * to |cbb|. It returns one on success and zero on failure. */
-OPENSSL_EXPORT int BN_bn2cbb(CBB *cbb, const BIGNUM *bn);
+/* BN_marshal_asn1 marshals |bn| as a non-negative DER INTEGER and appends the
+ * result to |cbb|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn);
 
 
 /* Internal functions.
@@ -749,11 +749,11 @@
 
 /* BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If
  * so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It
- * then stores it as |*pmont| and returns it, or NULL on error.
+ * then stores it as |*pmont|. It returns one on success and zero on error.
  *
- * If |*pmont| is already non-NULL then the existing value is returned. */
-BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
-                                    const BIGNUM *mod, BN_CTX *bn_ctx);
+ * If |*pmont| is already non-NULL then it does nothing and returns one. */
+int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
+                           const BIGNUM *mod, BN_CTX *bn_ctx);
 
 /* BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. It
  * returns one on success and zero on error. */
@@ -852,15 +852,6 @@
 #define BN_FLG_CONSTTIME 0x04
 
 
-/* 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 BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
-
-
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 76e3795..f4e315c 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -67,7 +67,7 @@
 /* Memory and string functions, see also mem.h. */
 
 
-/* BUF_MEM is a generic buffer object used by OpenSSL. */
+/* buf_mem_st (aka |BUF_MEM|) is a generic buffer object used by OpenSSL. */
 struct buf_mem_st {
   size_t length; /* current number of bytes */
   char *data;
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 9193e11..68ede2d 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -128,9 +128,21 @@
 #define CBS_ASN1_NULL 0x5
 #define CBS_ASN1_OBJECT 0x6
 #define CBS_ASN1_ENUMERATED 0xa
+#define CBS_ASN1_UTF8STRING 0xc
 #define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
 #define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_NUMERICSTRING 0x12
+#define CBS_ASN1_PRINTABLESTRING 0x13
+#define CBS_ASN1_T16STRING 0x14
+#define CBS_ASN1_VIDEOTEXSTRING 0x15
+#define CBS_ASN1_IA5STRING 0x16
+#define CBS_ASN1_UTCTIME 0x17
 #define CBS_ASN1_GENERALIZEDTIME 0x18
+#define CBS_ASN1_GRAPHICSTRING 0x19
+#define CBS_ASN1_VISIBLESTRING 0x1a
+#define CBS_ASN1_GENERALSTRING 0x1b
+#define CBS_ASN1_UNIVERSALSTRING 0x1c
+#define CBS_ASN1_BMPSTRING 0x1e
 
 #define CBS_ASN1_CONSTRUCTED 0x20
 #define CBS_ASN1_CONTEXT_SPECIFIC 0x80
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index fb7171f..5312308 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -481,7 +481,7 @@
 
   /* num contains the number of bytes of |iv| which are valid for modes that
    * manage partial blocks themselves. */
-  int num;
+  unsigned num;
 
   /* final_used is non-zero if the |final| buffer contains plaintext. */
   int final_used;
diff --git a/src/include/openssl/conf.h b/src/include/openssl/conf.h
index a2741a8..2aa3b79 100644
--- a/src/include/openssl/conf.h
+++ b/src/include/openssl/conf.h
@@ -92,10 +92,10 @@
 
 /* NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method|
  * argument must be NULL. */
-CONF *NCONF_new(void *method);
+OPENSSL_EXPORT CONF *NCONF_new(void *method);
 
 /* NCONF_free frees all the data owned by |conf| and then |conf| itself. */
-void NCONF_free(CONF *conf);
+OPENSSL_EXPORT void NCONF_free(CONF *conf);
 
 /* NCONF_load parses the file named |filename| and adds the values found to
  * |conf|. It returns one on success and zero on error. In the event of an
@@ -131,6 +131,31 @@
                     int (*list_cb)(const char *elem, int len, void *usr),
                     void *arg);
 
+
+/* Deprecated functions */
+
+/* These defines do nothing but are provided to make old code easier to
+ * compile. */
+#define CONF_MFLAGS_DEFAULT_SECTION 0
+#define CONF_MFLAGS_IGNORE_MISSING_FILE 0
+
+typedef struct conf_must_be_null_st CONF_MUST_BE_NULL;
+
+/* CONF_modules_load_file returns one. |filename| was originally a string, with
+ * NULL indicating the default. BoringSSL does not support configuration files,
+ * so this stub emulates the "default" no-op file but intentionally breaks
+ * compilation of consumers actively attempting to use this subsystem. */
+OPENSSL_EXPORT int CONF_modules_load_file(CONF_MUST_BE_NULL *filename,
+                                          const char *appname,
+                                          unsigned long flags);
+
+/* CONF_modules_free does nothing. */
+OPENSSL_EXPORT void CONF_modules_free(void);
+
+/* OPENSSL_config does nothing. */
+OPENSSL_EXPORT void OPENSSL_config(CONF_MUST_BE_NULL *config_name);
+
+
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index e946304..55be4c1 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -110,30 +110,23 @@
 /* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If
  * this is known statically then it returns one immediately. */
 static inline int CRYPTO_is_NEON_capable(void) {
-#if defined(__ARM_NEON__)
+  /* Only statically skip the runtime lookup on aarch64. On arm, one CPU is
+   * known to have a broken NEON unit which is known to fail with on some
+   * hand-written NEON assembly. For now, continue to apply the workaround even
+   * when the compiler is instructed to freely emit NEON code. See
+   * https://crbug.com/341598 and https://crbug.com/606629. */
+#if defined(__ARM_NEON__) && !defined(OPENSSL_ARM)
   return 1;
 #else
   return CRYPTO_is_NEON_capable_at_runtime();
 #endif
 }
 
-/* CRYPTO_set_NEON_capable sets the return value of |CRYPTO_is_NEON_capable|.
- * By default, unless the code was compiled with |-mfpu=neon|, NEON is assumed
- * not to be present. It is not autodetected. Calling this with a zero
- * argument also causes |CRYPTO_is_NEON_functional| to return false. */
-OPENSSL_EXPORT void CRYPTO_set_NEON_capable(char neon_capable);
-
-/* CRYPTO_is_NEON_functional returns true if the current CPU has a /working/
- * NEON unit. Some phones have a NEON unit, but the Poly1305 NEON code causes
- * it to fail. See https://code.google.com/p/chromium/issues/detail?id=341598 */
-OPENSSL_EXPORT char CRYPTO_is_NEON_functional(void);
-
-/* CRYPTO_set_NEON_functional sets the "NEON functional" flag. For
- * |CRYPTO_is_NEON_functional| to return true, both this flag and the NEON flag
- * must be true. By default NEON is assumed to be functional if the code was
- * compiled with |-mfpu=neon| or if |CRYPTO_set_NEON_capable| has been called
- * with a non-zero argument. */
-OPENSSL_EXPORT void CRYPTO_set_NEON_functional(char neon_functional);
+#if defined(OPENSSL_ARM)
+/* CRYPTO_has_broken_NEON returns one if the current CPU is known to have a
+ * broken NEON unit. See https://crbug.com/341598. */
+OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void);
+#endif
 
 /* CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the
  * ARMv8 AES instruction. */
@@ -153,10 +146,6 @@
 #endif
 }
 
-static inline int CRYPTO_is_NEON_functional(void) {
-  return CRYPTO_is_NEON_capable();
-}
-
 static inline int CRYPTO_is_ARMv8_AES_capable(void) {
 #if defined(OPENSSL_STATIC_ARMCAP_AES)
   return 1;
@@ -174,7 +163,7 @@
 }
 
 #endif  /* OPENSSL_STATIC_ARMCAP */
-#endif  /* OPENSSL_ARM */
+#endif  /* OPENSSL_ARM || OPENSSL_AARCH64 */
 
 
 #if defined(__cplusplus)
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index b421884..b52bcf8 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -36,13 +36,19 @@
 
 /* CRYPTO_library_init initializes the crypto library. It must be called if the
  * library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does
- * nothing and a static initializer is used instead. */
+ * nothing and a static initializer is used instead. It is safe to call this
+ * function multiple times and concurrently from multiple threads.
+ *
+ * On some ARM configurations, this function may require filesystem access and
+ * should be called before entering a sandbox. */
 OPENSSL_EXPORT void CRYPTO_library_init(void);
 
 
 /* Deprecated functions. */
 
-#define OPENSSL_VERSION_TEXT "BoringSSL"
+/* OPENSSL_VERSION_TEXT contains a string the identifies the version of
+ * “OpenSSL”. node.js requires a version number in this text. */
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2 (compatible; BoringSSL)"
 
 #define SSLEAY_VERSION 0
 
@@ -60,6 +66,12 @@
 /* ENGINE_load_builtin_engines does nothing. */
 OPENSSL_EXPORT void ENGINE_load_builtin_engines(void);
 
+/* OPENSSL_load_builtin_modules does nothing. */
+OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void);
+
+/* FIPS_mode returns zero. */
+OPENSSL_EXPORT int FIPS_mode(void);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h
index 30c6470..a9441cd 100644
--- a/src/include/openssl/curve25519.h
+++ b/src/include/openssl/curve25519.h
@@ -24,16 +24,14 @@
 
 /* Curve25519.
  *
- * Curve25519 is an elliptic curve. See
- * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */
+ * Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. */
 
 
 /* X25519.
  *
- * Curve25519 is an elliptic curve. The same name is also sometimes used for
- * the Diffie-Hellman primitive built from it but “X25519” is a more precise
- * name for that, which is the one used here. See http://cr.yp.to/ecdh.html and
- * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */
+ * X25519 is the Diffie-Hellman primitive built from curve25519. It is
+ * sometimes referred to as “curve25519”, but “X25519” is a more precise name.
+ * See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. */
 
 /* X25519_keypair sets |out_public_value| and |out_private_key| to a freshly
  * generated, public–private key pair. */
@@ -85,6 +83,88 @@
                                   const uint8_t public_key[32]);
 
 
+/* SPAKE2.
+ *
+ * SPAKE2 is a password-authenticated key-exchange. It allows two parties,
+ * who share a low-entropy secret (i.e. password), to agree on a shared key.
+ * An attacker can only make one guess of the password per execution of the
+ * protocol.
+ *
+ * See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. */
+
+/* spake2_role_t enumerates the different “roles” in SPAKE2. The protocol
+ * requires that the symmetry of the two parties be broken so one participant
+ * must be “Alice” and the other be “Bob”. */
+enum spake2_role_t {
+  spake2_role_alice,
+  spake2_role_bob,
+};
+
+/* SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a
+ * single execution of the protocol). SPAKE2 requires the symmetry of the two
+ * parties to be broken which is indicated via |my_role| – each party must pass
+ * a different value for this argument.
+ *
+ * The |my_name| and |their_name| arguments allow optional, opaque names to be
+ * bound into the protocol. For example MAC addresses, hostnames, usernames
+ * etc. These values are not exposed and can avoid context-confusion attacks
+ * when a password is shared between several devices. */
+OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new(
+    enum spake2_role_t my_role,
+    const uint8_t *my_name, size_t my_name_len,
+    const uint8_t *their_name, size_t their_name_len);
+
+/* SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. */
+OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx);
+
+/* SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. */
+#define SPAKE2_MAX_MSG_SIZE 32
+
+/* SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes
+ * it to |out| and sets |*out_len| to the number of bytes written.
+ *
+ * At most |max_out_len| bytes are written to |out| and, in order to ensure
+ * success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes.
+ *
+ * This function can only be called once for a given |SPAKE2_CTX|.
+ *
+ * It returns one on success and zero on error. */
+OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out,
+                                       size_t *out_len, size_t max_out_len,
+                                       const uint8_t *password,
+                                       size_t password_len);
+
+/* SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will
+ * produce. */
+#define SPAKE2_MAX_KEY_SIZE 64
+
+/* SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in
+ * |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets
+ * |*out_key_len| to the number of bytes written.
+ *
+ * The resulting keying material is suitable for:
+ *   a) Using directly in a key-confirmation step: i.e. each side could
+ *      transmit a hash of their role, a channel-binding value and the key
+ *      material to prove to the other side that they know the shared key.
+ *   b) Using as input keying material to HKDF to generate a variety of subkeys
+ *      for encryption etc.
+ *
+ * If |max_out_key_key| is smaller than the amount of key material generated
+ * then the key is silently truncated. If you want to ensure that no truncation
+ * occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|.
+ *
+ * You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling
+ * this function. On successful return, |ctx| is complete and calling
+ * |SPAKE2_CTX_free| is the only acceptable operation on it.
+ *
+ * Returns one on success or zero on error. */
+OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key,
+                                      size_t *out_key_len,
+                                      size_t max_out_key_len,
+                                      const uint8_t *their_msg,
+                                      size_t their_msg_len);
+
+
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 2c49fc8..5cdeb86 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -156,8 +156,9 @@
  * Note: these checks may be quite computationally expensive. */
 OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags);
 
-#define DH_CHECK_PUBKEY_TOO_SMALL 1
-#define DH_CHECK_PUBKEY_TOO_LARGE 2
+#define DH_CHECK_PUBKEY_TOO_SMALL 0x1
+#define DH_CHECK_PUBKEY_TOO_LARGE 0x2
+#define DH_CHECK_PUBKEY_INVALID 0x4
 
 /* DH_check_pub_key checks the suitability of |pub_key| as a public key for the
  * DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it
@@ -177,7 +178,10 @@
  * structure from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a
  * pointer to the result is in |*ret|. If |*ret| is already non-NULL on entry
  * then the result is written directly into |*ret|, otherwise a fresh |DH| is
- * allocated. On successful exit, |*inp| is advanced past the DER structure. It
+ * allocated. However, one should not depend on writing into |*ret| because
+ * this behaviour is likely to change in the future.
+ *
+ * On successful exit, |*inp| is advanced past the DER structure. It
  * returns the result or NULL on error. */
 OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len);
 
@@ -200,6 +204,16 @@
 OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx);
 
 
+/* Deprecated functions. */
+
+/* DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is
+ * what you should use instead. It returns NULL on error, or a newly-allocated
+ * |DH| on success. This function is provided for compatibility only. */
+OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator,
+                                          void (*callback)(int, int, void *),
+                                          void *cb_arg);
+
+
 struct dh_st {
   BIGNUM *p;
   BIGNUM *g;
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 80028ef..db3ead7 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -143,6 +143,9 @@
  * at least this much space. */
 #define EVP_MAX_MD_SIZE 64 /* SHA-512 is the longest so far. */
 
+/* EVP_MAX_MD_BLOCK_SIZE is the largest digest block size supported, in bytes. */
+#define EVP_MAX_MD_BLOCK_SIZE 128 /* SHA-512 is the longest so far. */
+
 /* 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.
@@ -218,11 +221,11 @@
 
 /* EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It
  * will crash if a digest hasn't been set on |ctx|. */
-OPENSSL_EXPORT unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_block_size returns the block size of the digest function used by
  * |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. */
-OPENSSL_EXPORT unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
  * (For example, |NID_sha256|.) It will crash if a digest hasn't been set on
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 2045fe7..0077a72 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -128,7 +128,7 @@
 
 /* Signatures. */
 
-/* DSA_SIG contains a DSA signature as a pair of integers. */
+/* DSA_SIG_st (aka |DSA_SIG|) contains a DSA signature as a pair of integers. */
 typedef struct DSA_SIG_st {
   BIGNUM *r, *s;
 } DSA_SIG;
@@ -218,62 +218,41 @@
 
 /* ASN.1 encoding. */
 
-/* d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at
- * |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is
- * in |*out_sig|. If |*out_sig| is already non-NULL on entry then the result is
- * written directly into |*out_sig|, otherwise a fresh |DSA_SIG| is allocated.
- * On successful exit, |*inp| is advanced past the DER structure. It returns
- * the result or NULL on error. */
-OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp,
-                                    long len);
+/* DSA_SIG_parse parses a DER-encoded DSA-Sig-Value structure from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA_SIG| or NULL on error. */
+OPENSSL_EXPORT DSA_SIG *DSA_SIG_parse(CBS *cbs);
 
-/* i2d_DSA_SIG marshals |in| to an ASN.1, DER structure. If |outp| is not NULL
- * then the result is written to |*outp| and |*outp| is advanced just past the
- * output. It returns the number of bytes in the result, whether written or not,
- * or a negative value on error. */
-OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
+/* DSA_SIG_marshal marshals |sig| as a DER-encoded DSA-Sig-Value and appends the
+ * result to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig);
 
-/* d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |DSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_public_key parses a DER-encoded DSA public key from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. */
+OPENSSL_EXPORT DSA *DSA_parse_public_key(CBS *cbs);
 
-/* i2d_DSAPublicKey marshals a public key from |in| to an ASN.1, DER structure.
- * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
- * advanced just past the output. It returns the number of bytes in the result,
- * whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, unsigned char **outp);
+/* DSA_marshal_public_key marshals |dsa| as a DER-encoded DSA public key and
+ * appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int DSA_marshal_public_key(CBB *cbb, const DSA *dsa);
 
-/* d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |DSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_private_key parses a DER-encoded DSA private key from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. */
+OPENSSL_EXPORT DSA *DSA_parse_private_key(CBS *cbs);
 
-/* i2d_DSAPrivateKey marshals a private key from |in| to an ASN.1, DER structure.
- * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
- * advanced just past the output. It returns the number of bytes in the result,
- * whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, unsigned char **outp);
+/* DSA_marshal_private_key marshals |dsa| as a DER-encoded DSA private key and
+ * appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int DSA_marshal_private_key(CBB *cbb, const DSA *dsa);
 
-/* d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at
- * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
- * |*out|. If |*out| is already non-NULL on entry then the result is written
- * directly into |*out|, otherwise a fresh |DSA| is allocated. On successful
- * exit, |*inp| is advanced past the DER structure. It returns the result or
- * NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_parameters parses a DER-encoded Dss-Parms structure (RFC 3279)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |DSA| or NULL on
+ * error. */
+OPENSSL_EXPORT DSA *DSA_parse_parameters(CBS *cbs);
 
-/* i2d_DSAparams marshals DSA parameters from |in| to an ASN.1, DER structure.
- * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
- * advanced just past the output. It returns the number of bytes in the result,
- * whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, unsigned char **outp);
+/* DSA_marshal_parameters marshals |dsa| as a DER-encoded Dss-Parms structure
+ * (RFC 3447) and appends the result to |cbb|. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int DSA_marshal_parameters(CBB *cbb, const DSA *dsa);
 
 
 /* Precomputation. */
@@ -309,9 +288,93 @@
 OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *d, int idx);
 
 
+/* Deprecated functions. */
+
+/* d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at
+ * |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is
+ * in |*out_sig|. Note that, even if |*out_sig| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |DSA_SIG| is allocated and the
+ * previous one is freed. On successful exit, |*inp| is advanced past the DER
+ * structure. It returns the result or NULL on error.
+ *
+ * Use |DSA_SIG_parse| instead. */
+OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp,
+                                    long len);
+
+/* i2d_DSA_SIG marshals |in| to an ASN.1, DER structure. If |outp| is not NULL
+ * then the result is written to |*outp| and |*outp| is advanced just past the
+ * output. It returns the number of bytes in the result, whether written or not,
+ * or a negative value on error.
+ *
+ * Use |DSA_SIG_marshal| instead. */
+OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
+
+/* d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. Note that, even if |*ou| is already non-NULL on entry, it will
+ * not be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_public_key| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAPublicKey marshals a public key from |in| to an ASN.1, DER structure.
+ * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
+ * advanced just past the output. It returns the number of bytes in the result,
+ * whether written or not, or a negative value on error.
+ *
+ * Use |DSA_marshal_public_key| instead. */
+OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, uint8_t **outp);
+
+/* d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it will
+ * not be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_private_key| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAPrivateKey marshals a private key from |in| to an ASN.1, DER structure.
+ * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
+ * advanced just past the output. It returns the number of bytes in the result,
+ * whether written or not, or a negative value on error.
+ *
+ * Use |DSA_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp);
+
+/* d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at
+ * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_parameters| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAparams marshals DSA parameters from |in| to an ASN.1, DER structure.
+ * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
+ * advanced just past the output. It returns the number of bytes in the result,
+ * whether written or not, or a negative value on error.
+ *
+ * Use |DSA_marshal_parameters| instead. */
+OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, uint8_t **outp);
+
+/* DSA_generate_parameters is a deprecated version of
+ * |DSA_generate_parameters_ex| that creates and returns a |DSA*|. Don't use
+ * it. */
+OPENSSL_EXPORT DSA *DSA_generate_parameters(int bits, unsigned char *seed,
+                                            int seed_len, int *counter_ret,
+                                            unsigned long *h_ret,
+                                            void (*callback)(int, int, void *),
+                                            void *cb_arg);
+
+
 struct dsa_st {
   long version;
-  int write_params;
   BIGNUM *p;
   BIGNUM *q; /* == 20 */
   BIGNUM *g;
@@ -339,5 +402,8 @@
 #define DSA_R_MISSING_PARAMETERS 101
 #define DSA_R_MODULUS_TOO_LARGE 102
 #define DSA_R_NEED_NEW_SETUP_VALUES 103
+#define DSA_R_BAD_VERSION 104
+#define DSA_R_DECODE_ERROR 105
+#define DSA_R_ENCODE_ERROR 106
 
 #endif  /* OPENSSL_HEADER_DSA_H */
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 667be3b..143aa96 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -81,14 +81,24 @@
 typedef struct ec_group_st EC_GROUP;
 typedef struct ec_point_st EC_POINT;
 
-/** Enum for the point conversion form as defined in X9.62 (ECDSA)
- *  for the encoding of a elliptic curve point (x,y) */
+/* point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for
+ * the encoding of a elliptic curve point (x,y) */
 typedef enum {
-	/** the point is encoded as z||x, where the octet z specifies 
-	 *  which solution of the quadratic equation y is  */
-	POINT_CONVERSION_COMPRESSED = 2,
-	/** the point is encoded as z||x||y, where z is the octet 0x04  */
-	POINT_CONVERSION_UNCOMPRESSED = 4
+  /* POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x,
+   * where the octet z specifies which solution of the quadratic equation y
+   * is. */
+  POINT_CONVERSION_COMPRESSED = 2,
+
+  /* POINT_CONVERSION_COMPRESSED indicates that the point is encoded as
+   * z||x||y, where z is the octet 0x04. */
+  POINT_CONVERSION_UNCOMPRESSED = 4,
+
+  /* POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y,
+   * where z specifies which solution of the quadratic equation y is. This is
+   * not supported by the code and has never been observed in use.
+   *
+   * TODO(agl): remove once node.js no longer references this. */
+  POINT_CONVERSION_HYBRID = 6,
 } point_conversion_form_t;
 
 
@@ -179,12 +189,13 @@
                                            const EC_POINT *point);
 
 /* EC_POINT_is_on_curve returns one if |point| is an element of |group| and
- * zero otheriwse. If |ctx| is non-NULL, it may be used. */
+ * and zero otherwise or when an error occurs. This is different from OpenSSL,
+ * which returns -1 on error. If |ctx| is non-NULL, it may be used. */
 OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group,
                                         const EC_POINT *point, BN_CTX *ctx);
 
-/* EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero is
- * non-equal and -1 on error. If |ctx| is not NULL, it may be used. */
+/* EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if
+ * not equal and -1 on error. If |ctx| is not NULL, it may be used. */
 OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a,
                                 const EC_POINT *b, BN_CTX *ctx);
 
@@ -210,10 +221,10 @@
                                                        BIGNUM *x, BIGNUM *y,
                                                        BN_CTX *ctx);
 
-/* EC_POINT_set_affine_coordinates_GFp sets the value of |p| to be (|x|, |y|).
- * The |ctx| argument may be used if not NULL. It returns one on success or
- * zero on error. Note that, unlike with OpenSSL, it's considered an error if
- * the point is not on the curve. */
+/* EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be
+ * (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one
+ * on success or zero on error. Note that, unlike with OpenSSL, it's
+ * considered an error if the point is not on the curve. */
 OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
                                                        EC_POINT *point,
                                                        const BIGNUM *x,
@@ -229,6 +240,13 @@
                                          point_conversion_form_t form,
                                          uint8_t *buf, size_t len, BN_CTX *ctx);
 
+/* EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the
+ * serialised point to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group,
+                                      const EC_POINT *point,
+                                      point_conversion_form_t form,
+                                      BN_CTX *ctx);
+
 /* EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format
  * serialisation in |buf|. It returns one on success and zero otherwise. The
  * |ctx| argument may be used if not NULL. */
@@ -275,27 +293,43 @@
  * on the equation y² = x³ + a·x + b. It returns the new group or NULL on
  * error.
  *
+ * This new group has no generator. It is an error to use a generator-less group
+ * with any functions except for |EC_GROUP_free|, |EC_POINT_new|,
+ * |EC_POINT_set_affine_coordinates_GFp|, and |EC_GROUP_set_generator|.
+ *
  * |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|. */
+ * return |NID_undef|.
+ *
+ * Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| instead. */
 OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p,
                                                 const BIGNUM *a,
                                                 const BIGNUM *b, BN_CTX *ctx);
 
+/* EC_GROUP_set_generator sets the generator for |group| to |generator|, which
+ * must have the given order and cofactor. It may only be used with |EC_GROUP|
+ * objects returned by |EC_GROUP_new_curve_GFp| and may only be used once on
+ * each group. */
+OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,
+                                          const EC_POINT *generator,
+                                          const BIGNUM *order,
+                                          const BIGNUM *cofactor);
+
+/* EC_GROUP_new_arbitrary calls |EC_GROUP_new_curve_GFp| and
+ * |EC_GROUP_set_generator|.
+ *
+ * TODO(davidben): Remove this once
+ * https://android-review.googlesource.com/#/c/207990/ has cycled in. */
+OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_arbitrary(
+    const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, const BIGNUM *gx,
+    const BIGNUM *gy, const BIGNUM *order, const BIGNUM *cofactor);
+
 /* EC_GROUP_get_order sets |*order| to the order of |group|, if it's not
  * NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use
  * |EC_GROUP_get0_order| instead. */
 OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order,
                                       BN_CTX *ctx);
 
-/* EC_GROUP_set_generator sets the generator for |group| to |generator|, which
- * must have the given order and cofactor. This should only be used with
- * |EC_GROUP| objects returned by |EC_GROUP_new_curve_GFp|. */
-OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,
-                                          const EC_POINT *generator,
-                                          const BIGNUM *order,
-                                          const BIGNUM *cofactor);
-
 /* EC_GROUP_set_asn1_flag does nothing. */
 OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
 
@@ -314,6 +348,19 @@
 OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
     EC_GROUP *group, point_conversion_form_t form);
 
+/* EC_builtin_curve describes a supported elliptic curve. */
+typedef struct {
+  int nid;
+  const char *comment;
+} EC_builtin_curve;
+
+/* EC_get_builtin_curves writes at most |max_num_curves| elements to
+ * |out_curves| and returns the total number that it would have written, had
+ * |max_num_curves| been large enough.
+ *
+ * The |EC_builtin_curve| items describe the supported elliptic curves. */
+OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
+                                            size_t max_num_curves);
 
 /* Old code expects to get EC_KEY from ec.h. */
 #include <openssl/ec_key.h>
@@ -351,5 +398,8 @@
 #define EC_R_WRONG_ORDER 125
 #define EC_R_BIGNUM_OUT_OF_RANGE 126
 #define EC_R_WRONG_CURVE_PARAMETERS 127
+#define EC_R_DECODE_ERROR 128
+#define EC_R_ENCODE_ERROR 129
+#define EC_R_GROUP_MISMATCH 130
 
 #endif  /* OPENSSL_HEADER_EC_H */
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index afd95d6..63554a7 100644
--- a/src/include/openssl/ec_key.h
+++ b/src/include/openssl/ec_key.h
@@ -177,48 +177,37 @@
 
 /* Serialisation. */
 
-/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes
- * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result
- * is in |*out_key|. If |*out_key| is already non-NULL on entry then the result
- * is written directly into |*out_key|, otherwise a fresh |EC_KEY| is
- * allocated. On successful exit, |*inp| is advanced past the DER structure. It
- * returns the result or NULL on error. */
-OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
-                                        long len);
+/* EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC
+ * 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or
+ * NULL on error. If |group| is non-null, the parameters field of the
+ * ECPrivateKey may be omitted (but must match |group| if present). Otherwise,
+ * the parameters field is required. */
+OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs,
+                                                const EC_GROUP *group);
 
-/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER
- * structure. If |outp| is not NULL then the result is written to |*outp| and
- * |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
+/* EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey
+ * structure (RFC 5915) and appends the result to |cbb|. It returns one on
+ * success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*|
+ * values and controls whether corresponding fields are omitted. */
+OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
+                                              unsigned enc_flags);
 
-/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from
- * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to
- * the result is in |*out_key|. If |*out_key| is already non-NULL on entry then
- * the result is written directly into |*out_key|, otherwise a fresh |EC_KEY|
- * is allocated. On successful exit, |*inp| is advanced past the DER structure.
- * It returns the result or NULL on error. */
-OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp,
-                                        long len);
+/* EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve
+ * name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP|
+ * or NULL on error. */
+OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs);
 
-/* i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER
- * structure. If |outp| is not NULL then the result is written to |*outp| and
- * |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
+/* EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER
+ * and appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group);
 
-/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into
- * |*out_key|. Note that this differs from the d2i format in that |*out_key|
- * must be non-NULL with a group set. On successful exit, |*inp| is advanced by
- * |len| bytes. It returns |*out_key| or NULL on error. */
-OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
-                                       long len);
-
-/* i2o_ECPublicKey marshals an EC point from |key|. If |outp| is not NULL then
- * the result is written to |*outp| and |*outp| is advanced just past the
- * output. It returns the number of bytes in the result, whether written or
- * not, or a negative value on error. */
-OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
+/* EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC
+ * 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP|
+ * or NULL on error. It supports the namedCurve and specifiedCurve options, but
+ * use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name|
+ * instead. */
+OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs);
 
 
 /* ex_data functions.
@@ -259,7 +248,7 @@
   int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig,
               unsigned int *sig_len, EC_KEY *eckey);
 
-  /* verify matches the arguments and behaviour of |ECDSA_verify|. */
+  /* Ignored. Set this to NULL. */
   int (*verify)(const uint8_t *digest, size_t digest_len, const uint8_t *sig,
                 size_t sig_len, EC_KEY *eckey);
 
@@ -272,6 +261,64 @@
 /* EC_KEY_set_asn1_flag does nothing. */
 OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag);
 
+/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes
+ * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result
+ * is in |*out_key|. Note that, even if |*out_key| is already non-NULL on entry,
+ * it * will not be written to. Rather, a fresh |EC_KEY| is allocated and the
+ * previous * one is freed. On successful exit, |*inp| is advanced past the DER
+ * structure. It returns the result or NULL on error.
+ *
+ * On input, if |*out_key| is non-NULL and has a group configured, the
+ * parameters field may be omitted but must match that group if present.
+ *
+ * Use |EC_KEY_parse_private_key| instead. */
+OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
+                                        long len);
+
+/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER
+ * structure. If |outp| is not NULL then the result is written to |*outp| and
+ * |*outp| is advanced just past the output. It returns the number of bytes in
+ * the result, whether written or not, or a negative value on error.
+ *
+ * Use |EC_KEY_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
+
+/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from
+ * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to
+ * the result is in |*out_key|. Note that, even if |*out_key| is already
+ * non-NULL on entry, it will not be written to. Rather, a fresh |EC_KEY| is
+ * allocated and the previous one is freed. On successful exit, |*inp| is
+ * advanced past the DER structure. It returns the result or NULL on error.
+ *
+ * Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. */
+OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp,
+                                        long len);
+
+/* i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER
+ * structure. If |outp| is not NULL then the result is written to |*outp| and
+ * |*outp| is advanced just past the output. It returns the number of bytes in
+ * the result, whether written or not, or a negative value on error.
+ *
+ * Use |EC_KEY_marshal_curve_name| instead. */
+OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
+
+/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into
+ * |*out_key|. Note that this differs from the d2i format in that |*out_key|
+ * must be non-NULL with a group set. On successful exit, |*inp| is advanced by
+ * |len| bytes. It returns |*out_key| or NULL on error.
+ *
+ * Use |EC_POINT_oct2point| instead. */
+OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
+                                       long len);
+
+/* i2o_ECPublicKey marshals an EC point from |key|. If |outp| is not NULL then
+ * the result is written to |*outp| and |*outp| is advanced just past the
+ * output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error.
+ *
+ * Use |EC_POINT_point2cbb| instead. */
+OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index f3f68eb..a060eab 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -178,10 +178,10 @@
 
 /* d2i_ECDSA_SIG parses an ASN.1, DER-encoded, signature from |len| bytes at
  * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
- * |*out|. If |*out| is already non-NULL on entry then the result is written
- * directly into |*out|, otherwise a fresh |ECDSA_SIG| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |ECDSA_SIG| is allocated and the previous one
+ * is freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error. */
 OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp,
                                         long len);
 
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 40361d7..cac50e0 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -317,7 +317,8 @@
 
 /* ERR_add_error_dataf takes a printf-style format and arguments, and sets the
  * result as the data on the most recent error. */
-OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...);
+OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...)
+    OPENSSL_PRINTF_FORMAT_FUNC(1, 2);
 
 /* ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|.
  * It returns one if an error was marked and zero if there are no errors. */
@@ -367,7 +368,7 @@
 /* ERR_NUM_ERRORS is the limit of the number of errors in the queue. */
 #define ERR_NUM_ERRORS 16
 
-/* ERR_STATE contains the per-thread, error queue. */
+/* err_state_st (aka |ERR_STATE|) contains the per-thread, error queue. */
 typedef struct err_state_st {
   /* errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
    * buffer. */
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index be2ea33..398c741 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -69,7 +69,7 @@
 #include <openssl/base64.h>
 #include <openssl/cipher.h>
 #include <openssl/digest.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -133,8 +133,8 @@
  * values. */
 OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
 
-/* EVP_PKEY_type returns a canonicalised form of |NID|. For example,
- * |EVP_PKEY_RSA2| will be turned into |EVP_PKEY_RSA|. */
+/* EVP_PKEY_type returns |nid| if |nid| is a known key type and |NID_undef|
+ * otherwise. */
 OPENSSL_EXPORT int EVP_PKEY_type(int nid);
 
 
@@ -165,7 +165,6 @@
 
 #define EVP_PKEY_NONE NID_undef
 #define EVP_PKEY_RSA NID_rsaEncryption
-#define EVP_PKEY_RSA2 NID_rsa
 #define EVP_PKEY_DSA NID_dsa
 #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
 
@@ -189,34 +188,37 @@
 
 /* ASN.1 functions */
 
-/* d2i_PrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes at
- * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
- * |*out|. If |*out| is already non-NULL on entry then the result is written
- * directly into |*out|, otherwise a fresh |EVP_PKEY| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
-                                        const uint8_t **inp, long len);
-
-/* d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type
- * of the private key. */
-OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
-                                            long len);
-
-/* i2d_PrivateKey marshals a private key from |key| to an ASN.1, DER
- * structure. If |outp| is not NULL then the result is written to |*outp| and
- * |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
-
-/* i2d_PublicKey marshals a public key from |key| to a type-specific format.
- * If |outp| is not NULL then the result is written to |*outp| and
- * |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error.
+/* EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure
+ * (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated
+ * |EVP_PKEY| or NULL on error.
  *
- * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
- * EC keys are serialized as an EC point per SEC 1. */
-OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
+ * The caller must check the type of the parsed public key to ensure it is
+ * suitable and validate other desired key properties such as RSA modulus size
+ * or EC curve. */
+OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs);
+
+/* EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo
+ * structure (RFC 5280) and appends the result to |cbb|. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key);
+
+/* EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC
+ * 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY|
+ * or NULL on error.
+ *
+ * The caller must check the type of the parsed private key to ensure it is
+ * suitable and validate other desired key properties such as RSA modulus size
+ * or EC curve.
+ *
+ * A PrivateKeyInfo ends with an optional set of attributes. These are not
+ * processed and so this function will silently ignore any trailing data in the
+ * structure. */
+OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs);
+
+/* EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo
+ * structure (RFC 5208) and appends the result to |cbb|. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key);
 
 
 /* Signing */
@@ -248,15 +250,6 @@
 OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
                                        size_t *out_sig_len);
 
-/* EVP_DigestSignAlgorithm encodes the signing parameters of |ctx| as an
- * AlgorithmIdentifer and saves the result in |algor|.
- *
- * It returns one on success, or zero on error.
- *
- * TODO(davidben): This API should eventually lose the dependency on
- * crypto/asn1/. */
-OPENSSL_EXPORT int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor);
-
 
 /* Verifying */
 
@@ -271,18 +264,6 @@
                                         const EVP_MD *type, ENGINE *e,
                                         EVP_PKEY *pkey);
 
-/* EVP_DigestVerifyInitFromAlgorithm sets up |ctx| for a signature verification
- * operation with public key |pkey| and parameters from |algor|. The |ctx|
- * argument must have been initialised with |EVP_MD_CTX_init|.
- *
- * It returns one on success, or zero on error.
- *
- * TODO(davidben): This API should eventually lose the dependency on
- * crypto/asn1/. */
-OPENSSL_EXPORT int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
-                                                     X509_ALGOR *algor,
-                                                     EVP_PKEY *pkey);
-
 /* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
  * will be verified by |EVP_DigestVerifyFinal|. It returns one. */
 OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
@@ -427,14 +408,6 @@
 /* EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. */
 OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
 
-/* EVP_PKEY_CTX_set_app_data sets an opaque pointer on |ctx|. */
-OPENSSL_EXPORT void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
-
-/* EVP_PKEY_CTX_get_app_data returns the opaque pointer from |ctx| that was
- * previously set with |EVP_PKEY_CTX_set_app_data|, or NULL if none has been
- * set. */
-OPENSSL_EXPORT void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
-
 /* EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It
  * should be called before |EVP_PKEY_sign|.
  *
@@ -510,6 +483,34 @@
                                     size_t *out_len, const uint8_t *in,
                                     size_t in_len);
 
+/* EVP_PKEY_verify_recover_init initialises an |EVP_PKEY_CTX| for a public-key
+ * decryption operation. It should be called before |EVP_PKEY_verify_recover|.
+ *
+ * Public-key decryption is a very obscure operation that is only implemented
+ * by RSA keys. It is effectively a signature verification operation that
+ * returns the signed message directly. It is almost certainly not what you
+ * want.
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+
+/* EVP_PKEY_verify_recover decrypts |sig_len| bytes from |sig|. If |out| is
+ * NULL, the maximum size of the plaintext is written to |out_len|. Otherwise,
+ * |*out_len| must contain the number of bytes of space available at |out|. If
+ * sufficient, the ciphertext will be written to |out| and |*out_len| updated
+ * with the true length.
+ *
+ * WARNING: Setting |out| to NULL only gives the maximum size of the
+ * plaintext. The actual plaintext may be smaller.
+ *
+ * See the warning about this operation in |EVP_PKEY_verify_recover_init|. It
+ * is probably not what you want.
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
+                                           size_t *out_len, const uint8_t *sig,
+                                           size_t siglen);
+
 /* EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation
  * operation. It should be called before |EVP_PKEY_derive_set_peer| and
  * |EVP_PKEY_derive|.
@@ -628,7 +629,7 @@
  *
  * Returns one on success or zero on error. */
 OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
-                                                    const uint8_t *label,
+                                                    uint8_t *label,
                                                     size_t label_len);
 
 /* EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal
@@ -646,6 +647,10 @@
  * |EVP_PKEY| of that type. */
 #define EVP_PKEY_DH NID_dhKeyAgreement
 
+/* EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID
+ * 2.5.8.1.1), but is no longer accepted. */
+#define EVP_PKEY_RSA2 NID_rsa
+
 /* OpenSSL_add_all_algorithms does nothing. */
 OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void);
 
@@ -658,22 +663,63 @@
 /* EVP_cleanup does nothing. */
 OPENSSL_EXPORT void EVP_cleanup(void);
 
+OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted(
+    void (*callback)(const EVP_CIPHER *cipher, const char *name,
+                     const char *unused, void *arg),
+    void *arg);
 
-/* Private functions */
+OPENSSL_EXPORT void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
+                                                          const char *name,
+                                                          const char *unused,
+                                                          void *arg),
+                                         void *arg);
 
-/* EVP_PKEY_asn1_find returns the ASN.1 method table for the given |nid|, which
- * should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
- * unknown. */
-OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine,
-                                                              int nid);
-
-/* EVP_PKEY_asn1_find_str returns an |EVP_PKEY_ASN1_METHOD| by matching values
- * of the |len| bytes at |name|. For example, if name equals "EC" then it will
- * return an ECC method. The |pengine| argument is ignored.
+/* i2d_PrivateKey marshals a private key from |key| to an ASN.1, DER
+ * structure. If |outp| is not NULL then the result is written to |*outp| and
+ * |*outp| is advanced just past the output. It returns the number of bytes in
+ * the result, whether written or not, or a negative value on error.
  *
- * TODO(fork): move to PEM? */
-OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(
-    ENGINE **pengine, const char *name, size_t len);
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as a DER-encoded ECPrivateKey (RFC 5915) structure.
+ *
+ * Use |RSA_marshal_private_key| or |EC_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
+
+/* i2d_PublicKey marshals a public key from |key| to a type-specific format.
+ * If |outp| is not NULL then the result is written to |*outp| and
+ * |*outp| is advanced just past the output. It returns the number of bytes in
+ * the result, whether written or not, or a negative value on error.
+ *
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as an EC point per SEC 1.
+ *
+ * Use |RSA_marshal_public_key| or |EC_POINT_point2cbb| instead. */
+OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
+
+/* d2i_PrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes at
+ * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |EVP_PKEY| is allocated and the previous one
+ * is freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * This function tries to detect one of several formats. Instead, use
+ * |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an
+ * RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. */
+OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
+                                        const uint8_t **inp, long len);
+
+/* d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type
+ * of the private key.
+ *
+ * This function tries to detect one of several formats. Instead, use
+ * |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an
+ * RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. */
+OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
+                                            long len);
+
+
+/* Private structures. */
 
 struct evp_pkey_st {
   CRYPTO_refcount_t references;
@@ -702,49 +748,33 @@
 
 #define EVP_R_BUFFER_TOO_SMALL 100
 #define EVP_R_COMMAND_NOT_SUPPORTED 101
-#define EVP_R_DIFFERENT_KEY_TYPES 104
-#define EVP_R_DIFFERENT_PARAMETERS 105
-#define EVP_R_EXPECTING_AN_EC_KEY_KEY 107
-#define EVP_R_EXPECTING_A_DH_KEY 109
-#define EVP_R_EXPECTING_A_DSA_KEY 110
-#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 111
-#define EVP_R_INVALID_CURVE 112
-#define EVP_R_INVALID_DIGEST_LENGTH 113
-#define EVP_R_INVALID_DIGEST_TYPE 114
-#define EVP_R_INVALID_KEYBITS 115
-#define EVP_R_INVALID_MGF1_MD 116
-#define EVP_R_INVALID_PADDING_MODE 118
-#define EVP_R_INVALID_PSS_PARAMETERS 119
-#define EVP_R_INVALID_SALT_LENGTH 121
-#define EVP_R_INVALID_TRAILER 122
-#define EVP_R_KEYS_NOT_SET 123
-#define EVP_R_MISSING_PARAMETERS 124
-#define EVP_R_NO_DEFAULT_DIGEST 125
-#define EVP_R_NO_KEY_SET 126
-#define EVP_R_NO_MDC2_SUPPORT 127
-#define EVP_R_NO_NID_FOR_CURVE 128
-#define EVP_R_NO_OPERATION_SET 129
-#define EVP_R_NO_PARAMETERS_SET 130
-#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 131
-#define EVP_R_OPERATON_NOT_INITIALIZED 132
-#define EVP_R_UNKNOWN_DIGEST 133
-#define EVP_R_UNKNOWN_MASK_DIGEST 134
-#define EVP_R_UNSUPPORTED_ALGORITHM 138
-#define EVP_R_UNSUPPORTED_MASK_ALGORITHM 139
-#define EVP_R_UNSUPPORTED_MASK_PARAMETER 140
-#define EVP_R_EXPECTING_AN_RSA_KEY 141
-#define EVP_R_INVALID_OPERATION 142
-#define EVP_R_DECODE_ERROR 143
-#define EVP_R_INVALID_PSS_SALTLEN 144
-#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 145
-#define EVP_R_CONTEXT_NOT_INITIALISED 146
-#define EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 147
-#define EVP_R_WRONG_PUBLIC_KEY_TYPE 148
-#define EVP_R_UNKNOWN_SIGNATURE_ALGORITHM 149
-#define EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 150
-#define EVP_R_BN_DECODE_ERROR 151
-#define EVP_R_PARAMETER_ENCODING_ERROR 152
-#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 153
-#define EVP_R_UNSUPPORTED_SIGNATURE_TYPE 154
+#define EVP_R_DECODE_ERROR 102
+#define EVP_R_DIFFERENT_KEY_TYPES 103
+#define EVP_R_DIFFERENT_PARAMETERS 104
+#define EVP_R_ENCODE_ERROR 105
+#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106
+#define EVP_R_EXPECTING_AN_RSA_KEY 107
+#define EVP_R_EXPECTING_A_DSA_KEY 108
+#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109
+#define EVP_R_INVALID_DIGEST_LENGTH 110
+#define EVP_R_INVALID_DIGEST_TYPE 111
+#define EVP_R_INVALID_KEYBITS 112
+#define EVP_R_INVALID_MGF1_MD 113
+#define EVP_R_INVALID_OPERATION 114
+#define EVP_R_INVALID_PADDING_MODE 115
+#define EVP_R_INVALID_PSS_SALTLEN 116
+#define EVP_R_KEYS_NOT_SET 117
+#define EVP_R_MISSING_PARAMETERS 118
+#define EVP_R_NO_DEFAULT_DIGEST 119
+#define EVP_R_NO_KEY_SET 120
+#define EVP_R_NO_MDC2_SUPPORT 121
+#define EVP_R_NO_NID_FOR_CURVE 122
+#define EVP_R_NO_OPERATION_SET 123
+#define EVP_R_NO_PARAMETERS_SET 124
+#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 125
+#define EVP_R_OPERATON_NOT_INITIALIZED 126
+#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127
+#define EVP_R_UNSUPPORTED_ALGORITHM 128
+#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129
 
 #endif  /* OPENSSL_HEADER_EVP_H */
diff --git a/src/include/openssl/hkdf.h b/src/include/openssl/hkdf.h
index b7a0dc2..8c96c4c 100644
--- a/src/include/openssl/hkdf.h
+++ b/src/include/openssl/hkdf.h
@@ -17,14 +17,17 @@
 
 #include <openssl/base.h>
 
-#ifdef  __cplusplus
+#if defined(__cplusplus)
 extern "C" {
 #endif
 
 
-/* Computes HKDF (as specified by RFC 5869) of initial keying material |secret|
- * with |salt| and |info| using |digest|, and outputs |out_len| bytes to
- * |out_key|. It returns one on success and zero on error.
+/* HKDF. */
+
+
+/* HKDF computes HKDF (as specified by RFC 5869) of initial keying material
+ * |secret| with |salt| and |info| using |digest|, and outputs |out_len| bytes
+ * to |out_key|. It returns one on success and zero on error.
  *
  * HKDF is an Extract-and-Expand algorithm. It does not do any key stretching,
  * and as such, is not suited to be used alone to generate a key from a
diff --git a/src/include/openssl/hmac.h b/src/include/openssl/hmac.h
index e521212..5a4e9c7 100644
--- a/src/include/openssl/hmac.h
+++ b/src/include/openssl/hmac.h
@@ -143,8 +143,6 @@
 
 /* Private functions */
 
-#define HMAC_MAX_MD_CBLOCK 128 /* largest known is SHA512 */
-
 struct hmac_ctx_st {
   const EVP_MD *md;
   EVP_MD_CTX md_ctx;
diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h
index 93c7af8..b66fcb0 100644
--- a/src/include/openssl/md4.h
+++ b/src/include/openssl/md4.h
@@ -83,6 +83,10 @@
  * returns one. */
 OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4);
 
+/* MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|.
+ * There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. */
+OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out);
+
 /* MD4_Transform is a low-level function that performs a single, MD4 block
  * transformation using the state from |md4| and 64 bytes from |block|. */
 OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block);
diff --git a/src/include/openssl/mem.h b/src/include/openssl/mem.h
index c8e2b3e..31756f0 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -114,23 +114,21 @@
  * representation of the given type. */
 #define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
 
-/* Printf functions.
- *
- * These functions are either OpenSSL wrappers for standard functions (i.e.
- * |BIO_snprintf| and |BIO_vsnprintf|) which don't exist in C89, or are
- * versions of printf functions that output to a BIO rather than a FILE. */
-#ifdef __GNUC__
-#define __bio_h__attr__ __attribute__
-#else
-#define __bio_h__attr__(x)
-#endif
+/* BIO_snprintf has the same behavior as snprintf(3). */
 OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...)
-    __bio_h__attr__((__format__(__printf__, 3, 4)));
+    OPENSSL_PRINTF_FORMAT_FUNC(3, 4);
 
+/* BIO_vsnprintf has the same behavior as vsnprintf(3). */
 OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format,
                                  va_list args)
-    __bio_h__attr__((__format__(__printf__, 3, 0)));
-#undef __bio_h__attr__
+    OPENSSL_PRINTF_FORMAT_FUNC(3, 0);
+
+
+/* Deprecated functions. */
+
+#define CRYPTO_malloc OPENSSL_malloc
+#define CRYPTO_realloc OPENSSL_realloc
+#define CRYPTO_free OPENSSL_free
 
 
 #if defined(__cplusplus)
diff --git a/src/include/openssl/newhope.h b/src/include/openssl/newhope.h
new file mode 100644
index 0000000..af573ba
--- /dev/null
+++ b/src/include/openssl/newhope.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_NEWHOPE_H
+#define OPENSSL_HEADER_NEWHOPE_H
+
+#include <openssl/base.h>
+#include <openssl/sha.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* Post-quantum key agreement, based upon the reference
+ * implementation. Note: this implementation does not interoperate
+ * with the reference implementation!
+ *
+ * Source: https://github.com/tpoeppelmann/newhope
+ *
+ * The authors' permission to use their code is gratefully acknowledged. */
+
+
+/* NEWHOPE_POLY_new returns a new |NEWHOPE_POLY| object, or NULL on error. */
+OPENSSL_EXPORT NEWHOPE_POLY *NEWHOPE_POLY_new(void);
+
+/* NEWHOPE_POLY_free frees |p|. */
+OPENSSL_EXPORT void NEWHOPE_POLY_free(NEWHOPE_POLY *p);
+
+/* NEWHOPE_SERVERMSG_LENGTH is the length of the server's message to the
+ * client. */
+#define NEWHOPE_SERVERMSG_LENGTH (((1024 * 14) / 8) + 32)
+
+/* NEWHOPE_CLIENTMSG_LENGTH is the length of the client's message to the
+ * server. */
+#define NEWHOPE_CLIENTMSG_LENGTH (((1024 * 14) / 8) + 1024 / 4)
+
+/* NEWHOPE_keygen initializes |out_msg| and |out_sk| for a new key
+ * exchange. |msg| must have room for |NEWHOPE_SERVERMSG_LENGTH| bytes. Neither
+ * output may be cached. */
+OPENSSL_EXPORT void NEWHOPE_keygen(uint8_t out_msg[NEWHOPE_SERVERMSG_LENGTH],
+                                   NEWHOPE_POLY *out_sk);
+
+/* NEWHOPE_server_compute_key completes a key exchange given a client message
+ * |msg| and the previously generated server secret |sk|. The result of the
+ * key exchange is written to |out_key|, which must have space for
+ * |SHA256_DIGEST_LENGTH| bytes. Returns 1 on success and 0 on error. */
+OPENSSL_EXPORT int NEWHOPE_server_compute_key(
+    uint8_t out_key[SHA256_DIGEST_LENGTH], const NEWHOPE_POLY *sk,
+    const uint8_t msg[NEWHOPE_CLIENTMSG_LENGTH], size_t msg_len);
+
+/* NEWHOPE_client_compute_key completes a key exchange given a server message
+ * |msg|. The result of the key exchange is written to |out_key|, which must
+ * have space for |SHA256_DIGEST_LENGTH| bytes. The message to be send to the
+ * client is written to |out_msg|, which must have room for
+ * |NEWHOPE_CLIENTMSG_LENGTH| bytes. Returns 1 on success and 0 on error. */
+OPENSSL_EXPORT int NEWHOPE_client_compute_key(
+    uint8_t out_key[SHA256_DIGEST_LENGTH],
+    uint8_t out_msg[NEWHOPE_CLIENTMSG_LENGTH],
+    const uint8_t msg[NEWHOPE_SERVERMSG_LENGTH], size_t msg_len);
+
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
+#endif /* OPENSSL_HEADER_NEWHOPE_H */
diff --git a/src/include/openssl/nid.h b/src/include/openssl/nid.h
new file mode 100644
index 0000000..d51a67c
--- /dev/null
+++ b/src/include/openssl/nid.h
@@ -0,0 +1,4163 @@
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef OPENSSL_HEADER_NID_H
+#define OPENSSL_HEADER_NID_H
+
+
+/* The nid library provides numbered values for ASN.1 object identifiers and
+ * other symbols. These values are used by other libraries to identify
+ * cryptographic primitives.
+ *
+ * A separate objects library, obj.h, provides functions for converting between
+ * nids and object identifiers. However it depends on large internal tables with
+ * the encodings of every nid defind. Consumers concerned with binary size
+ * should instead embed the encodings of the few consumed OIDs and compare
+ * against those.
+ *
+ * These values should not be used outside of a single process; they are not
+ * stable identifiers. */
+
+
+#define SN_undef "UNDEF"
+#define LN_undef "undefined"
+#define NID_undef 0
+#define OBJ_undef 0L
+
+#define SN_itu_t "ITU-T"
+#define LN_itu_t "itu-t"
+#define NID_itu_t 645
+#define OBJ_itu_t 0L
+
+#define NID_ccitt 404
+#define OBJ_ccitt OBJ_itu_t
+
+#define SN_iso "ISO"
+#define LN_iso "iso"
+#define NID_iso 181
+#define OBJ_iso 1L
+
+#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t "joint-iso-itu-t"
+#define NID_joint_iso_itu_t 646
+#define OBJ_joint_iso_itu_t 2L
+
+#define NID_joint_iso_ccitt 393
+#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t
+
+#define SN_member_body "member-body"
+#define LN_member_body "ISO Member Body"
+#define NID_member_body 182
+#define OBJ_member_body OBJ_iso,2L
+
+#define SN_identified_organization "identified-organization"
+#define NID_identified_organization 676
+#define OBJ_identified_organization OBJ_iso,3L
+
+#define SN_hmac_md5 "HMAC-MD5"
+#define LN_hmac_md5 "hmac-md5"
+#define NID_hmac_md5 780
+#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1 "HMAC-SHA1"
+#define LN_hmac_sha1 "hmac-sha1"
+#define NID_hmac_sha1 781
+#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc "certicom-arc"
+#define NID_certicom_arc 677
+#define OBJ_certicom_arc OBJ_identified_organization,132L
+
+#define SN_international_organizations "international-organizations"
+#define LN_international_organizations "International Organizations"
+#define NID_international_organizations 647
+#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L
+
+#define SN_wap "wap"
+#define NID_wap 678
+#define OBJ_wap OBJ_international_organizations,43L
+
+#define SN_wap_wsg "wap-wsg"
+#define NID_wap_wsg 679
+#define OBJ_wap_wsg OBJ_wap,1L
+
+#define SN_selected_attribute_types "selected-attribute-types"
+#define LN_selected_attribute_types "Selected Attribute Types"
+#define NID_selected_attribute_types 394
+#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance "clearance"
+#define NID_clearance 395
+#define OBJ_clearance OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US "ISO-US"
+#define LN_ISO_US "ISO US Member Body"
+#define NID_ISO_US 183
+#define OBJ_ISO_US OBJ_member_body,840L
+
+#define SN_X9_57 "X9-57"
+#define LN_X9_57 "X9.57"
+#define NID_X9_57 184
+#define OBJ_X9_57 OBJ_ISO_US,10040L
+
+#define SN_X9cm "X9cm"
+#define LN_X9cm "X9.57 CM ?"
+#define NID_X9cm 185
+#define OBJ_X9cm OBJ_X9_57,4L
+
+#define SN_dsa "DSA"
+#define LN_dsa "dsaEncryption"
+#define NID_dsa 116
+#define OBJ_dsa OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1 "DSA-SHA1"
+#define LN_dsaWithSHA1 "dsaWithSHA1"
+#define NID_dsaWithSHA1 113
+#define OBJ_dsaWithSHA1 OBJ_X9cm,3L
+
+#define SN_ansi_X9_62 "ansi-X9-62"
+#define LN_ansi_X9_62 "ANSI X9.62"
+#define NID_ansi_X9_62 405
+#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field "prime-field"
+#define NID_X9_62_prime_field 406
+#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field 407
+#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis 680
+#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis "onBasis"
+#define NID_X9_62_onBasis 681
+#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis "tpBasis"
+#define NID_X9_62_tpBasis 682
+#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis "ppBasis"
+#define NID_X9_62_ppBasis 683
+#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey 408
+#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1 "c2pnb163v1"
+#define NID_X9_62_c2pnb163v1 684
+#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2 "c2pnb163v2"
+#define NID_X9_62_c2pnb163v2 685
+#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3 "c2pnb163v3"
+#define NID_X9_62_c2pnb163v3 686
+#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1 "c2pnb176v1"
+#define NID_X9_62_c2pnb176v1 687
+#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1 "c2tnb191v1"
+#define NID_X9_62_c2tnb191v1 688
+#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2 "c2tnb191v2"
+#define NID_X9_62_c2tnb191v2 689
+#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3 "c2tnb191v3"
+#define NID_X9_62_c2tnb191v3 690
+#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4 "c2onb191v4"
+#define NID_X9_62_c2onb191v4 691
+#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5 "c2onb191v5"
+#define NID_X9_62_c2onb191v5 692
+#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1 "c2pnb208w1"
+#define NID_X9_62_c2pnb208w1 693
+#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1 "c2tnb239v1"
+#define NID_X9_62_c2tnb239v1 694
+#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2 "c2tnb239v2"
+#define NID_X9_62_c2tnb239v2 695
+#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3 "c2tnb239v3"
+#define NID_X9_62_c2tnb239v3 696
+#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4 "c2onb239v4"
+#define NID_X9_62_c2onb239v4 697
+#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5 "c2onb239v5"
+#define NID_X9_62_c2onb239v5 698
+#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1 "c2pnb272w1"
+#define NID_X9_62_c2pnb272w1 699
+#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1 "c2pnb304w1"
+#define NID_X9_62_c2pnb304w1 700
+#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1 "c2tnb359v1"
+#define NID_X9_62_c2tnb359v1 701
+#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1 "c2pnb368w1"
+#define NID_X9_62_c2pnb368w1 702
+#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1 "c2tnb431r1"
+#define NID_X9_62_c2tnb431r1 703
+#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1 "prime192v1"
+#define NID_X9_62_prime192v1 409
+#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2 "prime192v2"
+#define NID_X9_62_prime192v2 410
+#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3 "prime192v3"
+#define NID_X9_62_prime192v3 411
+#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1 "prime239v1"
+#define NID_X9_62_prime239v1 412
+#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2 "prime239v2"
+#define NID_X9_62_prime239v2 413
+#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3 "prime239v3"
+#define NID_X9_62_prime239v3 414
+#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1 "prime256v1"
+#define NID_X9_62_prime256v1 415
+#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1 416
+#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended 791
+#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified "ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified 792
+#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224 793
+#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256 794
+#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384 795
+#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512 796
+#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L
+
+#define SN_secp112r1 "secp112r1"
+#define NID_secp112r1 704
+#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2 "secp112r2"
+#define NID_secp112r2 705
+#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1 "secp128r1"
+#define NID_secp128r1 706
+#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2 "secp128r2"
+#define NID_secp128r2 707
+#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1 "secp160k1"
+#define NID_secp160k1 708
+#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1 "secp160r1"
+#define NID_secp160r1 709
+#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2 "secp160r2"
+#define NID_secp160r2 710
+#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1 "secp192k1"
+#define NID_secp192k1 711
+#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1 "secp224k1"
+#define NID_secp224k1 712
+#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1 "secp224r1"
+#define NID_secp224r1 713
+#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1 "secp256k1"
+#define NID_secp256k1 714
+#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1 "secp384r1"
+#define NID_secp384r1 715
+#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1 "secp521r1"
+#define NID_secp521r1 716
+#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1 "sect113r1"
+#define NID_sect113r1 717
+#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2 "sect113r2"
+#define NID_sect113r2 718
+#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1 "sect131r1"
+#define NID_sect131r1 719
+#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2 "sect131r2"
+#define NID_sect131r2 720
+#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1 "sect163k1"
+#define NID_sect163k1 721
+#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1 "sect163r1"
+#define NID_sect163r1 722
+#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2 "sect163r2"
+#define NID_sect163r2 723
+#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1 "sect193r1"
+#define NID_sect193r1 724
+#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2 "sect193r2"
+#define NID_sect193r2 725
+#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1 "sect233k1"
+#define NID_sect233k1 726
+#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1 "sect233r1"
+#define NID_sect233r1 727
+#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1 "sect239k1"
+#define NID_sect239k1 728
+#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1 "sect283k1"
+#define NID_sect283k1 729
+#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1 "sect283r1"
+#define NID_sect283r1 730
+#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1 "sect409k1"
+#define NID_sect409k1 731
+#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1 "sect409r1"
+#define NID_sect409r1 732
+#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1 "sect571k1"
+#define NID_sect571k1 733
+#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1 "sect571r1"
+#define NID_sect571r1 734
+#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1 735
+#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3 736
+#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4 737
+#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5 738
+#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6 739
+#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7 740
+#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8 741
+#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9 742
+#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10 743
+#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11 744
+#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12 745
+#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc "CAST5-CBC"
+#define LN_cast5_cbc "cast5-cbc"
+#define NID_cast5_cbc 108
+#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb "CAST5-ECB"
+#define LN_cast5_ecb "cast5-ecb"
+#define NID_cast5_ecb 109
+
+#define SN_cast5_cfb64 "CAST5-CFB"
+#define LN_cast5_cfb64 "cast5-cfb"
+#define NID_cast5_cfb64 110
+
+#define SN_cast5_ofb64 "CAST5-OFB"
+#define LN_cast5_ofb64 "cast5-ofb"
+#define NID_cast5_ofb64 111
+
+#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC 112
+#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC "password based MAC"
+#define NID_id_PasswordBasedMAC 782
+#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac "id-DHBasedMac"
+#define LN_id_DHBasedMac "Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac 783
+#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi "rsadsi"
+#define LN_rsadsi "RSA Data Security, Inc."
+#define NID_rsadsi 1
+#define OBJ_rsadsi OBJ_ISO_US,113549L
+
+#define SN_pkcs "pkcs"
+#define LN_pkcs "RSA Data Security, Inc. PKCS"
+#define NID_pkcs 2
+#define OBJ_pkcs OBJ_rsadsi,1L
+
+#define SN_pkcs1 "pkcs1"
+#define NID_pkcs1 186
+#define OBJ_pkcs1 OBJ_pkcs,1L
+
+#define LN_rsaEncryption "rsaEncryption"
+#define NID_rsaEncryption 6
+#define OBJ_rsaEncryption OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption "RSA-MD2"
+#define LN_md2WithRSAEncryption "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption 7
+#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption "RSA-MD4"
+#define LN_md4WithRSAEncryption "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption 396
+#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption "RSA-MD5"
+#define LN_md5WithRSAEncryption "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption 8
+#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption "RSA-SHA1"
+#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption 65
+#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L
+
+#define SN_rsaesOaep "RSAES-OAEP"
+#define LN_rsaesOaep "rsaesOaep"
+#define NID_rsaesOaep 919
+#define OBJ_rsaesOaep OBJ_pkcs1,7L
+
+#define SN_mgf1 "MGF1"
+#define LN_mgf1 "mgf1"
+#define NID_mgf1 911
+#define OBJ_mgf1 OBJ_pkcs1,8L
+
+#define SN_pSpecified "PSPECIFIED"
+#define LN_pSpecified "pSpecified"
+#define NID_pSpecified 935
+#define OBJ_pSpecified OBJ_pkcs1,9L
+
+#define SN_rsassaPss "RSASSA-PSS"
+#define LN_rsassaPss "rsassaPss"
+#define NID_rsassaPss 912
+#define OBJ_rsassaPss OBJ_pkcs1,10L
+
+#define SN_sha256WithRSAEncryption "RSA-SHA256"
+#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption 668
+#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption "RSA-SHA384"
+#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption 669
+#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption "RSA-SHA512"
+#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption 670
+#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption "RSA-SHA224"
+#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption 671
+#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L
+
+#define SN_pkcs3 "pkcs3"
+#define NID_pkcs3 27
+#define OBJ_pkcs3 OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement "dhKeyAgreement"
+#define NID_dhKeyAgreement 28
+#define OBJ_dhKeyAgreement OBJ_pkcs3,1L
+
+#define SN_pkcs5 "pkcs5"
+#define NID_pkcs5 187
+#define OBJ_pkcs5 OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC 9
+#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC 10
+#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC 168
+#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC 169
+#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC 170
+#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC 68
+#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2 "PBKDF2"
+#define NID_id_pbkdf2 69
+#define OBJ_id_pbkdf2 OBJ_pkcs5,12L
+
+#define LN_pbes2 "PBES2"
+#define NID_pbes2 161
+#define OBJ_pbes2 OBJ_pkcs5,13L
+
+#define LN_pbmac1 "PBMAC1"
+#define NID_pbmac1 162
+#define OBJ_pbmac1 OBJ_pkcs5,14L
+
+#define SN_pkcs7 "pkcs7"
+#define NID_pkcs7 20
+#define OBJ_pkcs7 OBJ_pkcs,7L
+
+#define LN_pkcs7_data "pkcs7-data"
+#define NID_pkcs7_data 21
+#define OBJ_pkcs7_data OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed "pkcs7-signedData"
+#define NID_pkcs7_signed 22
+#define OBJ_pkcs7_signed OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped 23
+#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped 24
+#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest "pkcs7-digestData"
+#define NID_pkcs7_digest 25
+#define OBJ_pkcs7_digest OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted 26
+#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L
+
+#define SN_pkcs9 "pkcs9"
+#define NID_pkcs9 47
+#define OBJ_pkcs9 OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress "emailAddress"
+#define NID_pkcs9_emailAddress 48
+#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName "unstructuredName"
+#define NID_pkcs9_unstructuredName 49
+#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType "contentType"
+#define NID_pkcs9_contentType 50
+#define OBJ_pkcs9_contentType OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest "messageDigest"
+#define NID_pkcs9_messageDigest 51
+#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime "signingTime"
+#define NID_pkcs9_signingTime 52
+#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature "countersignature"
+#define NID_pkcs9_countersignature 53
+#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword "challengePassword"
+#define NID_pkcs9_challengePassword 54
+#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress 55
+#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes 56
+#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L
+
+#define SN_ext_req "extReq"
+#define LN_ext_req "Extension Request"
+#define NID_ext_req 172
+#define OBJ_ext_req OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities "SMIME-CAPS"
+#define LN_SMIMECapabilities "S/MIME Capabilities"
+#define NID_SMIMECapabilities 167
+#define OBJ_SMIMECapabilities OBJ_pkcs9,15L
+
+#define SN_SMIME "SMIME"
+#define LN_SMIME "S/MIME"
+#define NID_SMIME 188
+#define OBJ_SMIME OBJ_pkcs9,16L
+
+#define SN_id_smime_mod "id-smime-mod"
+#define NID_id_smime_mod 189
+#define OBJ_id_smime_mod OBJ_SMIME,0L
+
+#define SN_id_smime_ct "id-smime-ct"
+#define NID_id_smime_ct 190
+#define OBJ_id_smime_ct OBJ_SMIME,1L
+
+#define SN_id_smime_aa "id-smime-aa"
+#define NID_id_smime_aa 191
+#define OBJ_id_smime_aa OBJ_SMIME,2L
+
+#define SN_id_smime_alg "id-smime-alg"
+#define NID_id_smime_alg 192
+#define OBJ_id_smime_alg OBJ_SMIME,3L
+
+#define SN_id_smime_cd "id-smime-cd"
+#define NID_id_smime_cd 193
+#define OBJ_id_smime_cd OBJ_SMIME,4L
+
+#define SN_id_smime_spq "id-smime-spq"
+#define NID_id_smime_spq 194
+#define OBJ_id_smime_spq OBJ_SMIME,5L
+
+#define SN_id_smime_cti "id-smime-cti"
+#define NID_id_smime_cti 195
+#define OBJ_id_smime_cti OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms "id-smime-mod-cms"
+#define NID_id_smime_mod_cms 196
+#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess "id-smime-mod-ess"
+#define NID_id_smime_mod_ess 197
+#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid "id-smime-mod-oid"
+#define NID_id_smime_mod_oid 198
+#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3 199
+#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88 200
+#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97 201
+#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88 202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97 203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt 204
+#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData "id-smime-ct-authData"
+#define NID_id_smime_ct_authData 205
+#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert 206
+#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo 207
+#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo 208
+#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo 209
+#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData 210
+#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData 211
+#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData 786
+#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L
+
+#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF 787
+#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L
+
+#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest 212
+#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel 213
+#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory 214
+#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint 215
+#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest 216
+#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType 217
+#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier 218
+#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue 219
+#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels 220
+#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference 221
+#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref 222
+#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate 223
+#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts 224
+#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken 225
+#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId 226
+#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType 227
+#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation 228
+#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr 229
+#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert 230
+#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp 231
+#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs 232
+#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs 233
+#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues 234
+#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues 235
+#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp 236
+#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp 237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp 238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType 239
+#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc 240
+#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES 241
+#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2 242
+#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap 243
+#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap 244
+#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH 245
+#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap 246
+#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap 247
+#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L
+
+#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK 893
+#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L
+
+#define SN_id_smime_cd_ldap "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap 248
+#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri 249
+#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice 250
+#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin 251
+#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt 252
+#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery 253
+#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender 254
+#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval 255
+#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation 256
+#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L
+
+#define LN_friendlyName "friendlyName"
+#define NID_friendlyName 156
+#define OBJ_friendlyName OBJ_pkcs9,20L
+
+#define LN_localKeyID "localKeyID"
+#define NID_localKeyID 157
+#define OBJ_localKeyID OBJ_pkcs9,21L
+
+#define SN_ms_csp_name "CSPName"
+#define LN_ms_csp_name "Microsoft CSP Name"
+#define NID_ms_csp_name 417
+#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet "LocalKeySet"
+#define LN_LocalKeySet "Microsoft Local Key set"
+#define NID_LocalKeySet 856
+#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes OBJ_pkcs9,22L
+
+#define LN_x509Certificate "x509Certificate"
+#define NID_x509Certificate 158
+#define OBJ_x509Certificate OBJ_certTypes,1L
+
+#define LN_sdsiCertificate "sdsiCertificate"
+#define NID_sdsiCertificate 159
+#define OBJ_sdsiCertificate OBJ_certTypes,2L
+
+#define OBJ_crlTypes OBJ_pkcs9,23L
+
+#define LN_x509Crl "x509Crl"
+#define NID_x509Crl 160
+#define OBJ_x509Crl OBJ_crlTypes,1L
+
+#define OBJ_pkcs12 OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4 144
+#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4 145
+#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC 148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC 149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag "keyBag"
+#define NID_keyBag 150
+#define OBJ_keyBag OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag 151
+#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag "certBag"
+#define NID_certBag 152
+#define OBJ_certBag OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag "crlBag"
+#define NID_crlBag 153
+#define OBJ_crlBag OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag "secretBag"
+#define NID_secretBag 154
+#define OBJ_secretBag OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag "safeContentsBag"
+#define NID_safeContentsBag 155
+#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L
+
+#define SN_md2 "MD2"
+#define LN_md2 "md2"
+#define NID_md2 3
+#define OBJ_md2 OBJ_rsadsi,2L,2L
+
+#define SN_md4 "MD4"
+#define LN_md4 "md4"
+#define NID_md4 257
+#define OBJ_md4 OBJ_rsadsi,2L,4L
+
+#define SN_md5 "MD5"
+#define LN_md5 "md5"
+#define NID_md5 4
+#define OBJ_md5 OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1 "MD5-SHA1"
+#define LN_md5_sha1 "md5-sha1"
+#define NID_md5_sha1 114
+
+#define LN_hmacWithMD5 "hmacWithMD5"
+#define NID_hmacWithMD5 797
+#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1 "hmacWithSHA1"
+#define NID_hmacWithSHA1 163
+#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224 "hmacWithSHA224"
+#define NID_hmacWithSHA224 798
+#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256 "hmacWithSHA256"
+#define NID_hmacWithSHA256 799
+#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384 "hmacWithSHA384"
+#define NID_hmacWithSHA384 800
+#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512 "hmacWithSHA512"
+#define NID_hmacWithSHA512 801
+#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc "RC2-CBC"
+#define LN_rc2_cbc "rc2-cbc"
+#define NID_rc2_cbc 37
+#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb "RC2-ECB"
+#define LN_rc2_ecb "rc2-ecb"
+#define NID_rc2_ecb 38
+
+#define SN_rc2_cfb64 "RC2-CFB"
+#define LN_rc2_cfb64 "rc2-cfb"
+#define NID_rc2_cfb64 39
+
+#define SN_rc2_ofb64 "RC2-OFB"
+#define LN_rc2_ofb64 "rc2-ofb"
+#define NID_rc2_ofb64 40
+
+#define SN_rc2_40_cbc "RC2-40-CBC"
+#define LN_rc2_40_cbc "rc2-40-cbc"
+#define NID_rc2_40_cbc 98
+
+#define SN_rc2_64_cbc "RC2-64-CBC"
+#define LN_rc2_64_cbc "rc2-64-cbc"
+#define NID_rc2_64_cbc 166
+
+#define SN_rc4 "RC4"
+#define LN_rc4 "rc4"
+#define NID_rc4 5
+#define OBJ_rc4 OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40 "RC4-40"
+#define LN_rc4_40 "rc4-40"
+#define NID_rc4_40 97
+
+#define SN_des_ede3_cbc "DES-EDE3-CBC"
+#define LN_des_ede3_cbc "des-ede3-cbc"
+#define NID_des_ede3_cbc 44
+#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc "RC5-CBC"
+#define LN_rc5_cbc "rc5-cbc"
+#define NID_rc5_cbc 120
+#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb "RC5-ECB"
+#define LN_rc5_ecb "rc5-ecb"
+#define NID_rc5_ecb 121
+
+#define SN_rc5_cfb64 "RC5-CFB"
+#define LN_rc5_cfb64 "rc5-cfb"
+#define NID_rc5_cfb64 122
+
+#define SN_rc5_ofb64 "RC5-OFB"
+#define LN_rc5_ofb64 "rc5-ofb"
+#define NID_rc5_ofb64 123
+
+#define SN_ms_ext_req "msExtReq"
+#define LN_ms_ext_req "Microsoft Extension Request"
+#define NID_ms_ext_req 171
+#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind "msCodeInd"
+#define LN_ms_code_ind "Microsoft Individual Code Signing"
+#define NID_ms_code_ind 134
+#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com "msCodeCom"
+#define LN_ms_code_com "Microsoft Commercial Code Signing"
+#define NID_ms_code_com 135
+#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign "msCTLSign"
+#define LN_ms_ctl_sign "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign 136
+#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc "msSGC"
+#define LN_ms_sgc "Microsoft Server Gated Crypto"
+#define NID_ms_sgc 137
+#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs "msEFS"
+#define LN_ms_efs "Microsoft Encrypted File System"
+#define NID_ms_efs 138
+#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login "msSmartcardLogin"
+#define LN_ms_smartcard_login "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login 648
+#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn "msUPN"
+#define LN_ms_upn "Microsoft Universal Principal Name"
+#define NID_ms_upn 649
+#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc "IDEA-CBC"
+#define LN_idea_cbc "idea-cbc"
+#define NID_idea_cbc 34
+#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb "IDEA-ECB"
+#define LN_idea_ecb "idea-ecb"
+#define NID_idea_ecb 36
+
+#define SN_idea_cfb64 "IDEA-CFB"
+#define LN_idea_cfb64 "idea-cfb"
+#define NID_idea_cfb64 35
+
+#define SN_idea_ofb64 "IDEA-OFB"
+#define LN_idea_ofb64 "idea-ofb"
+#define NID_idea_ofb64 46
+
+#define SN_bf_cbc "BF-CBC"
+#define LN_bf_cbc "bf-cbc"
+#define NID_bf_cbc 91
+#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb "BF-ECB"
+#define LN_bf_ecb "bf-ecb"
+#define NID_bf_ecb 92
+
+#define SN_bf_cfb64 "BF-CFB"
+#define LN_bf_cfb64 "bf-cfb"
+#define NID_bf_cfb64 93
+
+#define SN_bf_ofb64 "BF-OFB"
+#define LN_bf_ofb64 "bf-ofb"
+#define NID_bf_ofb64 94
+
+#define SN_id_pkix "PKIX"
+#define NID_id_pkix 127
+#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod "id-pkix-mod"
+#define NID_id_pkix_mod 258
+#define OBJ_id_pkix_mod OBJ_id_pkix,0L
+
+#define SN_id_pe "id-pe"
+#define NID_id_pe 175
+#define OBJ_id_pe OBJ_id_pkix,1L
+
+#define SN_id_qt "id-qt"
+#define NID_id_qt 259
+#define OBJ_id_qt OBJ_id_pkix,2L
+
+#define SN_id_kp "id-kp"
+#define NID_id_kp 128
+#define OBJ_id_kp OBJ_id_pkix,3L
+
+#define SN_id_it "id-it"
+#define NID_id_it 260
+#define OBJ_id_it OBJ_id_pkix,4L
+
+#define SN_id_pkip "id-pkip"
+#define NID_id_pkip 261
+#define OBJ_id_pkip OBJ_id_pkix,5L
+
+#define SN_id_alg "id-alg"
+#define NID_id_alg 262
+#define OBJ_id_alg OBJ_id_pkix,6L
+
+#define SN_id_cmc "id-cmc"
+#define NID_id_cmc 263
+#define OBJ_id_cmc OBJ_id_pkix,7L
+
+#define SN_id_on "id-on"
+#define NID_id_on 264
+#define OBJ_id_on OBJ_id_pkix,8L
+
+#define SN_id_pda "id-pda"
+#define NID_id_pda 265
+#define OBJ_id_pda OBJ_id_pkix,9L
+
+#define SN_id_aca "id-aca"
+#define NID_id_aca 266
+#define OBJ_id_aca OBJ_id_pkix,10L
+
+#define SN_id_qcs "id-qcs"
+#define NID_id_qcs 267
+#define OBJ_id_qcs OBJ_id_pkix,11L
+
+#define SN_id_cct "id-cct"
+#define NID_id_cct 268
+#define OBJ_id_cct OBJ_id_pkix,12L
+
+#define SN_id_ppl "id-ppl"
+#define NID_id_ppl 662
+#define OBJ_id_ppl OBJ_id_pkix,21L
+
+#define SN_id_ad "id-ad"
+#define NID_id_ad 176
+#define OBJ_id_ad OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88 269
+#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88 270
+#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93 271
+#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93 272
+#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf "id-mod-crmf"
+#define NID_id_mod_crmf 273
+#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc "id-mod-cmc"
+#define NID_id_mod_cmc 274
+#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88 275
+#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93 276
+#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp "id-mod-cmp"
+#define NID_id_mod_cmp 277
+#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88 278
+#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93 279
+#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert 280
+#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol 281
+#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp "id-mod-ocsp"
+#define NID_id_mod_ocsp 282
+#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs "id-mod-dvcs"
+#define NID_id_mod_dvcs 283
+#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000 "id-mod-cmp2000"
+#define NID_id_mod_cmp2000 284
+#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L
+
+#define SN_info_access "authorityInfoAccess"
+#define LN_info_access "Authority Information Access"
+#define NID_info_access 177
+#define OBJ_info_access OBJ_id_pe,1L
+
+#define SN_biometricInfo "biometricInfo"
+#define LN_biometricInfo "Biometric Info"
+#define NID_biometricInfo 285
+#define OBJ_biometricInfo OBJ_id_pe,2L
+
+#define SN_qcStatements "qcStatements"
+#define NID_qcStatements 286
+#define OBJ_qcStatements OBJ_id_pe,3L
+
+#define SN_ac_auditEntity "ac-auditEntity"
+#define NID_ac_auditEntity 287
+#define OBJ_ac_auditEntity OBJ_id_pe,4L
+
+#define SN_ac_targeting "ac-targeting"
+#define NID_ac_targeting 288
+#define OBJ_ac_targeting OBJ_id_pe,5L
+
+#define SN_aaControls "aaControls"
+#define NID_aaControls 289
+#define OBJ_aaControls OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock 290
+#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum 291
+#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier 292
+#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L
+
+#define SN_ac_proxying "ac-proxying"
+#define NID_ac_proxying 397
+#define OBJ_ac_proxying OBJ_id_pe,10L
+
+#define SN_sinfo_access "subjectInfoAccess"
+#define LN_sinfo_access "Subject Information Access"
+#define NID_sinfo_access 398
+#define OBJ_sinfo_access OBJ_id_pe,11L
+
+#define SN_proxyCertInfo "proxyCertInfo"
+#define LN_proxyCertInfo "Proxy Certificate Information"
+#define NID_proxyCertInfo 663
+#define OBJ_proxyCertInfo OBJ_id_pe,14L
+
+#define SN_id_qt_cps "id-qt-cps"
+#define LN_id_qt_cps "Policy Qualifier CPS"
+#define NID_id_qt_cps 164
+#define OBJ_id_qt_cps OBJ_id_qt,1L
+
+#define SN_id_qt_unotice "id-qt-unotice"
+#define LN_id_qt_unotice "Policy Qualifier User Notice"
+#define NID_id_qt_unotice 165
+#define OBJ_id_qt_unotice OBJ_id_qt,2L
+
+#define SN_textNotice "textNotice"
+#define NID_textNotice 293
+#define OBJ_textNotice OBJ_id_qt,3L
+
+#define SN_server_auth "serverAuth"
+#define LN_server_auth "TLS Web Server Authentication"
+#define NID_server_auth 129
+#define OBJ_server_auth OBJ_id_kp,1L
+
+#define SN_client_auth "clientAuth"
+#define LN_client_auth "TLS Web Client Authentication"
+#define NID_client_auth 130
+#define OBJ_client_auth OBJ_id_kp,2L
+
+#define SN_code_sign "codeSigning"
+#define LN_code_sign "Code Signing"
+#define NID_code_sign 131
+#define OBJ_code_sign OBJ_id_kp,3L
+
+#define SN_email_protect "emailProtection"
+#define LN_email_protect "E-mail Protection"
+#define NID_email_protect 132
+#define OBJ_email_protect OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem "ipsecEndSystem"
+#define LN_ipsecEndSystem "IPSec End System"
+#define NID_ipsecEndSystem 294
+#define OBJ_ipsecEndSystem OBJ_id_kp,5L
+
+#define SN_ipsecTunnel "ipsecTunnel"
+#define LN_ipsecTunnel "IPSec Tunnel"
+#define NID_ipsecTunnel 295
+#define OBJ_ipsecTunnel OBJ_id_kp,6L
+
+#define SN_ipsecUser "ipsecUser"
+#define LN_ipsecUser "IPSec User"
+#define NID_ipsecUser 296
+#define OBJ_ipsecUser OBJ_id_kp,7L
+
+#define SN_time_stamp "timeStamping"
+#define LN_time_stamp "Time Stamping"
+#define NID_time_stamp 133
+#define OBJ_time_stamp OBJ_id_kp,8L
+
+#define SN_OCSP_sign "OCSPSigning"
+#define LN_OCSP_sign "OCSP Signing"
+#define NID_OCSP_sign 180
+#define OBJ_OCSP_sign OBJ_id_kp,9L
+
+#define SN_dvcs "DVCS"
+#define LN_dvcs "dvcs"
+#define NID_dvcs 297
+#define OBJ_dvcs OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert 298
+#define OBJ_id_it_caProtEncCert OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes 299
+#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes 300
+#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg 301
+#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo 302
+#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L
+
+#define SN_id_it_currentCRL "id-it-currentCRL"
+#define NID_id_it_currentCRL 303
+#define OBJ_id_it_currentCRL OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs 304
+#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest 305
+#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse 306
+#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq 307
+#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep 308
+#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase "id-it-revPassphrase"
+#define NID_id_it_revPassphrase 309
+#define OBJ_id_it_revPassphrase OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm 310
+#define OBJ_id_it_implicitConfirm OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime 311
+#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage 312
+#define OBJ_id_it_origPKIMessage OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags "id-it-suppLangTags"
+#define NID_id_it_suppLangTags 784
+#define OBJ_id_it_suppLangTags OBJ_id_it,16L
+
+#define SN_id_regCtrl "id-regCtrl"
+#define NID_id_regCtrl 313
+#define OBJ_id_regCtrl OBJ_id_pkip,1L
+
+#define SN_id_regInfo "id-regInfo"
+#define NID_id_regInfo 314
+#define OBJ_id_regInfo OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken 315
+#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator 316
+#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo 317
+#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions 318
+#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID 319
+#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey 320
+#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs 321
+#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq "id-regInfo-certReq"
+#define NID_id_regInfo_certReq 322
+#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40 "id-alg-des40"
+#define NID_id_alg_des40 323
+#define OBJ_id_alg_des40 OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature "id-alg-noSignature"
+#define NID_id_alg_noSignature 324
+#define OBJ_id_alg_noSignature OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1 325
+#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop "id-alg-dh-pop"
+#define NID_id_alg_dh_pop 326
+#define OBJ_id_alg_dh_pop OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo 327
+#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification "id-cmc-identification"
+#define NID_id_cmc_identification 328
+#define OBJ_id_cmc_identification OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof "id-cmc-identityProof"
+#define NID_id_cmc_identityProof 329
+#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn 330
+#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId "id-cmc-transactionId"
+#define NID_id_cmc_transactionId 331
+#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce 332
+#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce 333
+#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions 334
+#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP 335
+#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP 336
+#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness 337
+#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert "id-cmc-getCert"
+#define NID_id_cmc_getCert 338
+#define OBJ_id_cmc_getCert OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL "id-cmc-getCRL"
+#define NID_id_cmc_getCRL 339
+#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest 340
+#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo "id-cmc-regInfo"
+#define NID_id_cmc_regInfo 341
+#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo 342
+#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending "id-cmc-queryPending"
+#define NID_id_cmc_queryPending 343
+#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom 344
+#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness 345
+#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance 346
+#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L
+
+#define SN_id_on_personalData "id-on-personalData"
+#define NID_id_on_personalData 347
+#define OBJ_id_on_personalData OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier "Permanent Identifier"
+#define NID_id_on_permanentIdentifier 858
+#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth 348
+#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth 349
+#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L
+
+#define SN_id_pda_gender "id-pda-gender"
+#define NID_id_pda_gender 351
+#define OBJ_id_pda_gender OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship 352
+#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence 353
+#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo 354
+#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity 355
+#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity 356
+#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L
+
+#define SN_id_aca_group "id-aca-group"
+#define NID_id_aca_group 357
+#define OBJ_id_aca_group OBJ_id_aca,4L
+
+#define SN_id_aca_role "id-aca-role"
+#define NID_id_aca_role 358
+#define OBJ_id_aca_role OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs "id-aca-encAttrs"
+#define NID_id_aca_encAttrs 399
+#define OBJ_id_aca_encAttrs OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1 359
+#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L
+
+#define SN_id_cct_crs "id-cct-crs"
+#define NID_id_cct_crs 360
+#define OBJ_id_cct_crs OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData "id-cct-PKIData"
+#define NID_id_cct_PKIData 361
+#define OBJ_id_cct_PKIData OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse 362
+#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage "Any language"
+#define NID_id_ppl_anyLanguage 664
+#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll "Inherit all"
+#define NID_id_ppl_inheritAll 665
+#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L
+
+#define SN_Independent "id-ppl-independent"
+#define LN_Independent "Independent"
+#define NID_Independent 667
+#define OBJ_Independent OBJ_id_ppl,2L
+
+#define SN_ad_OCSP "OCSP"
+#define LN_ad_OCSP "OCSP"
+#define NID_ad_OCSP 178
+#define OBJ_ad_OCSP OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers "caIssuers"
+#define LN_ad_ca_issuers "CA Issuers"
+#define NID_ad_ca_issuers 179
+#define OBJ_ad_ca_issuers OBJ_id_ad,2L
+
+#define SN_ad_timeStamping "ad_timestamping"
+#define LN_ad_timeStamping "AD Time Stamping"
+#define NID_ad_timeStamping 363
+#define OBJ_ad_timeStamping OBJ_id_ad,3L
+
+#define SN_ad_dvcs "AD_DVCS"
+#define LN_ad_dvcs "ad dvcs"
+#define NID_ad_dvcs 364
+#define OBJ_ad_dvcs OBJ_id_ad,4L
+
+#define SN_caRepository "caRepository"
+#define LN_caRepository "CA Repository"
+#define NID_caRepository 785
+#define OBJ_caRepository OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic 365
+#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce "Nonce"
+#define LN_id_pkix_OCSP_Nonce "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce 366
+#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID "CrlID"
+#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID 367
+#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses 368
+#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck "noCheck"
+#define LN_id_pkix_OCSP_noCheck "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck 369
+#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff 370
+#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator 371
+#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus 372
+#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid "valid"
+#define NID_id_pkix_OCSP_valid 373
+#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path "path"
+#define NID_id_pkix_OCSP_path 374
+#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot 375
+#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm "algorithm"
+#define LN_algorithm "algorithm"
+#define NID_algorithm 376
+#define OBJ_algorithm 1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA "RSA-NP-MD5"
+#define LN_md5WithRSA "md5WithRSA"
+#define NID_md5WithRSA 104
+#define OBJ_md5WithRSA OBJ_algorithm,3L
+
+#define SN_des_ecb "DES-ECB"
+#define LN_des_ecb "des-ecb"
+#define NID_des_ecb 29
+#define OBJ_des_ecb OBJ_algorithm,6L
+
+#define SN_des_cbc "DES-CBC"
+#define LN_des_cbc "des-cbc"
+#define NID_des_cbc 31
+#define OBJ_des_cbc OBJ_algorithm,7L
+
+#define SN_des_ofb64 "DES-OFB"
+#define LN_des_ofb64 "des-ofb"
+#define NID_des_ofb64 45
+#define OBJ_des_ofb64 OBJ_algorithm,8L
+
+#define SN_des_cfb64 "DES-CFB"
+#define LN_des_cfb64 "des-cfb"
+#define NID_des_cfb64 30
+#define OBJ_des_cfb64 OBJ_algorithm,9L
+
+#define SN_rsaSignature "rsaSignature"
+#define NID_rsaSignature 377
+#define OBJ_rsaSignature OBJ_algorithm,11L
+
+#define SN_dsa_2 "DSA-old"
+#define LN_dsa_2 "dsaEncryption-old"
+#define NID_dsa_2 67
+#define OBJ_dsa_2 OBJ_algorithm,12L
+
+#define SN_dsaWithSHA "DSA-SHA"
+#define LN_dsaWithSHA "dsaWithSHA"
+#define NID_dsaWithSHA 66
+#define OBJ_dsaWithSHA OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption "RSA-SHA"
+#define LN_shaWithRSAEncryption "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption 42
+#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L
+
+#define SN_des_ede_ecb "DES-EDE"
+#define LN_des_ede_ecb "des-ede"
+#define NID_des_ede_ecb 32
+#define OBJ_des_ede_ecb OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb "DES-EDE3"
+#define LN_des_ede3_ecb "des-ede3"
+#define NID_des_ede3_ecb 33
+
+#define SN_des_ede_cbc "DES-EDE-CBC"
+#define LN_des_ede_cbc "des-ede-cbc"
+#define NID_des_ede_cbc 43
+
+#define SN_des_ede_cfb64 "DES-EDE-CFB"
+#define LN_des_ede_cfb64 "des-ede-cfb"
+#define NID_des_ede_cfb64 60
+
+#define SN_des_ede3_cfb64 "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64 "des-ede3-cfb"
+#define NID_des_ede3_cfb64 61
+
+#define SN_des_ede_ofb64 "DES-EDE-OFB"
+#define LN_des_ede_ofb64 "des-ede-ofb"
+#define NID_des_ede_ofb64 62
+
+#define SN_des_ede3_ofb64 "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64 "des-ede3-ofb"
+#define NID_des_ede3_ofb64 63
+
+#define SN_desx_cbc "DESX-CBC"
+#define LN_desx_cbc "desx-cbc"
+#define NID_desx_cbc 80
+
+#define SN_sha "SHA"
+#define LN_sha "sha"
+#define NID_sha 41
+#define OBJ_sha OBJ_algorithm,18L
+
+#define SN_sha1 "SHA1"
+#define LN_sha1 "sha1"
+#define NID_sha1 64
+#define OBJ_sha1 OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2 "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2 "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2 70
+#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L
+
+#define SN_sha1WithRSA "RSA-SHA1-2"
+#define LN_sha1WithRSA "sha1WithRSA"
+#define NID_sha1WithRSA 115
+#define OBJ_sha1WithRSA OBJ_algorithm,29L
+
+#define SN_ripemd160 "RIPEMD160"
+#define LN_ripemd160 "ripemd160"
+#define NID_ripemd160 117
+#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA "ripemd160WithRSA"
+#define NID_ripemd160WithRSA 119
+#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet "SXNetID"
+#define LN_sxnet "Strong Extranet ID"
+#define NID_sxnet 143
+#define OBJ_sxnet 1L,3L,101L,1L,4L,1L
+
+#define SN_X500 "X500"
+#define LN_X500 "directory services (X.500)"
+#define NID_X500 11
+#define OBJ_X500 2L,5L
+
+#define SN_X509 "X509"
+#define NID_X509 12
+#define OBJ_X509 OBJ_X500,4L
+
+#define SN_commonName "CN"
+#define LN_commonName "commonName"
+#define NID_commonName 13
+#define OBJ_commonName OBJ_X509,3L
+
+#define SN_surname "SN"
+#define LN_surname "surname"
+#define NID_surname 100
+#define OBJ_surname OBJ_X509,4L
+
+#define LN_serialNumber "serialNumber"
+#define NID_serialNumber 105
+#define OBJ_serialNumber OBJ_X509,5L
+
+#define SN_countryName "C"
+#define LN_countryName "countryName"
+#define NID_countryName 14
+#define OBJ_countryName OBJ_X509,6L
+
+#define SN_localityName "L"
+#define LN_localityName "localityName"
+#define NID_localityName 15
+#define OBJ_localityName OBJ_X509,7L
+
+#define SN_stateOrProvinceName "ST"
+#define LN_stateOrProvinceName "stateOrProvinceName"
+#define NID_stateOrProvinceName 16
+#define OBJ_stateOrProvinceName OBJ_X509,8L
+
+#define SN_streetAddress "street"
+#define LN_streetAddress "streetAddress"
+#define NID_streetAddress 660
+#define OBJ_streetAddress OBJ_X509,9L
+
+#define SN_organizationName "O"
+#define LN_organizationName "organizationName"
+#define NID_organizationName 17
+#define OBJ_organizationName OBJ_X509,10L
+
+#define SN_organizationalUnitName "OU"
+#define LN_organizationalUnitName "organizationalUnitName"
+#define NID_organizationalUnitName 18
+#define OBJ_organizationalUnitName OBJ_X509,11L
+
+#define SN_title "title"
+#define LN_title "title"
+#define NID_title 106
+#define OBJ_title OBJ_X509,12L
+
+#define LN_description "description"
+#define NID_description 107
+#define OBJ_description OBJ_X509,13L
+
+#define LN_searchGuide "searchGuide"
+#define NID_searchGuide 859
+#define OBJ_searchGuide OBJ_X509,14L
+
+#define LN_businessCategory "businessCategory"
+#define NID_businessCategory 860
+#define OBJ_businessCategory OBJ_X509,15L
+
+#define LN_postalAddress "postalAddress"
+#define NID_postalAddress 861
+#define OBJ_postalAddress OBJ_X509,16L
+
+#define LN_postalCode "postalCode"
+#define NID_postalCode 661
+#define OBJ_postalCode OBJ_X509,17L
+
+#define LN_postOfficeBox "postOfficeBox"
+#define NID_postOfficeBox 862
+#define OBJ_postOfficeBox OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName 863
+#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L
+
+#define LN_telephoneNumber "telephoneNumber"
+#define NID_telephoneNumber 864
+#define OBJ_telephoneNumber OBJ_X509,20L
+
+#define LN_telexNumber "telexNumber"
+#define NID_telexNumber 865
+#define OBJ_telexNumber OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier 866
+#define OBJ_teletexTerminalIdentifier OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber 867
+#define OBJ_facsimileTelephoneNumber OBJ_X509,23L
+
+#define LN_x121Address "x121Address"
+#define NID_x121Address 868
+#define OBJ_x121Address OBJ_X509,24L
+
+#define LN_internationaliSDNNumber "internationaliSDNNumber"
+#define NID_internationaliSDNNumber 869
+#define OBJ_internationaliSDNNumber OBJ_X509,25L
+
+#define LN_registeredAddress "registeredAddress"
+#define NID_registeredAddress 870
+#define OBJ_registeredAddress OBJ_X509,26L
+
+#define LN_destinationIndicator "destinationIndicator"
+#define NID_destinationIndicator 871
+#define OBJ_destinationIndicator OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod 872
+#define OBJ_preferredDeliveryMethod OBJ_X509,28L
+
+#define LN_presentationAddress "presentationAddress"
+#define NID_presentationAddress 873
+#define OBJ_presentationAddress OBJ_X509,29L
+
+#define LN_supportedApplicationContext "supportedApplicationContext"
+#define NID_supportedApplicationContext 874
+#define OBJ_supportedApplicationContext OBJ_X509,30L
+
+#define SN_member "member"
+#define NID_member 875
+#define OBJ_member OBJ_X509,31L
+
+#define SN_owner "owner"
+#define NID_owner 876
+#define OBJ_owner OBJ_X509,32L
+
+#define LN_roleOccupant "roleOccupant"
+#define NID_roleOccupant 877
+#define OBJ_roleOccupant OBJ_X509,33L
+
+#define SN_seeAlso "seeAlso"
+#define NID_seeAlso 878
+#define OBJ_seeAlso OBJ_X509,34L
+
+#define LN_userPassword "userPassword"
+#define NID_userPassword 879
+#define OBJ_userPassword OBJ_X509,35L
+
+#define LN_userCertificate "userCertificate"
+#define NID_userCertificate 880
+#define OBJ_userCertificate OBJ_X509,36L
+
+#define LN_cACertificate "cACertificate"
+#define NID_cACertificate 881
+#define OBJ_cACertificate OBJ_X509,37L
+
+#define LN_authorityRevocationList "authorityRevocationList"
+#define NID_authorityRevocationList 882
+#define OBJ_authorityRevocationList OBJ_X509,38L
+
+#define LN_certificateRevocationList "certificateRevocationList"
+#define NID_certificateRevocationList 883
+#define OBJ_certificateRevocationList OBJ_X509,39L
+
+#define LN_crossCertificatePair "crossCertificatePair"
+#define NID_crossCertificatePair 884
+#define OBJ_crossCertificatePair OBJ_X509,40L
+
+#define SN_name "name"
+#define LN_name "name"
+#define NID_name 173
+#define OBJ_name OBJ_X509,41L
+
+#define SN_givenName "GN"
+#define LN_givenName "givenName"
+#define NID_givenName 99
+#define OBJ_givenName OBJ_X509,42L
+
+#define SN_initials "initials"
+#define LN_initials "initials"
+#define NID_initials 101
+#define OBJ_initials OBJ_X509,43L
+
+#define LN_generationQualifier "generationQualifier"
+#define NID_generationQualifier 509
+#define OBJ_generationQualifier OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier 503
+#define OBJ_x500UniqueIdentifier OBJ_X509,45L
+
+#define SN_dnQualifier "dnQualifier"
+#define LN_dnQualifier "dnQualifier"
+#define NID_dnQualifier 174
+#define OBJ_dnQualifier OBJ_X509,46L
+
+#define LN_enhancedSearchGuide "enhancedSearchGuide"
+#define NID_enhancedSearchGuide 885
+#define OBJ_enhancedSearchGuide OBJ_X509,47L
+
+#define LN_protocolInformation "protocolInformation"
+#define NID_protocolInformation 886
+#define OBJ_protocolInformation OBJ_X509,48L
+
+#define LN_distinguishedName "distinguishedName"
+#define NID_distinguishedName 887
+#define OBJ_distinguishedName OBJ_X509,49L
+
+#define LN_uniqueMember "uniqueMember"
+#define NID_uniqueMember 888
+#define OBJ_uniqueMember OBJ_X509,50L
+
+#define LN_houseIdentifier "houseIdentifier"
+#define NID_houseIdentifier 889
+#define OBJ_houseIdentifier OBJ_X509,51L
+
+#define LN_supportedAlgorithms "supportedAlgorithms"
+#define NID_supportedAlgorithms 890
+#define OBJ_supportedAlgorithms OBJ_X509,52L
+
+#define LN_deltaRevocationList "deltaRevocationList"
+#define NID_deltaRevocationList 891
+#define OBJ_deltaRevocationList OBJ_X509,53L
+
+#define SN_dmdName "dmdName"
+#define NID_dmdName 892
+#define OBJ_dmdName OBJ_X509,54L
+
+#define LN_pseudonym "pseudonym"
+#define NID_pseudonym 510
+#define OBJ_pseudonym OBJ_X509,65L
+
+#define SN_role "role"
+#define LN_role "role"
+#define NID_role 400
+#define OBJ_role OBJ_X509,72L
+
+#define SN_X500algorithms "X500algorithms"
+#define LN_X500algorithms "directory services - algorithms"
+#define NID_X500algorithms 378
+#define OBJ_X500algorithms OBJ_X500,8L
+
+#define SN_rsa "RSA"
+#define LN_rsa "rsa"
+#define NID_rsa 19
+#define OBJ_rsa OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA "RSA-MDC2"
+#define LN_mdc2WithRSA "mdc2WithRSA"
+#define NID_mdc2WithRSA 96
+#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2 "MDC2"
+#define LN_mdc2 "mdc2"
+#define NID_mdc2 95
+#define OBJ_mdc2 OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce "id-ce"
+#define NID_id_ce 81
+#define OBJ_id_ce OBJ_X500,29L
+
+#define SN_subject_directory_attributes "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes 769
+#define OBJ_subject_directory_attributes OBJ_id_ce,9L
+
+#define SN_subject_key_identifier "subjectKeyIdentifier"
+#define LN_subject_key_identifier "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier 82
+#define OBJ_subject_key_identifier OBJ_id_ce,14L
+
+#define SN_key_usage "keyUsage"
+#define LN_key_usage "X509v3 Key Usage"
+#define NID_key_usage 83
+#define OBJ_key_usage OBJ_id_ce,15L
+
+#define SN_private_key_usage_period "privateKeyUsagePeriod"
+#define LN_private_key_usage_period "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period 84
+#define OBJ_private_key_usage_period OBJ_id_ce,16L
+
+#define SN_subject_alt_name "subjectAltName"
+#define LN_subject_alt_name "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name 85
+#define OBJ_subject_alt_name OBJ_id_ce,17L
+
+#define SN_issuer_alt_name "issuerAltName"
+#define LN_issuer_alt_name "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name 86
+#define OBJ_issuer_alt_name OBJ_id_ce,18L
+
+#define SN_basic_constraints "basicConstraints"
+#define LN_basic_constraints "X509v3 Basic Constraints"
+#define NID_basic_constraints 87
+#define OBJ_basic_constraints OBJ_id_ce,19L
+
+#define SN_crl_number "crlNumber"
+#define LN_crl_number "X509v3 CRL Number"
+#define NID_crl_number 88
+#define OBJ_crl_number OBJ_id_ce,20L
+
+#define SN_crl_reason "CRLReason"
+#define LN_crl_reason "X509v3 CRL Reason Code"
+#define NID_crl_reason 141
+#define OBJ_crl_reason OBJ_id_ce,21L
+
+#define SN_invalidity_date "invalidityDate"
+#define LN_invalidity_date "Invalidity Date"
+#define NID_invalidity_date 142
+#define OBJ_invalidity_date OBJ_id_ce,24L
+
+#define SN_delta_crl "deltaCRL"
+#define LN_delta_crl "X509v3 Delta CRL Indicator"
+#define NID_delta_crl 140
+#define OBJ_delta_crl OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point "issuingDistributionPoint"
+#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point"
+#define NID_issuing_distribution_point 770
+#define OBJ_issuing_distribution_point OBJ_id_ce,28L
+
+#define SN_certificate_issuer "certificateIssuer"
+#define LN_certificate_issuer "X509v3 Certificate Issuer"
+#define NID_certificate_issuer 771
+#define OBJ_certificate_issuer OBJ_id_ce,29L
+
+#define SN_name_constraints "nameConstraints"
+#define LN_name_constraints "X509v3 Name Constraints"
+#define NID_name_constraints 666
+#define OBJ_name_constraints OBJ_id_ce,30L
+
+#define SN_crl_distribution_points "crlDistributionPoints"
+#define LN_crl_distribution_points "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points 103
+#define OBJ_crl_distribution_points OBJ_id_ce,31L
+
+#define SN_certificate_policies "certificatePolicies"
+#define LN_certificate_policies "X509v3 Certificate Policies"
+#define NID_certificate_policies 89
+#define OBJ_certificate_policies OBJ_id_ce,32L
+
+#define SN_any_policy "anyPolicy"
+#define LN_any_policy "X509v3 Any Policy"
+#define NID_any_policy 746
+#define OBJ_any_policy OBJ_certificate_policies,0L
+
+#define SN_policy_mappings "policyMappings"
+#define LN_policy_mappings "X509v3 Policy Mappings"
+#define NID_policy_mappings 747
+#define OBJ_policy_mappings OBJ_id_ce,33L
+
+#define SN_authority_key_identifier "authorityKeyIdentifier"
+#define LN_authority_key_identifier "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier 90
+#define OBJ_authority_key_identifier OBJ_id_ce,35L
+
+#define SN_policy_constraints "policyConstraints"
+#define LN_policy_constraints "X509v3 Policy Constraints"
+#define NID_policy_constraints 401
+#define OBJ_policy_constraints OBJ_id_ce,36L
+
+#define SN_ext_key_usage "extendedKeyUsage"
+#define LN_ext_key_usage "X509v3 Extended Key Usage"
+#define NID_ext_key_usage 126
+#define OBJ_ext_key_usage OBJ_id_ce,37L
+
+#define SN_freshest_crl "freshestCRL"
+#define LN_freshest_crl "X509v3 Freshest CRL"
+#define NID_freshest_crl 857
+#define OBJ_freshest_crl OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy "inhibitAnyPolicy"
+#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy 748
+#define OBJ_inhibit_any_policy OBJ_id_ce,54L
+
+#define SN_target_information "targetInformation"
+#define LN_target_information "X509v3 AC Targeting"
+#define NID_target_information 402
+#define OBJ_target_information OBJ_id_ce,55L
+
+#define SN_no_rev_avail "noRevAvail"
+#define LN_no_rev_avail "X509v3 No Revocation Available"
+#define NID_no_rev_avail 403
+#define OBJ_no_rev_avail OBJ_id_ce,56L
+
+#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage 910
+#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L
+
+#define SN_netscape "Netscape"
+#define LN_netscape "Netscape Communications Corp."
+#define NID_netscape 57
+#define OBJ_netscape 2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension "nsCertExt"
+#define LN_netscape_cert_extension "Netscape Certificate Extension"
+#define NID_netscape_cert_extension 58
+#define OBJ_netscape_cert_extension OBJ_netscape,1L
+
+#define SN_netscape_data_type "nsDataType"
+#define LN_netscape_data_type "Netscape Data Type"
+#define NID_netscape_data_type 59
+#define OBJ_netscape_data_type OBJ_netscape,2L
+
+#define SN_netscape_cert_type "nsCertType"
+#define LN_netscape_cert_type "Netscape Cert Type"
+#define NID_netscape_cert_type 71
+#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url "nsBaseUrl"
+#define LN_netscape_base_url "Netscape Base Url"
+#define NID_netscape_base_url 72
+#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url "nsRevocationUrl"
+#define LN_netscape_revocation_url "Netscape Revocation Url"
+#define NID_netscape_revocation_url 73
+#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url 74
+#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url "nsRenewalUrl"
+#define LN_netscape_renewal_url "Netscape Renewal Url"
+#define NID_netscape_renewal_url 75
+#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url 76
+#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name "nsSslServerName"
+#define LN_netscape_ssl_server_name "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name 77
+#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment "nsComment"
+#define LN_netscape_comment "Netscape Comment"
+#define NID_netscape_comment 78
+#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence "nsCertSequence"
+#define LN_netscape_cert_sequence "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence 79
+#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc "nsSGC"
+#define LN_ns_sgc "Netscape Server Gated Crypto"
+#define NID_ns_sgc 139
+#define OBJ_ns_sgc OBJ_netscape,4L,1L
+
+#define SN_org "ORG"
+#define LN_org "org"
+#define NID_org 379
+#define OBJ_org OBJ_iso,3L
+
+#define SN_dod "DOD"
+#define LN_dod "dod"
+#define NID_dod 380
+#define OBJ_dod OBJ_org,6L
+
+#define SN_iana "IANA"
+#define LN_iana "iana"
+#define NID_iana 381
+#define OBJ_iana OBJ_dod,1L
+
+#define OBJ_internet OBJ_iana
+
+#define SN_Directory "directory"
+#define LN_Directory "Directory"
+#define NID_Directory 382
+#define OBJ_Directory OBJ_internet,1L
+
+#define SN_Management "mgmt"
+#define LN_Management "Management"
+#define NID_Management 383
+#define OBJ_Management OBJ_internet,2L
+
+#define SN_Experimental "experimental"
+#define LN_Experimental "Experimental"
+#define NID_Experimental 384
+#define OBJ_Experimental OBJ_internet,3L
+
+#define SN_Private "private"
+#define LN_Private "Private"
+#define NID_Private 385
+#define OBJ_Private OBJ_internet,4L
+
+#define SN_Security "security"
+#define LN_Security "Security"
+#define NID_Security 386
+#define OBJ_Security OBJ_internet,5L
+
+#define SN_SNMPv2 "snmpv2"
+#define LN_SNMPv2 "SNMPv2"
+#define NID_SNMPv2 387
+#define OBJ_SNMPv2 OBJ_internet,6L
+
+#define LN_Mail "Mail"
+#define NID_Mail 388
+#define OBJ_Mail OBJ_internet,7L
+
+#define SN_Enterprises "enterprises"
+#define LN_Enterprises "Enterprises"
+#define NID_Enterprises 389
+#define OBJ_Enterprises OBJ_Private,1L
+
+#define SN_dcObject "dcobject"
+#define LN_dcObject "dcObject"
+#define NID_dcObject 390
+#define OBJ_dcObject OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs "mime-mhs"
+#define LN_mime_mhs "MIME MHS"
+#define NID_mime_mhs 504
+#define OBJ_mime_mhs OBJ_Mail,1L
+
+#define SN_mime_mhs_headings "mime-mhs-headings"
+#define LN_mime_mhs_headings "mime-mhs-headings"
+#define NID_mime_mhs_headings 505
+#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies "mime-mhs-bodies"
+#define LN_mime_mhs_bodies "mime-mhs-bodies"
+#define NID_mime_mhs_bodies 506
+#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message "id-hex-partial-message"
+#define LN_id_hex_partial_message "id-hex-partial-message"
+#define NID_id_hex_partial_message 507
+#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message "id-hex-multipart-message"
+#define LN_id_hex_multipart_message "id-hex-multipart-message"
+#define NID_id_hex_multipart_message 508
+#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L
+
+#define SN_zlib_compression "ZLIB"
+#define LN_zlib_compression "zlib compression"
+#define NID_zlib_compression 125
+#define OBJ_zlib_compression OBJ_id_smime_alg,8L
+
+#define OBJ_csor 2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms OBJ_csor,4L
+
+#define OBJ_aes OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb "AES-128-ECB"
+#define LN_aes_128_ecb "aes-128-ecb"
+#define NID_aes_128_ecb 418
+#define OBJ_aes_128_ecb OBJ_aes,1L
+
+#define SN_aes_128_cbc "AES-128-CBC"
+#define LN_aes_128_cbc "aes-128-cbc"
+#define NID_aes_128_cbc 419
+#define OBJ_aes_128_cbc OBJ_aes,2L
+
+#define SN_aes_128_ofb128 "AES-128-OFB"
+#define LN_aes_128_ofb128 "aes-128-ofb"
+#define NID_aes_128_ofb128 420
+#define OBJ_aes_128_ofb128 OBJ_aes,3L
+
+#define SN_aes_128_cfb128 "AES-128-CFB"
+#define LN_aes_128_cfb128 "aes-128-cfb"
+#define NID_aes_128_cfb128 421
+#define OBJ_aes_128_cfb128 OBJ_aes,4L
+
+#define SN_id_aes128_wrap "id-aes128-wrap"
+#define NID_id_aes128_wrap 788
+#define OBJ_id_aes128_wrap OBJ_aes,5L
+
+#define SN_aes_128_gcm "id-aes128-GCM"
+#define LN_aes_128_gcm "aes-128-gcm"
+#define NID_aes_128_gcm 895
+#define OBJ_aes_128_gcm OBJ_aes,6L
+
+#define SN_aes_128_ccm "id-aes128-CCM"
+#define LN_aes_128_ccm "aes-128-ccm"
+#define NID_aes_128_ccm 896
+#define OBJ_aes_128_ccm OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad 897
+#define OBJ_id_aes128_wrap_pad OBJ_aes,8L
+
+#define SN_aes_192_ecb "AES-192-ECB"
+#define LN_aes_192_ecb "aes-192-ecb"
+#define NID_aes_192_ecb 422
+#define OBJ_aes_192_ecb OBJ_aes,21L
+
+#define SN_aes_192_cbc "AES-192-CBC"
+#define LN_aes_192_cbc "aes-192-cbc"
+#define NID_aes_192_cbc 423
+#define OBJ_aes_192_cbc OBJ_aes,22L
+
+#define SN_aes_192_ofb128 "AES-192-OFB"
+#define LN_aes_192_ofb128 "aes-192-ofb"
+#define NID_aes_192_ofb128 424
+#define OBJ_aes_192_ofb128 OBJ_aes,23L
+
+#define SN_aes_192_cfb128 "AES-192-CFB"
+#define LN_aes_192_cfb128 "aes-192-cfb"
+#define NID_aes_192_cfb128 425
+#define OBJ_aes_192_cfb128 OBJ_aes,24L
+
+#define SN_id_aes192_wrap "id-aes192-wrap"
+#define NID_id_aes192_wrap 789
+#define OBJ_id_aes192_wrap OBJ_aes,25L
+
+#define SN_aes_192_gcm "id-aes192-GCM"
+#define LN_aes_192_gcm "aes-192-gcm"
+#define NID_aes_192_gcm 898
+#define OBJ_aes_192_gcm OBJ_aes,26L
+
+#define SN_aes_192_ccm "id-aes192-CCM"
+#define LN_aes_192_ccm "aes-192-ccm"
+#define NID_aes_192_ccm 899
+#define OBJ_aes_192_ccm OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad 900
+#define OBJ_id_aes192_wrap_pad OBJ_aes,28L
+
+#define SN_aes_256_ecb "AES-256-ECB"
+#define LN_aes_256_ecb "aes-256-ecb"
+#define NID_aes_256_ecb 426
+#define OBJ_aes_256_ecb OBJ_aes,41L
+
+#define SN_aes_256_cbc "AES-256-CBC"
+#define LN_aes_256_cbc "aes-256-cbc"
+#define NID_aes_256_cbc 427
+#define OBJ_aes_256_cbc OBJ_aes,42L
+
+#define SN_aes_256_ofb128 "AES-256-OFB"
+#define LN_aes_256_ofb128 "aes-256-ofb"
+#define NID_aes_256_ofb128 428
+#define OBJ_aes_256_ofb128 OBJ_aes,43L
+
+#define SN_aes_256_cfb128 "AES-256-CFB"
+#define LN_aes_256_cfb128 "aes-256-cfb"
+#define NID_aes_256_cfb128 429
+#define OBJ_aes_256_cfb128 OBJ_aes,44L
+
+#define SN_id_aes256_wrap "id-aes256-wrap"
+#define NID_id_aes256_wrap 790
+#define OBJ_id_aes256_wrap OBJ_aes,45L
+
+#define SN_aes_256_gcm "id-aes256-GCM"
+#define LN_aes_256_gcm "aes-256-gcm"
+#define NID_aes_256_gcm 901
+#define OBJ_aes_256_gcm OBJ_aes,46L
+
+#define SN_aes_256_ccm "id-aes256-CCM"
+#define LN_aes_256_ccm "aes-256-ccm"
+#define NID_aes_256_ccm 902
+#define OBJ_aes_256_ccm OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad 903
+#define OBJ_id_aes256_wrap_pad OBJ_aes,48L
+
+#define SN_aes_128_cfb1 "AES-128-CFB1"
+#define LN_aes_128_cfb1 "aes-128-cfb1"
+#define NID_aes_128_cfb1 650
+
+#define SN_aes_192_cfb1 "AES-192-CFB1"
+#define LN_aes_192_cfb1 "aes-192-cfb1"
+#define NID_aes_192_cfb1 651
+
+#define SN_aes_256_cfb1 "AES-256-CFB1"
+#define LN_aes_256_cfb1 "aes-256-cfb1"
+#define NID_aes_256_cfb1 652
+
+#define SN_aes_128_cfb8 "AES-128-CFB8"
+#define LN_aes_128_cfb8 "aes-128-cfb8"
+#define NID_aes_128_cfb8 653
+
+#define SN_aes_192_cfb8 "AES-192-CFB8"
+#define LN_aes_192_cfb8 "aes-192-cfb8"
+#define NID_aes_192_cfb8 654
+
+#define SN_aes_256_cfb8 "AES-256-CFB8"
+#define LN_aes_256_cfb8 "aes-256-cfb8"
+#define NID_aes_256_cfb8 655
+
+#define SN_aes_128_ctr "AES-128-CTR"
+#define LN_aes_128_ctr "aes-128-ctr"
+#define NID_aes_128_ctr 904
+
+#define SN_aes_192_ctr "AES-192-CTR"
+#define LN_aes_192_ctr "aes-192-ctr"
+#define NID_aes_192_ctr 905
+
+#define SN_aes_256_ctr "AES-256-CTR"
+#define LN_aes_256_ctr "aes-256-ctr"
+#define NID_aes_256_ctr 906
+
+#define SN_aes_128_xts "AES-128-XTS"
+#define LN_aes_128_xts "aes-128-xts"
+#define NID_aes_128_xts 913
+
+#define SN_aes_256_xts "AES-256-XTS"
+#define LN_aes_256_xts "aes-256-xts"
+#define NID_aes_256_xts 914
+
+#define SN_des_cfb1 "DES-CFB1"
+#define LN_des_cfb1 "des-cfb1"
+#define NID_des_cfb1 656
+
+#define SN_des_cfb8 "DES-CFB8"
+#define LN_des_cfb8 "des-cfb8"
+#define NID_des_cfb8 657
+
+#define SN_des_ede3_cfb1 "DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1 "des-ede3-cfb1"
+#define NID_des_ede3_cfb1 658
+
+#define SN_des_ede3_cfb8 "DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8 "des-ede3-cfb8"
+#define NID_des_ede3_cfb8 659
+
+#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L
+
+#define SN_sha256 "SHA256"
+#define LN_sha256 "sha256"
+#define NID_sha256 672
+#define OBJ_sha256 OBJ_nist_hashalgs,1L
+
+#define SN_sha384 "SHA384"
+#define LN_sha384 "sha384"
+#define NID_sha384 673
+#define OBJ_sha384 OBJ_nist_hashalgs,2L
+
+#define SN_sha512 "SHA512"
+#define LN_sha512 "sha512"
+#define NID_sha512 674
+#define OBJ_sha512 OBJ_nist_hashalgs,3L
+
+#define SN_sha224 "SHA224"
+#define LN_sha224 "sha224"
+#define NID_sha224 675
+#define OBJ_sha224 OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224 "dsa_with_SHA224"
+#define NID_dsa_with_SHA224 802
+#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256 "dsa_with_SHA256"
+#define NID_dsa_with_SHA256 803
+#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code "holdInstructionCode"
+#define LN_hold_instruction_code "Hold Instruction Code"
+#define NID_hold_instruction_code 430
+#define OBJ_hold_instruction_code OBJ_id_ce,23L
+
+#define OBJ_holdInstruction OBJ_X9_57,2L
+
+#define SN_hold_instruction_none "holdInstructionNone"
+#define LN_hold_instruction_none "Hold Instruction None"
+#define NID_hold_instruction_none 431
+#define OBJ_hold_instruction_none OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer 432
+#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject "holdInstructionReject"
+#define LN_hold_instruction_reject "Hold Instruction Reject"
+#define NID_hold_instruction_reject 433
+#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L
+
+#define SN_data "data"
+#define NID_data 434
+#define OBJ_data OBJ_itu_t,9L
+
+#define SN_pss "pss"
+#define NID_pss 435
+#define OBJ_pss OBJ_data,2342L
+
+#define SN_ucl "ucl"
+#define NID_ucl 436
+#define OBJ_ucl OBJ_pss,19200300L
+
+#define SN_pilot "pilot"
+#define NID_pilot 437
+#define OBJ_pilot OBJ_ucl,100L
+
+#define LN_pilotAttributeType "pilotAttributeType"
+#define NID_pilotAttributeType 438
+#define OBJ_pilotAttributeType OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax 439
+#define OBJ_pilotAttributeSyntax OBJ_pilot,3L
+
+#define LN_pilotObjectClass "pilotObjectClass"
+#define NID_pilotObjectClass 440
+#define OBJ_pilotObjectClass OBJ_pilot,4L
+
+#define LN_pilotGroups "pilotGroups"
+#define NID_pilotGroups 441
+#define OBJ_pilotGroups OBJ_pilot,10L
+
+#define LN_iA5StringSyntax "iA5StringSyntax"
+#define NID_iA5StringSyntax 442
+#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax 443
+#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject "pilotObject"
+#define NID_pilotObject 444
+#define OBJ_pilotObject OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson "pilotPerson"
+#define NID_pilotPerson 445
+#define OBJ_pilotPerson OBJ_pilotObjectClass,4L
+
+#define SN_account "account"
+#define NID_account 446
+#define OBJ_account OBJ_pilotObjectClass,5L
+
+#define SN_document "document"
+#define NID_document 447
+#define OBJ_document OBJ_pilotObjectClass,6L
+
+#define SN_room "room"
+#define NID_room 448
+#define OBJ_room OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries "documentSeries"
+#define NID_documentSeries 449
+#define OBJ_documentSeries OBJ_pilotObjectClass,9L
+
+#define SN_Domain "domain"
+#define LN_Domain "Domain"
+#define NID_Domain 392
+#define OBJ_Domain OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart "rFC822localPart"
+#define NID_rFC822localPart 450
+#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain "dNSDomain"
+#define NID_dNSDomain 451
+#define OBJ_dNSDomain OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject "domainRelatedObject"
+#define NID_domainRelatedObject 452
+#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry "friendlyCountry"
+#define NID_friendlyCountry 453
+#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject "simpleSecurityObject"
+#define NID_simpleSecurityObject 454
+#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization "pilotOrganization"
+#define NID_pilotOrganization 455
+#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA "pilotDSA"
+#define NID_pilotDSA 456
+#define OBJ_pilotDSA OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData "qualityLabelledData"
+#define NID_qualityLabelledData 457
+#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L
+
+#define SN_userId "UID"
+#define LN_userId "userId"
+#define NID_userId 458
+#define OBJ_userId OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress "textEncodedORAddress"
+#define NID_textEncodedORAddress 459
+#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox "mail"
+#define LN_rfc822Mailbox "rfc822Mailbox"
+#define NID_rfc822Mailbox 460
+#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L
+
+#define SN_info "info"
+#define NID_info 461
+#define OBJ_info OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink "favouriteDrink"
+#define NID_favouriteDrink 462
+#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber "roomNumber"
+#define NID_roomNumber 463
+#define OBJ_roomNumber OBJ_pilotAttributeType,6L
+
+#define SN_photo "photo"
+#define NID_photo 464
+#define OBJ_photo OBJ_pilotAttributeType,7L
+
+#define LN_userClass "userClass"
+#define NID_userClass 465
+#define OBJ_userClass OBJ_pilotAttributeType,8L
+
+#define SN_host "host"
+#define NID_host 466
+#define OBJ_host OBJ_pilotAttributeType,9L
+
+#define SN_manager "manager"
+#define NID_manager 467
+#define OBJ_manager OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier "documentIdentifier"
+#define NID_documentIdentifier 468
+#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle "documentTitle"
+#define NID_documentTitle 469
+#define OBJ_documentTitle OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion "documentVersion"
+#define NID_documentVersion 470
+#define OBJ_documentVersion OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor "documentAuthor"
+#define NID_documentAuthor 471
+#define OBJ_documentAuthor OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation "documentLocation"
+#define NID_documentLocation 472
+#define OBJ_documentLocation OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber "homeTelephoneNumber"
+#define NID_homeTelephoneNumber 473
+#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L
+
+#define SN_secretary "secretary"
+#define NID_secretary 474
+#define OBJ_secretary OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox "otherMailbox"
+#define NID_otherMailbox 475
+#define OBJ_otherMailbox OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime "lastModifiedTime"
+#define NID_lastModifiedTime 476
+#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy "lastModifiedBy"
+#define NID_lastModifiedBy 477
+#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent "DC"
+#define LN_domainComponent "domainComponent"
+#define NID_domainComponent 391
+#define OBJ_domainComponent OBJ_pilotAttributeType,25L
+
+#define LN_aRecord "aRecord"
+#define NID_aRecord 478
+#define OBJ_aRecord OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27 "pilotAttributeType27"
+#define NID_pilotAttributeType27 479
+#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord "mXRecord"
+#define NID_mXRecord 480
+#define OBJ_mXRecord OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord "nSRecord"
+#define NID_nSRecord 481
+#define OBJ_nSRecord OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord "sOARecord"
+#define NID_sOARecord 482
+#define OBJ_sOARecord OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord "cNAMERecord"
+#define NID_cNAMERecord 483
+#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain "associatedDomain"
+#define NID_associatedDomain 484
+#define OBJ_associatedDomain OBJ_pilotAttributeType,37L
+
+#define LN_associatedName "associatedName"
+#define NID_associatedName 485
+#define OBJ_associatedName OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress "homePostalAddress"
+#define NID_homePostalAddress 486
+#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle "personalTitle"
+#define NID_personalTitle 487
+#define OBJ_personalTitle OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber 488
+#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber 489
+#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName "friendlyCountryName"
+#define NID_friendlyCountryName 490
+#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus "organizationalStatus"
+#define NID_organizationalStatus 491
+#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox "janetMailbox"
+#define NID_janetMailbox 492
+#define OBJ_janetMailbox OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption "mailPreferenceOption"
+#define NID_mailPreferenceOption 493
+#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L
+
+#define LN_buildingName "buildingName"
+#define NID_buildingName 494
+#define OBJ_buildingName OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality "dSAQuality"
+#define NID_dSAQuality 495
+#define OBJ_dSAQuality OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality "singleLevelQuality"
+#define NID_singleLevelQuality 496
+#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality 497
+#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality 498
+#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature "personalSignature"
+#define NID_personalSignature 499
+#define OBJ_personalSignature OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect "dITRedirect"
+#define NID_dITRedirect 500
+#define OBJ_dITRedirect OBJ_pilotAttributeType,54L
+
+#define SN_audio "audio"
+#define NID_audio 501
+#define OBJ_audio OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher "documentPublisher"
+#define NID_documentPublisher 502
+#define OBJ_documentPublisher OBJ_pilotAttributeType,56L
+
+#define SN_id_set "id-set"
+#define LN_id_set "Secure Electronic Transactions"
+#define NID_id_set 512
+#define OBJ_id_set OBJ_international_organizations,42L
+
+#define SN_set_ctype "set-ctype"
+#define LN_set_ctype "content types"
+#define NID_set_ctype 513
+#define OBJ_set_ctype OBJ_id_set,0L
+
+#define SN_set_msgExt "set-msgExt"
+#define LN_set_msgExt "message extensions"
+#define NID_set_msgExt 514
+#define OBJ_set_msgExt OBJ_id_set,1L
+
+#define SN_set_attr "set-attr"
+#define NID_set_attr 515
+#define OBJ_set_attr OBJ_id_set,3L
+
+#define SN_set_policy "set-policy"
+#define NID_set_policy 516
+#define OBJ_set_policy OBJ_id_set,5L
+
+#define SN_set_certExt "set-certExt"
+#define LN_set_certExt "certificate extensions"
+#define NID_set_certExt 517
+#define OBJ_set_certExt OBJ_id_set,7L
+
+#define SN_set_brand "set-brand"
+#define NID_set_brand 518
+#define OBJ_set_brand OBJ_id_set,8L
+
+#define SN_setct_PANData "setct-PANData"
+#define NID_setct_PANData 519
+#define OBJ_setct_PANData OBJ_set_ctype,0L
+
+#define SN_setct_PANToken "setct-PANToken"
+#define NID_setct_PANToken 520
+#define OBJ_setct_PANToken OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly "setct-PANOnly"
+#define NID_setct_PANOnly 521
+#define OBJ_setct_PANOnly OBJ_set_ctype,2L
+
+#define SN_setct_OIData "setct-OIData"
+#define NID_setct_OIData 522
+#define OBJ_setct_OIData OBJ_set_ctype,3L
+
+#define SN_setct_PI "setct-PI"
+#define NID_setct_PI 523
+#define OBJ_setct_PI OBJ_set_ctype,4L
+
+#define SN_setct_PIData "setct-PIData"
+#define NID_setct_PIData 524
+#define OBJ_setct_PIData OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned 525
+#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L
+
+#define SN_setct_HODInput "setct-HODInput"
+#define NID_setct_HODInput 526
+#define OBJ_setct_HODInput OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage 527
+#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage 528
+#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage 529
+#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq 530
+#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData "setct-PInitResData"
+#define NID_setct_PInitResData 531
+#define OBJ_setct_PInitResData OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS "setct-PI-TBS"
+#define NID_setct_PI_TBS 532
+#define OBJ_setct_PI_TBS OBJ_set_ctype,13L
+
+#define SN_setct_PResData "setct-PResData"
+#define NID_setct_PResData 533
+#define OBJ_setct_PResData OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS 534
+#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS "setct-AuthResTBS"
+#define NID_setct_AuthResTBS 535
+#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX 536
+#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS 537
+#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData "setct-CapTokenData"
+#define NID_setct_CapTokenData 538
+#define OBJ_setct_CapTokenData OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS 539
+#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg 540
+#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS 541
+#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData "setct-AuthRevResData"
+#define NID_setct_AuthRevResData 542
+#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS 543
+#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS "setct-CapReqTBS"
+#define NID_setct_CapReqTBS 544
+#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX 545
+#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L
+
+#define SN_setct_CapResData "setct-CapResData"
+#define NID_setct_CapResData 546
+#define OBJ_setct_CapResData OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS 547
+#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX 548
+#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData "setct-CapRevResData"
+#define NID_setct_CapRevResData 549
+#define OBJ_setct_CapRevResData OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS "setct-CredReqTBS"
+#define NID_setct_CredReqTBS 550
+#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX 551
+#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L
+
+#define SN_setct_CredResData "setct-CredResData"
+#define NID_setct_CredResData 552
+#define OBJ_setct_CredResData OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS 553
+#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX 554
+#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData "setct-CredRevResData"
+#define NID_setct_CredRevResData 555
+#define OBJ_setct_CredRevResData OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData "setct-PCertReqData"
+#define NID_setct_PCertReqData 556
+#define OBJ_setct_PCertReqData OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS "setct-PCertResTBS"
+#define NID_setct_PCertResTBS 557
+#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData 558
+#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData 559
+#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS 560
+#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS 561
+#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS 562
+#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData "setct-CertReqData"
+#define NID_setct_CertReqData 563
+#define OBJ_setct_CertReqData OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS "setct-CertReqTBS"
+#define NID_setct_CertReqTBS 564
+#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L
+
+#define SN_setct_CertResData "setct-CertResData"
+#define NID_setct_CertResData 565
+#define OBJ_setct_CertResData OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS 566
+#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS "setct-ErrorTBS"
+#define NID_setct_ErrorTBS 567
+#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE 568
+#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE 569
+#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE 570
+#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE "setct-AuthResTBE"
+#define NID_setct_AuthResTBE 571
+#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX 572
+#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE 573
+#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE 574
+#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX 575
+#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE 576
+#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE 577
+#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE 578
+#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB 579
+#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE "setct-CapReqTBE"
+#define NID_setct_CapReqTBE 580
+#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX 581
+#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE "setct-CapResTBE"
+#define NID_setct_CapResTBE 582
+#define OBJ_setct_CapResTBE OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE 583
+#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX 584
+#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE 585
+#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE "setct-CredReqTBE"
+#define NID_setct_CredReqTBE 586
+#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX 587
+#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE "setct-CredResTBE"
+#define NID_setct_CredResTBE 588
+#define OBJ_setct_CredResTBE OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE 589
+#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX 590
+#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE 591
+#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE 592
+#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE 593
+#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE 594
+#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE "setct-CertReqTBE"
+#define NID_setct_CertReqTBE 595
+#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX 596
+#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE "setct-CertResTBE"
+#define NID_setct_CertResTBE 597
+#define OBJ_setct_CertResTBE OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS 598
+#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS 599
+#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS 600
+#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt "setext-genCrypt"
+#define LN_setext_genCrypt "generic cryptogram"
+#define NID_setext_genCrypt 601
+#define OBJ_setext_genCrypt OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth "setext-miAuth"
+#define LN_setext_miAuth "merchant initiated auth"
+#define NID_setext_miAuth 602
+#define OBJ_setext_miAuth OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure "setext-pinSecure"
+#define NID_setext_pinSecure 603
+#define OBJ_setext_pinSecure OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny "setext-pinAny"
+#define NID_setext_pinAny 604
+#define OBJ_setext_pinAny OBJ_set_msgExt,5L
+
+#define SN_setext_track2 "setext-track2"
+#define NID_setext_track2 605
+#define OBJ_setext_track2 OBJ_set_msgExt,7L
+
+#define SN_setext_cv "setext-cv"
+#define LN_setext_cv "additional verification"
+#define NID_setext_cv 606
+#define OBJ_setext_cv OBJ_set_msgExt,8L
+
+#define SN_set_policy_root "set-policy-root"
+#define NID_set_policy_root 607
+#define OBJ_set_policy_root OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot "setCext-hashedRoot"
+#define NID_setCext_hashedRoot 608
+#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L
+
+#define SN_setCext_certType "setCext-certType"
+#define NID_setCext_certType 609
+#define OBJ_setCext_certType OBJ_set_certExt,1L
+
+#define SN_setCext_merchData "setCext-merchData"
+#define NID_setCext_merchData 610
+#define OBJ_setCext_merchData OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired "setCext-cCertRequired"
+#define NID_setCext_cCertRequired 611
+#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling "setCext-tunneling"
+#define NID_setCext_tunneling 612
+#define OBJ_setCext_tunneling OBJ_set_certExt,4L
+
+#define SN_setCext_setExt "setCext-setExt"
+#define NID_setCext_setExt 613
+#define OBJ_setCext_setExt OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf "setCext-setQualf"
+#define NID_setCext_setQualf 614
+#define OBJ_setCext_setQualf OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities 615
+#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier 616
+#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data "setCext-Track2Data"
+#define NID_setCext_Track2Data 617
+#define OBJ_setCext_Track2Data OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType "setCext-TokenType"
+#define NID_setCext_TokenType 618
+#define OBJ_setCext_TokenType OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities 619
+#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert "setAttr-Cert"
+#define NID_setAttr_Cert 620
+#define OBJ_setAttr_Cert OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap "payment gateway capabilities"
+#define NID_setAttr_PGWYcap 621
+#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType "setAttr-TokenType"
+#define NID_setAttr_TokenType 622
+#define OBJ_setAttr_TokenType OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap "setAttr-IssCap"
+#define LN_setAttr_IssCap "issuer capabilities"
+#define NID_setAttr_IssCap 623
+#define OBJ_setAttr_IssCap OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb "set-rootKeyThumb"
+#define NID_set_rootKeyThumb 624
+#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy "set-addPolicy"
+#define NID_set_addPolicy 625
+#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV 626
+#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime 627
+#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM 628
+#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2 629
+#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig 630
+#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm "generate cryptogram"
+#define NID_setAttr_GenCryptgrm 631
+#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc "setAttr-T2Enc"
+#define LN_setAttr_T2Enc "encrypted track 2"
+#define NID_setAttr_T2Enc 632
+#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt "cleartext track 2"
+#define NID_setAttr_T2cleartxt 633
+#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig "ICC or token signature"
+#define NID_setAttr_TokICCsig 634
+#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig "secure device signature"
+#define NID_setAttr_SecDevSig 635
+#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA 636
+#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L
+
+#define SN_set_brand_Diners "set-brand-Diners"
+#define NID_set_brand_Diners 637
+#define OBJ_set_brand_Diners OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress 638
+#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L
+
+#define SN_set_brand_JCB "set-brand-JCB"
+#define NID_set_brand_JCB 639
+#define OBJ_set_brand_JCB OBJ_set_brand,35L
+
+#define SN_set_brand_Visa "set-brand-Visa"
+#define NID_set_brand_Visa 640
+#define OBJ_set_brand_Visa OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard "set-brand-MasterCard"
+#define NID_set_brand_MasterCard 641
+#define OBJ_set_brand_MasterCard OBJ_set_brand,5L
+
+#define SN_set_brand_Novus "set-brand-Novus"
+#define NID_set_brand_Novus 642
+#define OBJ_set_brand_Novus OBJ_set_brand,6011L
+
+#define SN_des_cdmf "DES-CDMF"
+#define LN_des_cdmf "des-cdmf"
+#define NID_des_cdmf 643
+#define OBJ_des_cdmf OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET 644
+#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3 "Oakley-EC2N-3"
+#define LN_ipsec3 "ipsec3"
+#define NID_ipsec3 749
+
+#define SN_ipsec4 "Oakley-EC2N-4"
+#define LN_ipsec4 "ipsec4"
+#define NID_ipsec4 750
+
+#define SN_whirlpool "whirlpool"
+#define NID_whirlpool 804
+#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro "cryptopro"
+#define NID_cryptopro 805
+#define OBJ_cryptopro OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom "cryptocom"
+#define NID_cryptocom 806
+#define OBJ_cryptocom OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001 807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94 808
+#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94 "md_gost94"
+#define LN_id_GostR3411_94 "GOST R 34.11-94"
+#define NID_id_GostR3411_94 809
+#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94 810
+#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001 "gost2001"
+#define LN_id_GostR3410_2001 "GOST R 34.10-2001"
+#define NID_id_GostR3410_2001 811
+#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94 "gost94"
+#define LN_id_GostR3410_94 "GOST R 34.10-94"
+#define NID_id_GostR3410_94 812
+#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89 "gost89"
+#define LN_id_Gost28147_89 "GOST 28147-89"
+#define NID_id_Gost28147_89 813
+#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L
+
+#define SN_gost89_cnt "gost89-cnt"
+#define NID_gost89_cnt 814
+
+#define SN_id_Gost28147_89_MAC "gost-mac"
+#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC 815
+#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf "prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf 816
+#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH 817
+#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH "id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH 818
+#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing 820
+#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet 821
+#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet 822
+#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet 823
+#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet 831
+#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet 839
+#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a "id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a 845
+#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis 846
+#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b "id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b 847
+#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis 848
+#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc 849
+#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc "gost94cc"
+#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc 850
+#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc "gost2001cc"
+#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc 851
+#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc 852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc 854
+#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L
+
+#define SN_camellia_128_cbc "CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc "camellia-128-cbc"
+#define NID_camellia_128_cbc 751
+#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc "CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc "camellia-192-cbc"
+#define NID_camellia_192_cbc 752
+#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc "CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc "camellia-256-cbc"
+#define NID_camellia_256_cbc 753
+#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define SN_id_camellia128_wrap "id-camellia128-wrap"
+#define NID_id_camellia128_wrap 907
+#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap "id-camellia192-wrap"
+#define NID_id_camellia192_wrap 908
+#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap "id-camellia256-wrap"
+#define NID_id_camellia256_wrap 909
+#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
+#define OBJ_ntt_ds 0L,3L,4401L,5L
+
+#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb "CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb "camellia-128-ecb"
+#define NID_camellia_128_ecb 754
+#define OBJ_camellia_128_ecb OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128 "camellia-128-ofb"
+#define NID_camellia_128_ofb128 766
+#define OBJ_camellia_128_ofb128 OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128 "camellia-128-cfb"
+#define NID_camellia_128_cfb128 757
+#define OBJ_camellia_128_cfb128 OBJ_camellia,4L
+
+#define SN_camellia_192_ecb "CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb "camellia-192-ecb"
+#define NID_camellia_192_ecb 755
+#define OBJ_camellia_192_ecb OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128 "camellia-192-ofb"
+#define NID_camellia_192_ofb128 767
+#define OBJ_camellia_192_ofb128 OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128 "camellia-192-cfb"
+#define NID_camellia_192_cfb128 758
+#define OBJ_camellia_192_cfb128 OBJ_camellia,24L
+
+#define SN_camellia_256_ecb "CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb "camellia-256-ecb"
+#define NID_camellia_256_ecb 756
+#define OBJ_camellia_256_ecb OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128 "camellia-256-ofb"
+#define NID_camellia_256_ofb128 768
+#define OBJ_camellia_256_ofb128 OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128 "camellia-256-cfb"
+#define NID_camellia_256_cfb128 759
+#define OBJ_camellia_256_cfb128 OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1 "camellia-128-cfb1"
+#define NID_camellia_128_cfb1 760
+
+#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1 "camellia-192-cfb1"
+#define NID_camellia_192_cfb1 761
+
+#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1 "camellia-256-cfb1"
+#define NID_camellia_256_cfb1 762
+
+#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8 "camellia-128-cfb8"
+#define NID_camellia_128_cfb8 763
+
+#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8 "camellia-192-cfb8"
+#define NID_camellia_192_cfb8 764
+
+#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8 "camellia-256-cfb8"
+#define NID_camellia_256_cfb8 765
+
+#define SN_kisa "KISA"
+#define LN_kisa "kisa"
+#define NID_kisa 773
+#define OBJ_kisa OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb "SEED-ECB"
+#define LN_seed_ecb "seed-ecb"
+#define NID_seed_ecb 776
+#define OBJ_seed_ecb OBJ_kisa,1L,3L
+
+#define SN_seed_cbc "SEED-CBC"
+#define LN_seed_cbc "seed-cbc"
+#define NID_seed_cbc 777
+#define OBJ_seed_cbc OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128 "SEED-CFB"
+#define LN_seed_cfb128 "seed-cfb"
+#define NID_seed_cfb128 779
+#define OBJ_seed_cfb128 OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128 "SEED-OFB"
+#define LN_seed_ofb128 "seed-ofb"
+#define NID_seed_ofb128 778
+#define OBJ_seed_ofb128 OBJ_kisa,1L,6L
+
+#define SN_hmac "HMAC"
+#define LN_hmac "hmac"
+#define NID_hmac 855
+
+#define SN_cmac "CMAC"
+#define LN_cmac "cmac"
+#define NID_cmac 894
+
+#define SN_rc4_hmac_md5 "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5 "rc4-hmac-md5"
+#define NID_rc4_hmac_md5 915
+
+#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1 916
+
+#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1 917
+
+#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1 918
+
+#define SN_dhpublicnumber "dhpublicnumber"
+#define LN_dhpublicnumber "X9.42 DH"
+#define NID_dhpublicnumber 920
+#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L
+
+#define SN_brainpoolP160r1 "brainpoolP160r1"
+#define NID_brainpoolP160r1 921
+#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
+
+#define SN_brainpoolP160t1 "brainpoolP160t1"
+#define NID_brainpoolP160t1 922
+#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
+
+#define SN_brainpoolP192r1 "brainpoolP192r1"
+#define NID_brainpoolP192r1 923
+#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
+
+#define SN_brainpoolP192t1 "brainpoolP192t1"
+#define NID_brainpoolP192t1 924
+#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
+
+#define SN_brainpoolP224r1 "brainpoolP224r1"
+#define NID_brainpoolP224r1 925
+#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
+
+#define SN_brainpoolP224t1 "brainpoolP224t1"
+#define NID_brainpoolP224t1 926
+#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
+
+#define SN_brainpoolP256r1 "brainpoolP256r1"
+#define NID_brainpoolP256r1 927
+#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
+
+#define SN_brainpoolP256t1 "brainpoolP256t1"
+#define NID_brainpoolP256t1 928
+#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
+
+#define SN_brainpoolP320r1 "brainpoolP320r1"
+#define NID_brainpoolP320r1 929
+#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
+
+#define SN_brainpoolP320t1 "brainpoolP320t1"
+#define NID_brainpoolP320t1 930
+#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
+
+#define SN_brainpoolP384r1 "brainpoolP384r1"
+#define NID_brainpoolP384r1 931
+#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
+
+#define SN_brainpoolP384t1 "brainpoolP384t1"
+#define NID_brainpoolP384t1 932
+#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
+
+#define SN_brainpoolP512r1 "brainpoolP512r1"
+#define NID_brainpoolP512r1 933
+#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
+
+#define SN_brainpoolP512t1 "brainpoolP512t1"
+#define NID_brainpoolP512t1 934
+#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
+
+#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L
+
+#define OBJ_secg_scheme OBJ_certicom_arc,1L
+
+#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936
+#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L
+
+#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937
+#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L
+
+#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938
+#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L
+
+#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939
+#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L
+
+#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940
+#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L
+
+#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941
+#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L
+
+#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942
+#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L
+
+#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943
+#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L
+
+#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944
+#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L
+
+#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945
+#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L
+
+#define SN_dh_std_kdf "dh-std-kdf"
+#define NID_dh_std_kdf 946
+
+#define SN_dh_cofactor_kdf "dh-cofactor-kdf"
+#define NID_dh_cofactor_kdf 947
+
+#define SN_X25519 "X25519"
+#define NID_X25519 948
+
+
+#endif  /* OPENSSL_HEADER_NID_H */
diff --git a/src/include/openssl/obj.h b/src/include/openssl/obj.h
index 32a4894..7e24820 100644
--- a/src/include/openssl/obj.h
+++ b/src/include/openssl/obj.h
@@ -60,7 +60,7 @@
 #include <openssl/base.h>
 
 #include <openssl/bytestring.h>
-#include <openssl/obj_mac.h>
+#include <openssl/nid.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -189,6 +189,32 @@
                                           int pkey_nid);
 
 
+/* Deprecated functions. */
+
+typedef struct obj_name_st {
+  int type;
+  const char *name;
+} OBJ_NAME;
+
+#define OBJ_NAME_TYPE_MD_METH 1
+#define OBJ_NAME_TYPE_CIPHER_METH 2
+
+/* OBJ_NAME_do_all_sorted calls |callback| zero or more times, each time with
+ * the name of a different primitive. If |type| is |OBJ_NAME_TYPE_MD_METH| then
+ * the primitives will be hash functions, alternatively if |type| is
+ * |OBJ_NAME_TYPE_CIPHER_METH| then the primitives will be ciphers or cipher
+ * modes.
+ *
+ * This function is ill-specified and should never be used. */
+OPENSSL_EXPORT void OBJ_NAME_do_all_sorted(
+    int type, void (*callback)(const OBJ_NAME *, void *arg), void *arg);
+
+/* OBJ_NAME_do_all calls |OBJ_NAME_do_all_sorted|. */
+OPENSSL_EXPORT void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *,
+                                                               void *arg),
+                                    void *arg);
+
+
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/include/openssl/obj_mac.h b/src/include/openssl/obj_mac.h
index b636adc..e7ccadc 100644
--- a/src/include/openssl/obj_mac.h
+++ b/src/include/openssl/obj_mac.h
@@ -1,4144 +1,18 @@
-/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
- * following command:
- * perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h */
-
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/* Copyright (c) 2016, Google Inc.
  *
- * 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.]
- */
+ * 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. */
 
-#define SN_undef			"UNDEF"
-#define LN_undef			"undefined"
-#define NID_undef			0
-#define OBJ_undef			0L
+/* This header is provided in order to make compiling against code that expects
+   OpenSSL easier. */
 
-#define SN_itu_t		"ITU-T"
-#define LN_itu_t		"itu-t"
-#define NID_itu_t		645
-#define OBJ_itu_t		0L
-
-#define NID_ccitt		404
-#define OBJ_ccitt		OBJ_itu_t
-
-#define SN_iso		"ISO"
-#define LN_iso		"iso"
-#define NID_iso		181
-#define OBJ_iso		1L
-
-#define SN_joint_iso_itu_t		"JOINT-ISO-ITU-T"
-#define LN_joint_iso_itu_t		"joint-iso-itu-t"
-#define NID_joint_iso_itu_t		646
-#define OBJ_joint_iso_itu_t		2L
-
-#define NID_joint_iso_ccitt		393
-#define OBJ_joint_iso_ccitt		OBJ_joint_iso_itu_t
-
-#define SN_member_body		"member-body"
-#define LN_member_body		"ISO Member Body"
-#define NID_member_body		182
-#define OBJ_member_body		OBJ_iso,2L
-
-#define SN_identified_organization		"identified-organization"
-#define NID_identified_organization		676
-#define OBJ_identified_organization		OBJ_iso,3L
-
-#define SN_hmac_md5		"HMAC-MD5"
-#define LN_hmac_md5		"hmac-md5"
-#define NID_hmac_md5		780
-#define OBJ_hmac_md5		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
-
-#define SN_hmac_sha1		"HMAC-SHA1"
-#define LN_hmac_sha1		"hmac-sha1"
-#define NID_hmac_sha1		781
-#define OBJ_hmac_sha1		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
-
-#define SN_certicom_arc		"certicom-arc"
-#define NID_certicom_arc		677
-#define OBJ_certicom_arc		OBJ_identified_organization,132L
-
-#define SN_international_organizations		"international-organizations"
-#define LN_international_organizations		"International Organizations"
-#define NID_international_organizations		647
-#define OBJ_international_organizations		OBJ_joint_iso_itu_t,23L
-
-#define SN_wap		"wap"
-#define NID_wap		678
-#define OBJ_wap		OBJ_international_organizations,43L
-
-#define SN_wap_wsg		"wap-wsg"
-#define NID_wap_wsg		679
-#define OBJ_wap_wsg		OBJ_wap,1L
-
-#define SN_selected_attribute_types		"selected-attribute-types"
-#define LN_selected_attribute_types		"Selected Attribute Types"
-#define NID_selected_attribute_types		394
-#define OBJ_selected_attribute_types		OBJ_joint_iso_itu_t,5L,1L,5L
-
-#define SN_clearance		"clearance"
-#define NID_clearance		395
-#define OBJ_clearance		OBJ_selected_attribute_types,55L
-
-#define SN_ISO_US		"ISO-US"
-#define LN_ISO_US		"ISO US Member Body"
-#define NID_ISO_US		183
-#define OBJ_ISO_US		OBJ_member_body,840L
-
-#define SN_X9_57		"X9-57"
-#define LN_X9_57		"X9.57"
-#define NID_X9_57		184
-#define OBJ_X9_57		OBJ_ISO_US,10040L
-
-#define SN_X9cm		"X9cm"
-#define LN_X9cm		"X9.57 CM ?"
-#define NID_X9cm		185
-#define OBJ_X9cm		OBJ_X9_57,4L
-
-#define SN_dsa		"DSA"
-#define LN_dsa		"dsaEncryption"
-#define NID_dsa		116
-#define OBJ_dsa		OBJ_X9cm,1L
-
-#define SN_dsaWithSHA1		"DSA-SHA1"
-#define LN_dsaWithSHA1		"dsaWithSHA1"
-#define NID_dsaWithSHA1		113
-#define OBJ_dsaWithSHA1		OBJ_X9cm,3L
-
-#define SN_ansi_X9_62		"ansi-X9-62"
-#define LN_ansi_X9_62		"ANSI X9.62"
-#define NID_ansi_X9_62		405
-#define OBJ_ansi_X9_62		OBJ_ISO_US,10045L
-
-#define OBJ_X9_62_id_fieldType		OBJ_ansi_X9_62,1L
-
-#define SN_X9_62_prime_field		"prime-field"
-#define NID_X9_62_prime_field		406
-#define OBJ_X9_62_prime_field		OBJ_X9_62_id_fieldType,1L
-
-#define SN_X9_62_characteristic_two_field		"characteristic-two-field"
-#define NID_X9_62_characteristic_two_field		407
-#define OBJ_X9_62_characteristic_two_field		OBJ_X9_62_id_fieldType,2L
-
-#define SN_X9_62_id_characteristic_two_basis		"id-characteristic-two-basis"
-#define NID_X9_62_id_characteristic_two_basis		680
-#define OBJ_X9_62_id_characteristic_two_basis		OBJ_X9_62_characteristic_two_field,3L
-
-#define SN_X9_62_onBasis		"onBasis"
-#define NID_X9_62_onBasis		681
-#define OBJ_X9_62_onBasis		OBJ_X9_62_id_characteristic_two_basis,1L
-
-#define SN_X9_62_tpBasis		"tpBasis"
-#define NID_X9_62_tpBasis		682
-#define OBJ_X9_62_tpBasis		OBJ_X9_62_id_characteristic_two_basis,2L
-
-#define SN_X9_62_ppBasis		"ppBasis"
-#define NID_X9_62_ppBasis		683
-#define OBJ_X9_62_ppBasis		OBJ_X9_62_id_characteristic_two_basis,3L
-
-#define OBJ_X9_62_id_publicKeyType		OBJ_ansi_X9_62,2L
-
-#define SN_X9_62_id_ecPublicKey		"id-ecPublicKey"
-#define NID_X9_62_id_ecPublicKey		408
-#define OBJ_X9_62_id_ecPublicKey		OBJ_X9_62_id_publicKeyType,1L
-
-#define OBJ_X9_62_ellipticCurve		OBJ_ansi_X9_62,3L
-
-#define OBJ_X9_62_c_TwoCurve		OBJ_X9_62_ellipticCurve,0L
-
-#define SN_X9_62_c2pnb163v1		"c2pnb163v1"
-#define NID_X9_62_c2pnb163v1		684
-#define OBJ_X9_62_c2pnb163v1		OBJ_X9_62_c_TwoCurve,1L
-
-#define SN_X9_62_c2pnb163v2		"c2pnb163v2"
-#define NID_X9_62_c2pnb163v2		685
-#define OBJ_X9_62_c2pnb163v2		OBJ_X9_62_c_TwoCurve,2L
-
-#define SN_X9_62_c2pnb163v3		"c2pnb163v3"
-#define NID_X9_62_c2pnb163v3		686
-#define OBJ_X9_62_c2pnb163v3		OBJ_X9_62_c_TwoCurve,3L
-
-#define SN_X9_62_c2pnb176v1		"c2pnb176v1"
-#define NID_X9_62_c2pnb176v1		687
-#define OBJ_X9_62_c2pnb176v1		OBJ_X9_62_c_TwoCurve,4L
-
-#define SN_X9_62_c2tnb191v1		"c2tnb191v1"
-#define NID_X9_62_c2tnb191v1		688
-#define OBJ_X9_62_c2tnb191v1		OBJ_X9_62_c_TwoCurve,5L
-
-#define SN_X9_62_c2tnb191v2		"c2tnb191v2"
-#define NID_X9_62_c2tnb191v2		689
-#define OBJ_X9_62_c2tnb191v2		OBJ_X9_62_c_TwoCurve,6L
-
-#define SN_X9_62_c2tnb191v3		"c2tnb191v3"
-#define NID_X9_62_c2tnb191v3		690
-#define OBJ_X9_62_c2tnb191v3		OBJ_X9_62_c_TwoCurve,7L
-
-#define SN_X9_62_c2onb191v4		"c2onb191v4"
-#define NID_X9_62_c2onb191v4		691
-#define OBJ_X9_62_c2onb191v4		OBJ_X9_62_c_TwoCurve,8L
-
-#define SN_X9_62_c2onb191v5		"c2onb191v5"
-#define NID_X9_62_c2onb191v5		692
-#define OBJ_X9_62_c2onb191v5		OBJ_X9_62_c_TwoCurve,9L
-
-#define SN_X9_62_c2pnb208w1		"c2pnb208w1"
-#define NID_X9_62_c2pnb208w1		693
-#define OBJ_X9_62_c2pnb208w1		OBJ_X9_62_c_TwoCurve,10L
-
-#define SN_X9_62_c2tnb239v1		"c2tnb239v1"
-#define NID_X9_62_c2tnb239v1		694
-#define OBJ_X9_62_c2tnb239v1		OBJ_X9_62_c_TwoCurve,11L
-
-#define SN_X9_62_c2tnb239v2		"c2tnb239v2"
-#define NID_X9_62_c2tnb239v2		695
-#define OBJ_X9_62_c2tnb239v2		OBJ_X9_62_c_TwoCurve,12L
-
-#define SN_X9_62_c2tnb239v3		"c2tnb239v3"
-#define NID_X9_62_c2tnb239v3		696
-#define OBJ_X9_62_c2tnb239v3		OBJ_X9_62_c_TwoCurve,13L
-
-#define SN_X9_62_c2onb239v4		"c2onb239v4"
-#define NID_X9_62_c2onb239v4		697
-#define OBJ_X9_62_c2onb239v4		OBJ_X9_62_c_TwoCurve,14L
-
-#define SN_X9_62_c2onb239v5		"c2onb239v5"
-#define NID_X9_62_c2onb239v5		698
-#define OBJ_X9_62_c2onb239v5		OBJ_X9_62_c_TwoCurve,15L
-
-#define SN_X9_62_c2pnb272w1		"c2pnb272w1"
-#define NID_X9_62_c2pnb272w1		699
-#define OBJ_X9_62_c2pnb272w1		OBJ_X9_62_c_TwoCurve,16L
-
-#define SN_X9_62_c2pnb304w1		"c2pnb304w1"
-#define NID_X9_62_c2pnb304w1		700
-#define OBJ_X9_62_c2pnb304w1		OBJ_X9_62_c_TwoCurve,17L
-
-#define SN_X9_62_c2tnb359v1		"c2tnb359v1"
-#define NID_X9_62_c2tnb359v1		701
-#define OBJ_X9_62_c2tnb359v1		OBJ_X9_62_c_TwoCurve,18L
-
-#define SN_X9_62_c2pnb368w1		"c2pnb368w1"
-#define NID_X9_62_c2pnb368w1		702
-#define OBJ_X9_62_c2pnb368w1		OBJ_X9_62_c_TwoCurve,19L
-
-#define SN_X9_62_c2tnb431r1		"c2tnb431r1"
-#define NID_X9_62_c2tnb431r1		703
-#define OBJ_X9_62_c2tnb431r1		OBJ_X9_62_c_TwoCurve,20L
-
-#define OBJ_X9_62_primeCurve		OBJ_X9_62_ellipticCurve,1L
-
-#define SN_X9_62_prime192v1		"prime192v1"
-#define NID_X9_62_prime192v1		409
-#define OBJ_X9_62_prime192v1		OBJ_X9_62_primeCurve,1L
-
-#define SN_X9_62_prime192v2		"prime192v2"
-#define NID_X9_62_prime192v2		410
-#define OBJ_X9_62_prime192v2		OBJ_X9_62_primeCurve,2L
-
-#define SN_X9_62_prime192v3		"prime192v3"
-#define NID_X9_62_prime192v3		411
-#define OBJ_X9_62_prime192v3		OBJ_X9_62_primeCurve,3L
-
-#define SN_X9_62_prime239v1		"prime239v1"
-#define NID_X9_62_prime239v1		412
-#define OBJ_X9_62_prime239v1		OBJ_X9_62_primeCurve,4L
-
-#define SN_X9_62_prime239v2		"prime239v2"
-#define NID_X9_62_prime239v2		413
-#define OBJ_X9_62_prime239v2		OBJ_X9_62_primeCurve,5L
-
-#define SN_X9_62_prime239v3		"prime239v3"
-#define NID_X9_62_prime239v3		414
-#define OBJ_X9_62_prime239v3		OBJ_X9_62_primeCurve,6L
-
-#define SN_X9_62_prime256v1		"prime256v1"
-#define NID_X9_62_prime256v1		415
-#define OBJ_X9_62_prime256v1		OBJ_X9_62_primeCurve,7L
-
-#define OBJ_X9_62_id_ecSigType		OBJ_ansi_X9_62,4L
-
-#define SN_ecdsa_with_SHA1		"ecdsa-with-SHA1"
-#define NID_ecdsa_with_SHA1		416
-#define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
-
-#define SN_ecdsa_with_Recommended		"ecdsa-with-Recommended"
-#define NID_ecdsa_with_Recommended		791
-#define OBJ_ecdsa_with_Recommended		OBJ_X9_62_id_ecSigType,2L
-
-#define SN_ecdsa_with_Specified		"ecdsa-with-Specified"
-#define NID_ecdsa_with_Specified		792
-#define OBJ_ecdsa_with_Specified		OBJ_X9_62_id_ecSigType,3L
-
-#define SN_ecdsa_with_SHA224		"ecdsa-with-SHA224"
-#define NID_ecdsa_with_SHA224		793
-#define OBJ_ecdsa_with_SHA224		OBJ_ecdsa_with_Specified,1L
-
-#define SN_ecdsa_with_SHA256		"ecdsa-with-SHA256"
-#define NID_ecdsa_with_SHA256		794
-#define OBJ_ecdsa_with_SHA256		OBJ_ecdsa_with_Specified,2L
-
-#define SN_ecdsa_with_SHA384		"ecdsa-with-SHA384"
-#define NID_ecdsa_with_SHA384		795
-#define OBJ_ecdsa_with_SHA384		OBJ_ecdsa_with_Specified,3L
-
-#define SN_ecdsa_with_SHA512		"ecdsa-with-SHA512"
-#define NID_ecdsa_with_SHA512		796
-#define OBJ_ecdsa_with_SHA512		OBJ_ecdsa_with_Specified,4L
-
-#define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
-
-#define SN_secp112r1		"secp112r1"
-#define NID_secp112r1		704
-#define OBJ_secp112r1		OBJ_secg_ellipticCurve,6L
-
-#define SN_secp112r2		"secp112r2"
-#define NID_secp112r2		705
-#define OBJ_secp112r2		OBJ_secg_ellipticCurve,7L
-
-#define SN_secp128r1		"secp128r1"
-#define NID_secp128r1		706
-#define OBJ_secp128r1		OBJ_secg_ellipticCurve,28L
-
-#define SN_secp128r2		"secp128r2"
-#define NID_secp128r2		707
-#define OBJ_secp128r2		OBJ_secg_ellipticCurve,29L
-
-#define SN_secp160k1		"secp160k1"
-#define NID_secp160k1		708
-#define OBJ_secp160k1		OBJ_secg_ellipticCurve,9L
-
-#define SN_secp160r1		"secp160r1"
-#define NID_secp160r1		709
-#define OBJ_secp160r1		OBJ_secg_ellipticCurve,8L
-
-#define SN_secp160r2		"secp160r2"
-#define NID_secp160r2		710
-#define OBJ_secp160r2		OBJ_secg_ellipticCurve,30L
-
-#define SN_secp192k1		"secp192k1"
-#define NID_secp192k1		711
-#define OBJ_secp192k1		OBJ_secg_ellipticCurve,31L
-
-#define SN_secp224k1		"secp224k1"
-#define NID_secp224k1		712
-#define OBJ_secp224k1		OBJ_secg_ellipticCurve,32L
-
-#define SN_secp224r1		"secp224r1"
-#define NID_secp224r1		713
-#define OBJ_secp224r1		OBJ_secg_ellipticCurve,33L
-
-#define SN_secp256k1		"secp256k1"
-#define NID_secp256k1		714
-#define OBJ_secp256k1		OBJ_secg_ellipticCurve,10L
-
-#define SN_secp384r1		"secp384r1"
-#define NID_secp384r1		715
-#define OBJ_secp384r1		OBJ_secg_ellipticCurve,34L
-
-#define SN_secp521r1		"secp521r1"
-#define NID_secp521r1		716
-#define OBJ_secp521r1		OBJ_secg_ellipticCurve,35L
-
-#define SN_sect113r1		"sect113r1"
-#define NID_sect113r1		717
-#define OBJ_sect113r1		OBJ_secg_ellipticCurve,4L
-
-#define SN_sect113r2		"sect113r2"
-#define NID_sect113r2		718
-#define OBJ_sect113r2		OBJ_secg_ellipticCurve,5L
-
-#define SN_sect131r1		"sect131r1"
-#define NID_sect131r1		719
-#define OBJ_sect131r1		OBJ_secg_ellipticCurve,22L
-
-#define SN_sect131r2		"sect131r2"
-#define NID_sect131r2		720
-#define OBJ_sect131r2		OBJ_secg_ellipticCurve,23L
-
-#define SN_sect163k1		"sect163k1"
-#define NID_sect163k1		721
-#define OBJ_sect163k1		OBJ_secg_ellipticCurve,1L
-
-#define SN_sect163r1		"sect163r1"
-#define NID_sect163r1		722
-#define OBJ_sect163r1		OBJ_secg_ellipticCurve,2L
-
-#define SN_sect163r2		"sect163r2"
-#define NID_sect163r2		723
-#define OBJ_sect163r2		OBJ_secg_ellipticCurve,15L
-
-#define SN_sect193r1		"sect193r1"
-#define NID_sect193r1		724
-#define OBJ_sect193r1		OBJ_secg_ellipticCurve,24L
-
-#define SN_sect193r2		"sect193r2"
-#define NID_sect193r2		725
-#define OBJ_sect193r2		OBJ_secg_ellipticCurve,25L
-
-#define SN_sect233k1		"sect233k1"
-#define NID_sect233k1		726
-#define OBJ_sect233k1		OBJ_secg_ellipticCurve,26L
-
-#define SN_sect233r1		"sect233r1"
-#define NID_sect233r1		727
-#define OBJ_sect233r1		OBJ_secg_ellipticCurve,27L
-
-#define SN_sect239k1		"sect239k1"
-#define NID_sect239k1		728
-#define OBJ_sect239k1		OBJ_secg_ellipticCurve,3L
-
-#define SN_sect283k1		"sect283k1"
-#define NID_sect283k1		729
-#define OBJ_sect283k1		OBJ_secg_ellipticCurve,16L
-
-#define SN_sect283r1		"sect283r1"
-#define NID_sect283r1		730
-#define OBJ_sect283r1		OBJ_secg_ellipticCurve,17L
-
-#define SN_sect409k1		"sect409k1"
-#define NID_sect409k1		731
-#define OBJ_sect409k1		OBJ_secg_ellipticCurve,36L
-
-#define SN_sect409r1		"sect409r1"
-#define NID_sect409r1		732
-#define OBJ_sect409r1		OBJ_secg_ellipticCurve,37L
-
-#define SN_sect571k1		"sect571k1"
-#define NID_sect571k1		733
-#define OBJ_sect571k1		OBJ_secg_ellipticCurve,38L
-
-#define SN_sect571r1		"sect571r1"
-#define NID_sect571r1		734
-#define OBJ_sect571r1		OBJ_secg_ellipticCurve,39L
-
-#define OBJ_wap_wsg_idm_ecid		OBJ_wap_wsg,4L
-
-#define SN_wap_wsg_idm_ecid_wtls1		"wap-wsg-idm-ecid-wtls1"
-#define NID_wap_wsg_idm_ecid_wtls1		735
-#define OBJ_wap_wsg_idm_ecid_wtls1		OBJ_wap_wsg_idm_ecid,1L
-
-#define SN_wap_wsg_idm_ecid_wtls3		"wap-wsg-idm-ecid-wtls3"
-#define NID_wap_wsg_idm_ecid_wtls3		736
-#define OBJ_wap_wsg_idm_ecid_wtls3		OBJ_wap_wsg_idm_ecid,3L
-
-#define SN_wap_wsg_idm_ecid_wtls4		"wap-wsg-idm-ecid-wtls4"
-#define NID_wap_wsg_idm_ecid_wtls4		737
-#define OBJ_wap_wsg_idm_ecid_wtls4		OBJ_wap_wsg_idm_ecid,4L
-
-#define SN_wap_wsg_idm_ecid_wtls5		"wap-wsg-idm-ecid-wtls5"
-#define NID_wap_wsg_idm_ecid_wtls5		738
-#define OBJ_wap_wsg_idm_ecid_wtls5		OBJ_wap_wsg_idm_ecid,5L
-
-#define SN_wap_wsg_idm_ecid_wtls6		"wap-wsg-idm-ecid-wtls6"
-#define NID_wap_wsg_idm_ecid_wtls6		739
-#define OBJ_wap_wsg_idm_ecid_wtls6		OBJ_wap_wsg_idm_ecid,6L
-
-#define SN_wap_wsg_idm_ecid_wtls7		"wap-wsg-idm-ecid-wtls7"
-#define NID_wap_wsg_idm_ecid_wtls7		740
-#define OBJ_wap_wsg_idm_ecid_wtls7		OBJ_wap_wsg_idm_ecid,7L
-
-#define SN_wap_wsg_idm_ecid_wtls8		"wap-wsg-idm-ecid-wtls8"
-#define NID_wap_wsg_idm_ecid_wtls8		741
-#define OBJ_wap_wsg_idm_ecid_wtls8		OBJ_wap_wsg_idm_ecid,8L
-
-#define SN_wap_wsg_idm_ecid_wtls9		"wap-wsg-idm-ecid-wtls9"
-#define NID_wap_wsg_idm_ecid_wtls9		742
-#define OBJ_wap_wsg_idm_ecid_wtls9		OBJ_wap_wsg_idm_ecid,9L
-
-#define SN_wap_wsg_idm_ecid_wtls10		"wap-wsg-idm-ecid-wtls10"
-#define NID_wap_wsg_idm_ecid_wtls10		743
-#define OBJ_wap_wsg_idm_ecid_wtls10		OBJ_wap_wsg_idm_ecid,10L
-
-#define SN_wap_wsg_idm_ecid_wtls11		"wap-wsg-idm-ecid-wtls11"
-#define NID_wap_wsg_idm_ecid_wtls11		744
-#define OBJ_wap_wsg_idm_ecid_wtls11		OBJ_wap_wsg_idm_ecid,11L
-
-#define SN_wap_wsg_idm_ecid_wtls12		"wap-wsg-idm-ecid-wtls12"
-#define NID_wap_wsg_idm_ecid_wtls12		745
-#define OBJ_wap_wsg_idm_ecid_wtls12		OBJ_wap_wsg_idm_ecid,12L
-
-#define SN_cast5_cbc		"CAST5-CBC"
-#define LN_cast5_cbc		"cast5-cbc"
-#define NID_cast5_cbc		108
-#define OBJ_cast5_cbc		OBJ_ISO_US,113533L,7L,66L,10L
-
-#define SN_cast5_ecb		"CAST5-ECB"
-#define LN_cast5_ecb		"cast5-ecb"
-#define NID_cast5_ecb		109
-
-#define SN_cast5_cfb64		"CAST5-CFB"
-#define LN_cast5_cfb64		"cast5-cfb"
-#define NID_cast5_cfb64		110
-
-#define SN_cast5_ofb64		"CAST5-OFB"
-#define LN_cast5_ofb64		"cast5-ofb"
-#define NID_cast5_ofb64		111
-
-#define LN_pbeWithMD5AndCast5_CBC		"pbeWithMD5AndCast5CBC"
-#define NID_pbeWithMD5AndCast5_CBC		112
-#define OBJ_pbeWithMD5AndCast5_CBC		OBJ_ISO_US,113533L,7L,66L,12L
-
-#define SN_id_PasswordBasedMAC		"id-PasswordBasedMAC"
-#define LN_id_PasswordBasedMAC		"password based MAC"
-#define NID_id_PasswordBasedMAC		782
-#define OBJ_id_PasswordBasedMAC		OBJ_ISO_US,113533L,7L,66L,13L
-
-#define SN_id_DHBasedMac		"id-DHBasedMac"
-#define LN_id_DHBasedMac		"Diffie-Hellman based MAC"
-#define NID_id_DHBasedMac		783
-#define OBJ_id_DHBasedMac		OBJ_ISO_US,113533L,7L,66L,30L
-
-#define SN_rsadsi		"rsadsi"
-#define LN_rsadsi		"RSA Data Security, Inc."
-#define NID_rsadsi		1
-#define OBJ_rsadsi		OBJ_ISO_US,113549L
-
-#define SN_pkcs		"pkcs"
-#define LN_pkcs		"RSA Data Security, Inc. PKCS"
-#define NID_pkcs		2
-#define OBJ_pkcs		OBJ_rsadsi,1L
-
-#define SN_pkcs1		"pkcs1"
-#define NID_pkcs1		186
-#define OBJ_pkcs1		OBJ_pkcs,1L
-
-#define LN_rsaEncryption		"rsaEncryption"
-#define NID_rsaEncryption		6
-#define OBJ_rsaEncryption		OBJ_pkcs1,1L
-
-#define SN_md2WithRSAEncryption		"RSA-MD2"
-#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
-#define NID_md2WithRSAEncryption		7
-#define OBJ_md2WithRSAEncryption		OBJ_pkcs1,2L
-
-#define SN_md4WithRSAEncryption		"RSA-MD4"
-#define LN_md4WithRSAEncryption		"md4WithRSAEncryption"
-#define NID_md4WithRSAEncryption		396
-#define OBJ_md4WithRSAEncryption		OBJ_pkcs1,3L
-
-#define SN_md5WithRSAEncryption		"RSA-MD5"
-#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
-#define NID_md5WithRSAEncryption		8
-#define OBJ_md5WithRSAEncryption		OBJ_pkcs1,4L
-
-#define SN_sha1WithRSAEncryption		"RSA-SHA1"
-#define LN_sha1WithRSAEncryption		"sha1WithRSAEncryption"
-#define NID_sha1WithRSAEncryption		65
-#define OBJ_sha1WithRSAEncryption		OBJ_pkcs1,5L
-
-#define SN_rsaesOaep		"RSAES-OAEP"
-#define LN_rsaesOaep		"rsaesOaep"
-#define NID_rsaesOaep		919
-#define OBJ_rsaesOaep		OBJ_pkcs1,7L
-
-#define SN_mgf1		"MGF1"
-#define LN_mgf1		"mgf1"
-#define NID_mgf1		911
-#define OBJ_mgf1		OBJ_pkcs1,8L
-
-#define SN_pSpecified		"PSPECIFIED"
-#define LN_pSpecified		"pSpecified"
-#define NID_pSpecified		935
-#define OBJ_pSpecified		OBJ_pkcs1,9L
-
-#define SN_rsassaPss		"RSASSA-PSS"
-#define LN_rsassaPss		"rsassaPss"
-#define NID_rsassaPss		912
-#define OBJ_rsassaPss		OBJ_pkcs1,10L
-
-#define SN_sha256WithRSAEncryption		"RSA-SHA256"
-#define LN_sha256WithRSAEncryption		"sha256WithRSAEncryption"
-#define NID_sha256WithRSAEncryption		668
-#define OBJ_sha256WithRSAEncryption		OBJ_pkcs1,11L
-
-#define SN_sha384WithRSAEncryption		"RSA-SHA384"
-#define LN_sha384WithRSAEncryption		"sha384WithRSAEncryption"
-#define NID_sha384WithRSAEncryption		669
-#define OBJ_sha384WithRSAEncryption		OBJ_pkcs1,12L
-
-#define SN_sha512WithRSAEncryption		"RSA-SHA512"
-#define LN_sha512WithRSAEncryption		"sha512WithRSAEncryption"
-#define NID_sha512WithRSAEncryption		670
-#define OBJ_sha512WithRSAEncryption		OBJ_pkcs1,13L
-
-#define SN_sha224WithRSAEncryption		"RSA-SHA224"
-#define LN_sha224WithRSAEncryption		"sha224WithRSAEncryption"
-#define NID_sha224WithRSAEncryption		671
-#define OBJ_sha224WithRSAEncryption		OBJ_pkcs1,14L
-
-#define SN_pkcs3		"pkcs3"
-#define NID_pkcs3		27
-#define OBJ_pkcs3		OBJ_pkcs,3L
-
-#define LN_dhKeyAgreement		"dhKeyAgreement"
-#define NID_dhKeyAgreement		28
-#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
-
-#define SN_pkcs5		"pkcs5"
-#define NID_pkcs5		187
-#define OBJ_pkcs5		OBJ_pkcs,5L
-
-#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
-#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
-#define NID_pbeWithMD2AndDES_CBC		9
-#define OBJ_pbeWithMD2AndDES_CBC		OBJ_pkcs5,1L
-
-#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
-#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
-#define NID_pbeWithMD5AndDES_CBC		10
-#define OBJ_pbeWithMD5AndDES_CBC		OBJ_pkcs5,3L
-
-#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
-#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
-#define NID_pbeWithMD2AndRC2_CBC		168
-#define OBJ_pbeWithMD2AndRC2_CBC		OBJ_pkcs5,4L
-
-#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
-#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
-#define NID_pbeWithMD5AndRC2_CBC		169
-#define OBJ_pbeWithMD5AndRC2_CBC		OBJ_pkcs5,6L
-
-#define SN_pbeWithSHA1AndDES_CBC		"PBE-SHA1-DES"
-#define LN_pbeWithSHA1AndDES_CBC		"pbeWithSHA1AndDES-CBC"
-#define NID_pbeWithSHA1AndDES_CBC		170
-#define OBJ_pbeWithSHA1AndDES_CBC		OBJ_pkcs5,10L
-
-#define SN_pbeWithSHA1AndRC2_CBC		"PBE-SHA1-RC2-64"
-#define LN_pbeWithSHA1AndRC2_CBC		"pbeWithSHA1AndRC2-CBC"
-#define NID_pbeWithSHA1AndRC2_CBC		68
-#define OBJ_pbeWithSHA1AndRC2_CBC		OBJ_pkcs5,11L
-
-#define LN_id_pbkdf2		"PBKDF2"
-#define NID_id_pbkdf2		69
-#define OBJ_id_pbkdf2		OBJ_pkcs5,12L
-
-#define LN_pbes2		"PBES2"
-#define NID_pbes2		161
-#define OBJ_pbes2		OBJ_pkcs5,13L
-
-#define LN_pbmac1		"PBMAC1"
-#define NID_pbmac1		162
-#define OBJ_pbmac1		OBJ_pkcs5,14L
-
-#define SN_pkcs7		"pkcs7"
-#define NID_pkcs7		20
-#define OBJ_pkcs7		OBJ_pkcs,7L
-
-#define LN_pkcs7_data		"pkcs7-data"
-#define NID_pkcs7_data		21
-#define OBJ_pkcs7_data		OBJ_pkcs7,1L
-
-#define LN_pkcs7_signed		"pkcs7-signedData"
-#define NID_pkcs7_signed		22
-#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
-
-#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
-#define NID_pkcs7_enveloped		23
-#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
-
-#define LN_pkcs7_signedAndEnveloped		"pkcs7-signedAndEnvelopedData"
-#define NID_pkcs7_signedAndEnveloped		24
-#define OBJ_pkcs7_signedAndEnveloped		OBJ_pkcs7,4L
-
-#define LN_pkcs7_digest		"pkcs7-digestData"
-#define NID_pkcs7_digest		25
-#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
-
-#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
-#define NID_pkcs7_encrypted		26
-#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
-
-#define SN_pkcs9		"pkcs9"
-#define NID_pkcs9		47
-#define OBJ_pkcs9		OBJ_pkcs,9L
-
-#define LN_pkcs9_emailAddress		"emailAddress"
-#define NID_pkcs9_emailAddress		48
-#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
-
-#define LN_pkcs9_unstructuredName		"unstructuredName"
-#define NID_pkcs9_unstructuredName		49
-#define OBJ_pkcs9_unstructuredName		OBJ_pkcs9,2L
-
-#define LN_pkcs9_contentType		"contentType"
-#define NID_pkcs9_contentType		50
-#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
-
-#define LN_pkcs9_messageDigest		"messageDigest"
-#define NID_pkcs9_messageDigest		51
-#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
-
-#define LN_pkcs9_signingTime		"signingTime"
-#define NID_pkcs9_signingTime		52
-#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
-
-#define LN_pkcs9_countersignature		"countersignature"
-#define NID_pkcs9_countersignature		53
-#define OBJ_pkcs9_countersignature		OBJ_pkcs9,6L
-
-#define LN_pkcs9_challengePassword		"challengePassword"
-#define NID_pkcs9_challengePassword		54
-#define OBJ_pkcs9_challengePassword		OBJ_pkcs9,7L
-
-#define LN_pkcs9_unstructuredAddress		"unstructuredAddress"
-#define NID_pkcs9_unstructuredAddress		55
-#define OBJ_pkcs9_unstructuredAddress		OBJ_pkcs9,8L
-
-#define LN_pkcs9_extCertAttributes		"extendedCertificateAttributes"
-#define NID_pkcs9_extCertAttributes		56
-#define OBJ_pkcs9_extCertAttributes		OBJ_pkcs9,9L
-
-#define SN_ext_req		"extReq"
-#define LN_ext_req		"Extension Request"
-#define NID_ext_req		172
-#define OBJ_ext_req		OBJ_pkcs9,14L
-
-#define SN_SMIMECapabilities		"SMIME-CAPS"
-#define LN_SMIMECapabilities		"S/MIME Capabilities"
-#define NID_SMIMECapabilities		167
-#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
-
-#define SN_SMIME		"SMIME"
-#define LN_SMIME		"S/MIME"
-#define NID_SMIME		188
-#define OBJ_SMIME		OBJ_pkcs9,16L
-
-#define SN_id_smime_mod		"id-smime-mod"
-#define NID_id_smime_mod		189
-#define OBJ_id_smime_mod		OBJ_SMIME,0L
-
-#define SN_id_smime_ct		"id-smime-ct"
-#define NID_id_smime_ct		190
-#define OBJ_id_smime_ct		OBJ_SMIME,1L
-
-#define SN_id_smime_aa		"id-smime-aa"
-#define NID_id_smime_aa		191
-#define OBJ_id_smime_aa		OBJ_SMIME,2L
-
-#define SN_id_smime_alg		"id-smime-alg"
-#define NID_id_smime_alg		192
-#define OBJ_id_smime_alg		OBJ_SMIME,3L
-
-#define SN_id_smime_cd		"id-smime-cd"
-#define NID_id_smime_cd		193
-#define OBJ_id_smime_cd		OBJ_SMIME,4L
-
-#define SN_id_smime_spq		"id-smime-spq"
-#define NID_id_smime_spq		194
-#define OBJ_id_smime_spq		OBJ_SMIME,5L
-
-#define SN_id_smime_cti		"id-smime-cti"
-#define NID_id_smime_cti		195
-#define OBJ_id_smime_cti		OBJ_SMIME,6L
-
-#define SN_id_smime_mod_cms		"id-smime-mod-cms"
-#define NID_id_smime_mod_cms		196
-#define OBJ_id_smime_mod_cms		OBJ_id_smime_mod,1L
-
-#define SN_id_smime_mod_ess		"id-smime-mod-ess"
-#define NID_id_smime_mod_ess		197
-#define OBJ_id_smime_mod_ess		OBJ_id_smime_mod,2L
-
-#define SN_id_smime_mod_oid		"id-smime-mod-oid"
-#define NID_id_smime_mod_oid		198
-#define OBJ_id_smime_mod_oid		OBJ_id_smime_mod,3L
-
-#define SN_id_smime_mod_msg_v3		"id-smime-mod-msg-v3"
-#define NID_id_smime_mod_msg_v3		199
-#define OBJ_id_smime_mod_msg_v3		OBJ_id_smime_mod,4L
-
-#define SN_id_smime_mod_ets_eSignature_88		"id-smime-mod-ets-eSignature-88"
-#define NID_id_smime_mod_ets_eSignature_88		200
-#define OBJ_id_smime_mod_ets_eSignature_88		OBJ_id_smime_mod,5L
-
-#define SN_id_smime_mod_ets_eSignature_97		"id-smime-mod-ets-eSignature-97"
-#define NID_id_smime_mod_ets_eSignature_97		201
-#define OBJ_id_smime_mod_ets_eSignature_97		OBJ_id_smime_mod,6L
-
-#define SN_id_smime_mod_ets_eSigPolicy_88		"id-smime-mod-ets-eSigPolicy-88"
-#define NID_id_smime_mod_ets_eSigPolicy_88		202
-#define OBJ_id_smime_mod_ets_eSigPolicy_88		OBJ_id_smime_mod,7L
-
-#define SN_id_smime_mod_ets_eSigPolicy_97		"id-smime-mod-ets-eSigPolicy-97"
-#define NID_id_smime_mod_ets_eSigPolicy_97		203
-#define OBJ_id_smime_mod_ets_eSigPolicy_97		OBJ_id_smime_mod,8L
-
-#define SN_id_smime_ct_receipt		"id-smime-ct-receipt"
-#define NID_id_smime_ct_receipt		204
-#define OBJ_id_smime_ct_receipt		OBJ_id_smime_ct,1L
-
-#define SN_id_smime_ct_authData		"id-smime-ct-authData"
-#define NID_id_smime_ct_authData		205
-#define OBJ_id_smime_ct_authData		OBJ_id_smime_ct,2L
-
-#define SN_id_smime_ct_publishCert		"id-smime-ct-publishCert"
-#define NID_id_smime_ct_publishCert		206
-#define OBJ_id_smime_ct_publishCert		OBJ_id_smime_ct,3L
-
-#define SN_id_smime_ct_TSTInfo		"id-smime-ct-TSTInfo"
-#define NID_id_smime_ct_TSTInfo		207
-#define OBJ_id_smime_ct_TSTInfo		OBJ_id_smime_ct,4L
-
-#define SN_id_smime_ct_TDTInfo		"id-smime-ct-TDTInfo"
-#define NID_id_smime_ct_TDTInfo		208
-#define OBJ_id_smime_ct_TDTInfo		OBJ_id_smime_ct,5L
-
-#define SN_id_smime_ct_contentInfo		"id-smime-ct-contentInfo"
-#define NID_id_smime_ct_contentInfo		209
-#define OBJ_id_smime_ct_contentInfo		OBJ_id_smime_ct,6L
-
-#define SN_id_smime_ct_DVCSRequestData		"id-smime-ct-DVCSRequestData"
-#define NID_id_smime_ct_DVCSRequestData		210
-#define OBJ_id_smime_ct_DVCSRequestData		OBJ_id_smime_ct,7L
-
-#define SN_id_smime_ct_DVCSResponseData		"id-smime-ct-DVCSResponseData"
-#define NID_id_smime_ct_DVCSResponseData		211
-#define OBJ_id_smime_ct_DVCSResponseData		OBJ_id_smime_ct,8L
-
-#define SN_id_smime_ct_compressedData		"id-smime-ct-compressedData"
-#define NID_id_smime_ct_compressedData		786
-#define OBJ_id_smime_ct_compressedData		OBJ_id_smime_ct,9L
-
-#define SN_id_ct_asciiTextWithCRLF		"id-ct-asciiTextWithCRLF"
-#define NID_id_ct_asciiTextWithCRLF		787
-#define OBJ_id_ct_asciiTextWithCRLF		OBJ_id_smime_ct,27L
-
-#define SN_id_smime_aa_receiptRequest		"id-smime-aa-receiptRequest"
-#define NID_id_smime_aa_receiptRequest		212
-#define OBJ_id_smime_aa_receiptRequest		OBJ_id_smime_aa,1L
-
-#define SN_id_smime_aa_securityLabel		"id-smime-aa-securityLabel"
-#define NID_id_smime_aa_securityLabel		213
-#define OBJ_id_smime_aa_securityLabel		OBJ_id_smime_aa,2L
-
-#define SN_id_smime_aa_mlExpandHistory		"id-smime-aa-mlExpandHistory"
-#define NID_id_smime_aa_mlExpandHistory		214
-#define OBJ_id_smime_aa_mlExpandHistory		OBJ_id_smime_aa,3L
-
-#define SN_id_smime_aa_contentHint		"id-smime-aa-contentHint"
-#define NID_id_smime_aa_contentHint		215
-#define OBJ_id_smime_aa_contentHint		OBJ_id_smime_aa,4L
-
-#define SN_id_smime_aa_msgSigDigest		"id-smime-aa-msgSigDigest"
-#define NID_id_smime_aa_msgSigDigest		216
-#define OBJ_id_smime_aa_msgSigDigest		OBJ_id_smime_aa,5L
-
-#define SN_id_smime_aa_encapContentType		"id-smime-aa-encapContentType"
-#define NID_id_smime_aa_encapContentType		217
-#define OBJ_id_smime_aa_encapContentType		OBJ_id_smime_aa,6L
-
-#define SN_id_smime_aa_contentIdentifier		"id-smime-aa-contentIdentifier"
-#define NID_id_smime_aa_contentIdentifier		218
-#define OBJ_id_smime_aa_contentIdentifier		OBJ_id_smime_aa,7L
-
-#define SN_id_smime_aa_macValue		"id-smime-aa-macValue"
-#define NID_id_smime_aa_macValue		219
-#define OBJ_id_smime_aa_macValue		OBJ_id_smime_aa,8L
-
-#define SN_id_smime_aa_equivalentLabels		"id-smime-aa-equivalentLabels"
-#define NID_id_smime_aa_equivalentLabels		220
-#define OBJ_id_smime_aa_equivalentLabels		OBJ_id_smime_aa,9L
-
-#define SN_id_smime_aa_contentReference		"id-smime-aa-contentReference"
-#define NID_id_smime_aa_contentReference		221
-#define OBJ_id_smime_aa_contentReference		OBJ_id_smime_aa,10L
-
-#define SN_id_smime_aa_encrypKeyPref		"id-smime-aa-encrypKeyPref"
-#define NID_id_smime_aa_encrypKeyPref		222
-#define OBJ_id_smime_aa_encrypKeyPref		OBJ_id_smime_aa,11L
-
-#define SN_id_smime_aa_signingCertificate		"id-smime-aa-signingCertificate"
-#define NID_id_smime_aa_signingCertificate		223
-#define OBJ_id_smime_aa_signingCertificate		OBJ_id_smime_aa,12L
-
-#define SN_id_smime_aa_smimeEncryptCerts		"id-smime-aa-smimeEncryptCerts"
-#define NID_id_smime_aa_smimeEncryptCerts		224
-#define OBJ_id_smime_aa_smimeEncryptCerts		OBJ_id_smime_aa,13L
-
-#define SN_id_smime_aa_timeStampToken		"id-smime-aa-timeStampToken"
-#define NID_id_smime_aa_timeStampToken		225
-#define OBJ_id_smime_aa_timeStampToken		OBJ_id_smime_aa,14L
-
-#define SN_id_smime_aa_ets_sigPolicyId		"id-smime-aa-ets-sigPolicyId"
-#define NID_id_smime_aa_ets_sigPolicyId		226
-#define OBJ_id_smime_aa_ets_sigPolicyId		OBJ_id_smime_aa,15L
-
-#define SN_id_smime_aa_ets_commitmentType		"id-smime-aa-ets-commitmentType"
-#define NID_id_smime_aa_ets_commitmentType		227
-#define OBJ_id_smime_aa_ets_commitmentType		OBJ_id_smime_aa,16L
-
-#define SN_id_smime_aa_ets_signerLocation		"id-smime-aa-ets-signerLocation"
-#define NID_id_smime_aa_ets_signerLocation		228
-#define OBJ_id_smime_aa_ets_signerLocation		OBJ_id_smime_aa,17L
-
-#define SN_id_smime_aa_ets_signerAttr		"id-smime-aa-ets-signerAttr"
-#define NID_id_smime_aa_ets_signerAttr		229
-#define OBJ_id_smime_aa_ets_signerAttr		OBJ_id_smime_aa,18L
-
-#define SN_id_smime_aa_ets_otherSigCert		"id-smime-aa-ets-otherSigCert"
-#define NID_id_smime_aa_ets_otherSigCert		230
-#define OBJ_id_smime_aa_ets_otherSigCert		OBJ_id_smime_aa,19L
-
-#define SN_id_smime_aa_ets_contentTimestamp		"id-smime-aa-ets-contentTimestamp"
-#define NID_id_smime_aa_ets_contentTimestamp		231
-#define OBJ_id_smime_aa_ets_contentTimestamp		OBJ_id_smime_aa,20L
-
-#define SN_id_smime_aa_ets_CertificateRefs		"id-smime-aa-ets-CertificateRefs"
-#define NID_id_smime_aa_ets_CertificateRefs		232
-#define OBJ_id_smime_aa_ets_CertificateRefs		OBJ_id_smime_aa,21L
-
-#define SN_id_smime_aa_ets_RevocationRefs		"id-smime-aa-ets-RevocationRefs"
-#define NID_id_smime_aa_ets_RevocationRefs		233
-#define OBJ_id_smime_aa_ets_RevocationRefs		OBJ_id_smime_aa,22L
-
-#define SN_id_smime_aa_ets_certValues		"id-smime-aa-ets-certValues"
-#define NID_id_smime_aa_ets_certValues		234
-#define OBJ_id_smime_aa_ets_certValues		OBJ_id_smime_aa,23L
-
-#define SN_id_smime_aa_ets_revocationValues		"id-smime-aa-ets-revocationValues"
-#define NID_id_smime_aa_ets_revocationValues		235
-#define OBJ_id_smime_aa_ets_revocationValues		OBJ_id_smime_aa,24L
-
-#define SN_id_smime_aa_ets_escTimeStamp		"id-smime-aa-ets-escTimeStamp"
-#define NID_id_smime_aa_ets_escTimeStamp		236
-#define OBJ_id_smime_aa_ets_escTimeStamp		OBJ_id_smime_aa,25L
-
-#define SN_id_smime_aa_ets_certCRLTimestamp		"id-smime-aa-ets-certCRLTimestamp"
-#define NID_id_smime_aa_ets_certCRLTimestamp		237
-#define OBJ_id_smime_aa_ets_certCRLTimestamp		OBJ_id_smime_aa,26L
-
-#define SN_id_smime_aa_ets_archiveTimeStamp		"id-smime-aa-ets-archiveTimeStamp"
-#define NID_id_smime_aa_ets_archiveTimeStamp		238
-#define OBJ_id_smime_aa_ets_archiveTimeStamp		OBJ_id_smime_aa,27L
-
-#define SN_id_smime_aa_signatureType		"id-smime-aa-signatureType"
-#define NID_id_smime_aa_signatureType		239
-#define OBJ_id_smime_aa_signatureType		OBJ_id_smime_aa,28L
-
-#define SN_id_smime_aa_dvcs_dvc		"id-smime-aa-dvcs-dvc"
-#define NID_id_smime_aa_dvcs_dvc		240
-#define OBJ_id_smime_aa_dvcs_dvc		OBJ_id_smime_aa,29L
-
-#define SN_id_smime_alg_ESDHwith3DES		"id-smime-alg-ESDHwith3DES"
-#define NID_id_smime_alg_ESDHwith3DES		241
-#define OBJ_id_smime_alg_ESDHwith3DES		OBJ_id_smime_alg,1L
-
-#define SN_id_smime_alg_ESDHwithRC2		"id-smime-alg-ESDHwithRC2"
-#define NID_id_smime_alg_ESDHwithRC2		242
-#define OBJ_id_smime_alg_ESDHwithRC2		OBJ_id_smime_alg,2L
-
-#define SN_id_smime_alg_3DESwrap		"id-smime-alg-3DESwrap"
-#define NID_id_smime_alg_3DESwrap		243
-#define OBJ_id_smime_alg_3DESwrap		OBJ_id_smime_alg,3L
-
-#define SN_id_smime_alg_RC2wrap		"id-smime-alg-RC2wrap"
-#define NID_id_smime_alg_RC2wrap		244
-#define OBJ_id_smime_alg_RC2wrap		OBJ_id_smime_alg,4L
-
-#define SN_id_smime_alg_ESDH		"id-smime-alg-ESDH"
-#define NID_id_smime_alg_ESDH		245
-#define OBJ_id_smime_alg_ESDH		OBJ_id_smime_alg,5L
-
-#define SN_id_smime_alg_CMS3DESwrap		"id-smime-alg-CMS3DESwrap"
-#define NID_id_smime_alg_CMS3DESwrap		246
-#define OBJ_id_smime_alg_CMS3DESwrap		OBJ_id_smime_alg,6L
-
-#define SN_id_smime_alg_CMSRC2wrap		"id-smime-alg-CMSRC2wrap"
-#define NID_id_smime_alg_CMSRC2wrap		247
-#define OBJ_id_smime_alg_CMSRC2wrap		OBJ_id_smime_alg,7L
-
-#define SN_id_alg_PWRI_KEK		"id-alg-PWRI-KEK"
-#define NID_id_alg_PWRI_KEK		893
-#define OBJ_id_alg_PWRI_KEK		OBJ_id_smime_alg,9L
-
-#define SN_id_smime_cd_ldap		"id-smime-cd-ldap"
-#define NID_id_smime_cd_ldap		248
-#define OBJ_id_smime_cd_ldap		OBJ_id_smime_cd,1L
-
-#define SN_id_smime_spq_ets_sqt_uri		"id-smime-spq-ets-sqt-uri"
-#define NID_id_smime_spq_ets_sqt_uri		249
-#define OBJ_id_smime_spq_ets_sqt_uri		OBJ_id_smime_spq,1L
-
-#define SN_id_smime_spq_ets_sqt_unotice		"id-smime-spq-ets-sqt-unotice"
-#define NID_id_smime_spq_ets_sqt_unotice		250
-#define OBJ_id_smime_spq_ets_sqt_unotice		OBJ_id_smime_spq,2L
-
-#define SN_id_smime_cti_ets_proofOfOrigin		"id-smime-cti-ets-proofOfOrigin"
-#define NID_id_smime_cti_ets_proofOfOrigin		251
-#define OBJ_id_smime_cti_ets_proofOfOrigin		OBJ_id_smime_cti,1L
-
-#define SN_id_smime_cti_ets_proofOfReceipt		"id-smime-cti-ets-proofOfReceipt"
-#define NID_id_smime_cti_ets_proofOfReceipt		252
-#define OBJ_id_smime_cti_ets_proofOfReceipt		OBJ_id_smime_cti,2L
-
-#define SN_id_smime_cti_ets_proofOfDelivery		"id-smime-cti-ets-proofOfDelivery"
-#define NID_id_smime_cti_ets_proofOfDelivery		253
-#define OBJ_id_smime_cti_ets_proofOfDelivery		OBJ_id_smime_cti,3L
-
-#define SN_id_smime_cti_ets_proofOfSender		"id-smime-cti-ets-proofOfSender"
-#define NID_id_smime_cti_ets_proofOfSender		254
-#define OBJ_id_smime_cti_ets_proofOfSender		OBJ_id_smime_cti,4L
-
-#define SN_id_smime_cti_ets_proofOfApproval		"id-smime-cti-ets-proofOfApproval"
-#define NID_id_smime_cti_ets_proofOfApproval		255
-#define OBJ_id_smime_cti_ets_proofOfApproval		OBJ_id_smime_cti,5L
-
-#define SN_id_smime_cti_ets_proofOfCreation		"id-smime-cti-ets-proofOfCreation"
-#define NID_id_smime_cti_ets_proofOfCreation		256
-#define OBJ_id_smime_cti_ets_proofOfCreation		OBJ_id_smime_cti,6L
-
-#define LN_friendlyName		"friendlyName"
-#define NID_friendlyName		156
-#define OBJ_friendlyName		OBJ_pkcs9,20L
-
-#define LN_localKeyID		"localKeyID"
-#define NID_localKeyID		157
-#define OBJ_localKeyID		OBJ_pkcs9,21L
-
-#define SN_ms_csp_name		"CSPName"
-#define LN_ms_csp_name		"Microsoft CSP Name"
-#define NID_ms_csp_name		417
-#define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
-
-#define SN_LocalKeySet		"LocalKeySet"
-#define LN_LocalKeySet		"Microsoft Local Key set"
-#define NID_LocalKeySet		856
-#define OBJ_LocalKeySet		1L,3L,6L,1L,4L,1L,311L,17L,2L
-
-#define OBJ_certTypes		OBJ_pkcs9,22L
-
-#define LN_x509Certificate		"x509Certificate"
-#define NID_x509Certificate		158
-#define OBJ_x509Certificate		OBJ_certTypes,1L
-
-#define LN_sdsiCertificate		"sdsiCertificate"
-#define NID_sdsiCertificate		159
-#define OBJ_sdsiCertificate		OBJ_certTypes,2L
-
-#define OBJ_crlTypes		OBJ_pkcs9,23L
-
-#define LN_x509Crl		"x509Crl"
-#define NID_x509Crl		160
-#define OBJ_x509Crl		OBJ_crlTypes,1L
-
-#define OBJ_pkcs12		OBJ_pkcs,12L
-
-#define OBJ_pkcs12_pbeids		OBJ_pkcs12,1L
-
-#define SN_pbe_WithSHA1And128BitRC4		"PBE-SHA1-RC4-128"
-#define LN_pbe_WithSHA1And128BitRC4		"pbeWithSHA1And128BitRC4"
-#define NID_pbe_WithSHA1And128BitRC4		144
-#define OBJ_pbe_WithSHA1And128BitRC4		OBJ_pkcs12_pbeids,1L
-
-#define SN_pbe_WithSHA1And40BitRC4		"PBE-SHA1-RC4-40"
-#define LN_pbe_WithSHA1And40BitRC4		"pbeWithSHA1And40BitRC4"
-#define NID_pbe_WithSHA1And40BitRC4		145
-#define OBJ_pbe_WithSHA1And40BitRC4		OBJ_pkcs12_pbeids,2L
-
-#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC		"PBE-SHA1-3DES"
-#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC		"pbeWithSHA1And3-KeyTripleDES-CBC"
-#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC		146
-#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,3L
-
-#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC		"PBE-SHA1-2DES"
-#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC		"pbeWithSHA1And2-KeyTripleDES-CBC"
-#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC		147
-#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,4L
-
-#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
-#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
-#define NID_pbe_WithSHA1And128BitRC2_CBC		148
-#define OBJ_pbe_WithSHA1And128BitRC2_CBC		OBJ_pkcs12_pbeids,5L
-
-#define SN_pbe_WithSHA1And40BitRC2_CBC		"PBE-SHA1-RC2-40"
-#define LN_pbe_WithSHA1And40BitRC2_CBC		"pbeWithSHA1And40BitRC2-CBC"
-#define NID_pbe_WithSHA1And40BitRC2_CBC		149
-#define OBJ_pbe_WithSHA1And40BitRC2_CBC		OBJ_pkcs12_pbeids,6L
-
-#define OBJ_pkcs12_Version1		OBJ_pkcs12,10L
-
-#define OBJ_pkcs12_BagIds		OBJ_pkcs12_Version1,1L
-
-#define LN_keyBag		"keyBag"
-#define NID_keyBag		150
-#define OBJ_keyBag		OBJ_pkcs12_BagIds,1L
-
-#define LN_pkcs8ShroudedKeyBag		"pkcs8ShroudedKeyBag"
-#define NID_pkcs8ShroudedKeyBag		151
-#define OBJ_pkcs8ShroudedKeyBag		OBJ_pkcs12_BagIds,2L
-
-#define LN_certBag		"certBag"
-#define NID_certBag		152
-#define OBJ_certBag		OBJ_pkcs12_BagIds,3L
-
-#define LN_crlBag		"crlBag"
-#define NID_crlBag		153
-#define OBJ_crlBag		OBJ_pkcs12_BagIds,4L
-
-#define LN_secretBag		"secretBag"
-#define NID_secretBag		154
-#define OBJ_secretBag		OBJ_pkcs12_BagIds,5L
-
-#define LN_safeContentsBag		"safeContentsBag"
-#define NID_safeContentsBag		155
-#define OBJ_safeContentsBag		OBJ_pkcs12_BagIds,6L
-
-#define SN_md2		"MD2"
-#define LN_md2		"md2"
-#define NID_md2		3
-#define OBJ_md2		OBJ_rsadsi,2L,2L
-
-#define SN_md4		"MD4"
-#define LN_md4		"md4"
-#define NID_md4		257
-#define OBJ_md4		OBJ_rsadsi,2L,4L
-
-#define SN_md5		"MD5"
-#define LN_md5		"md5"
-#define NID_md5		4
-#define OBJ_md5		OBJ_rsadsi,2L,5L
-
-#define SN_md5_sha1		"MD5-SHA1"
-#define LN_md5_sha1		"md5-sha1"
-#define NID_md5_sha1		114
-
-#define LN_hmacWithMD5		"hmacWithMD5"
-#define NID_hmacWithMD5		797
-#define OBJ_hmacWithMD5		OBJ_rsadsi,2L,6L
-
-#define LN_hmacWithSHA1		"hmacWithSHA1"
-#define NID_hmacWithSHA1		163
-#define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
-
-#define LN_hmacWithSHA224		"hmacWithSHA224"
-#define NID_hmacWithSHA224		798
-#define OBJ_hmacWithSHA224		OBJ_rsadsi,2L,8L
-
-#define LN_hmacWithSHA256		"hmacWithSHA256"
-#define NID_hmacWithSHA256		799
-#define OBJ_hmacWithSHA256		OBJ_rsadsi,2L,9L
-
-#define LN_hmacWithSHA384		"hmacWithSHA384"
-#define NID_hmacWithSHA384		800
-#define OBJ_hmacWithSHA384		OBJ_rsadsi,2L,10L
-
-#define LN_hmacWithSHA512		"hmacWithSHA512"
-#define NID_hmacWithSHA512		801
-#define OBJ_hmacWithSHA512		OBJ_rsadsi,2L,11L
-
-#define SN_rc2_cbc		"RC2-CBC"
-#define LN_rc2_cbc		"rc2-cbc"
-#define NID_rc2_cbc		37
-#define OBJ_rc2_cbc		OBJ_rsadsi,3L,2L
-
-#define SN_rc2_ecb		"RC2-ECB"
-#define LN_rc2_ecb		"rc2-ecb"
-#define NID_rc2_ecb		38
-
-#define SN_rc2_cfb64		"RC2-CFB"
-#define LN_rc2_cfb64		"rc2-cfb"
-#define NID_rc2_cfb64		39
-
-#define SN_rc2_ofb64		"RC2-OFB"
-#define LN_rc2_ofb64		"rc2-ofb"
-#define NID_rc2_ofb64		40
-
-#define SN_rc2_40_cbc		"RC2-40-CBC"
-#define LN_rc2_40_cbc		"rc2-40-cbc"
-#define NID_rc2_40_cbc		98
-
-#define SN_rc2_64_cbc		"RC2-64-CBC"
-#define LN_rc2_64_cbc		"rc2-64-cbc"
-#define NID_rc2_64_cbc		166
-
-#define SN_rc4		"RC4"
-#define LN_rc4		"rc4"
-#define NID_rc4		5
-#define OBJ_rc4		OBJ_rsadsi,3L,4L
-
-#define SN_rc4_40		"RC4-40"
-#define LN_rc4_40		"rc4-40"
-#define NID_rc4_40		97
-
-#define SN_des_ede3_cbc		"DES-EDE3-CBC"
-#define LN_des_ede3_cbc		"des-ede3-cbc"
-#define NID_des_ede3_cbc		44
-#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
-
-#define SN_rc5_cbc		"RC5-CBC"
-#define LN_rc5_cbc		"rc5-cbc"
-#define NID_rc5_cbc		120
-#define OBJ_rc5_cbc		OBJ_rsadsi,3L,8L
-
-#define SN_rc5_ecb		"RC5-ECB"
-#define LN_rc5_ecb		"rc5-ecb"
-#define NID_rc5_ecb		121
-
-#define SN_rc5_cfb64		"RC5-CFB"
-#define LN_rc5_cfb64		"rc5-cfb"
-#define NID_rc5_cfb64		122
-
-#define SN_rc5_ofb64		"RC5-OFB"
-#define LN_rc5_ofb64		"rc5-ofb"
-#define NID_rc5_ofb64		123
-
-#define SN_ms_ext_req		"msExtReq"
-#define LN_ms_ext_req		"Microsoft Extension Request"
-#define NID_ms_ext_req		171
-#define OBJ_ms_ext_req		1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
-
-#define SN_ms_code_ind		"msCodeInd"
-#define LN_ms_code_ind		"Microsoft Individual Code Signing"
-#define NID_ms_code_ind		134
-#define OBJ_ms_code_ind		1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
-
-#define SN_ms_code_com		"msCodeCom"
-#define LN_ms_code_com		"Microsoft Commercial Code Signing"
-#define NID_ms_code_com		135
-#define OBJ_ms_code_com		1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
-
-#define SN_ms_ctl_sign		"msCTLSign"
-#define LN_ms_ctl_sign		"Microsoft Trust List Signing"
-#define NID_ms_ctl_sign		136
-#define OBJ_ms_ctl_sign		1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
-
-#define SN_ms_sgc		"msSGC"
-#define LN_ms_sgc		"Microsoft Server Gated Crypto"
-#define NID_ms_sgc		137
-#define OBJ_ms_sgc		1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
-
-#define SN_ms_efs		"msEFS"
-#define LN_ms_efs		"Microsoft Encrypted File System"
-#define NID_ms_efs		138
-#define OBJ_ms_efs		1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
-
-#define SN_ms_smartcard_login		"msSmartcardLogin"
-#define LN_ms_smartcard_login		"Microsoft Smartcardlogin"
-#define NID_ms_smartcard_login		648
-#define OBJ_ms_smartcard_login		1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
-
-#define SN_ms_upn		"msUPN"
-#define LN_ms_upn		"Microsoft Universal Principal Name"
-#define NID_ms_upn		649
-#define OBJ_ms_upn		1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
-
-#define SN_idea_cbc		"IDEA-CBC"
-#define LN_idea_cbc		"idea-cbc"
-#define NID_idea_cbc		34
-#define OBJ_idea_cbc		1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
-
-#define SN_idea_ecb		"IDEA-ECB"
-#define LN_idea_ecb		"idea-ecb"
-#define NID_idea_ecb		36
-
-#define SN_idea_cfb64		"IDEA-CFB"
-#define LN_idea_cfb64		"idea-cfb"
-#define NID_idea_cfb64		35
-
-#define SN_idea_ofb64		"IDEA-OFB"
-#define LN_idea_ofb64		"idea-ofb"
-#define NID_idea_ofb64		46
-
-#define SN_bf_cbc		"BF-CBC"
-#define LN_bf_cbc		"bf-cbc"
-#define NID_bf_cbc		91
-#define OBJ_bf_cbc		1L,3L,6L,1L,4L,1L,3029L,1L,2L
-
-#define SN_bf_ecb		"BF-ECB"
-#define LN_bf_ecb		"bf-ecb"
-#define NID_bf_ecb		92
-
-#define SN_bf_cfb64		"BF-CFB"
-#define LN_bf_cfb64		"bf-cfb"
-#define NID_bf_cfb64		93
-
-#define SN_bf_ofb64		"BF-OFB"
-#define LN_bf_ofb64		"bf-ofb"
-#define NID_bf_ofb64		94
-
-#define SN_id_pkix		"PKIX"
-#define NID_id_pkix		127
-#define OBJ_id_pkix		1L,3L,6L,1L,5L,5L,7L
-
-#define SN_id_pkix_mod		"id-pkix-mod"
-#define NID_id_pkix_mod		258
-#define OBJ_id_pkix_mod		OBJ_id_pkix,0L
-
-#define SN_id_pe		"id-pe"
-#define NID_id_pe		175
-#define OBJ_id_pe		OBJ_id_pkix,1L
-
-#define SN_id_qt		"id-qt"
-#define NID_id_qt		259
-#define OBJ_id_qt		OBJ_id_pkix,2L
-
-#define SN_id_kp		"id-kp"
-#define NID_id_kp		128
-#define OBJ_id_kp		OBJ_id_pkix,3L
-
-#define SN_id_it		"id-it"
-#define NID_id_it		260
-#define OBJ_id_it		OBJ_id_pkix,4L
-
-#define SN_id_pkip		"id-pkip"
-#define NID_id_pkip		261
-#define OBJ_id_pkip		OBJ_id_pkix,5L
-
-#define SN_id_alg		"id-alg"
-#define NID_id_alg		262
-#define OBJ_id_alg		OBJ_id_pkix,6L
-
-#define SN_id_cmc		"id-cmc"
-#define NID_id_cmc		263
-#define OBJ_id_cmc		OBJ_id_pkix,7L
-
-#define SN_id_on		"id-on"
-#define NID_id_on		264
-#define OBJ_id_on		OBJ_id_pkix,8L
-
-#define SN_id_pda		"id-pda"
-#define NID_id_pda		265
-#define OBJ_id_pda		OBJ_id_pkix,9L
-
-#define SN_id_aca		"id-aca"
-#define NID_id_aca		266
-#define OBJ_id_aca		OBJ_id_pkix,10L
-
-#define SN_id_qcs		"id-qcs"
-#define NID_id_qcs		267
-#define OBJ_id_qcs		OBJ_id_pkix,11L
-
-#define SN_id_cct		"id-cct"
-#define NID_id_cct		268
-#define OBJ_id_cct		OBJ_id_pkix,12L
-
-#define SN_id_ppl		"id-ppl"
-#define NID_id_ppl		662
-#define OBJ_id_ppl		OBJ_id_pkix,21L
-
-#define SN_id_ad		"id-ad"
-#define NID_id_ad		176
-#define OBJ_id_ad		OBJ_id_pkix,48L
-
-#define SN_id_pkix1_explicit_88		"id-pkix1-explicit-88"
-#define NID_id_pkix1_explicit_88		269
-#define OBJ_id_pkix1_explicit_88		OBJ_id_pkix_mod,1L
-
-#define SN_id_pkix1_implicit_88		"id-pkix1-implicit-88"
-#define NID_id_pkix1_implicit_88		270
-#define OBJ_id_pkix1_implicit_88		OBJ_id_pkix_mod,2L
-
-#define SN_id_pkix1_explicit_93		"id-pkix1-explicit-93"
-#define NID_id_pkix1_explicit_93		271
-#define OBJ_id_pkix1_explicit_93		OBJ_id_pkix_mod,3L
-
-#define SN_id_pkix1_implicit_93		"id-pkix1-implicit-93"
-#define NID_id_pkix1_implicit_93		272
-#define OBJ_id_pkix1_implicit_93		OBJ_id_pkix_mod,4L
-
-#define SN_id_mod_crmf		"id-mod-crmf"
-#define NID_id_mod_crmf		273
-#define OBJ_id_mod_crmf		OBJ_id_pkix_mod,5L
-
-#define SN_id_mod_cmc		"id-mod-cmc"
-#define NID_id_mod_cmc		274
-#define OBJ_id_mod_cmc		OBJ_id_pkix_mod,6L
-
-#define SN_id_mod_kea_profile_88		"id-mod-kea-profile-88"
-#define NID_id_mod_kea_profile_88		275
-#define OBJ_id_mod_kea_profile_88		OBJ_id_pkix_mod,7L
-
-#define SN_id_mod_kea_profile_93		"id-mod-kea-profile-93"
-#define NID_id_mod_kea_profile_93		276
-#define OBJ_id_mod_kea_profile_93		OBJ_id_pkix_mod,8L
-
-#define SN_id_mod_cmp		"id-mod-cmp"
-#define NID_id_mod_cmp		277
-#define OBJ_id_mod_cmp		OBJ_id_pkix_mod,9L
-
-#define SN_id_mod_qualified_cert_88		"id-mod-qualified-cert-88"
-#define NID_id_mod_qualified_cert_88		278
-#define OBJ_id_mod_qualified_cert_88		OBJ_id_pkix_mod,10L
-
-#define SN_id_mod_qualified_cert_93		"id-mod-qualified-cert-93"
-#define NID_id_mod_qualified_cert_93		279
-#define OBJ_id_mod_qualified_cert_93		OBJ_id_pkix_mod,11L
-
-#define SN_id_mod_attribute_cert		"id-mod-attribute-cert"
-#define NID_id_mod_attribute_cert		280
-#define OBJ_id_mod_attribute_cert		OBJ_id_pkix_mod,12L
-
-#define SN_id_mod_timestamp_protocol		"id-mod-timestamp-protocol"
-#define NID_id_mod_timestamp_protocol		281
-#define OBJ_id_mod_timestamp_protocol		OBJ_id_pkix_mod,13L
-
-#define SN_id_mod_ocsp		"id-mod-ocsp"
-#define NID_id_mod_ocsp		282
-#define OBJ_id_mod_ocsp		OBJ_id_pkix_mod,14L
-
-#define SN_id_mod_dvcs		"id-mod-dvcs"
-#define NID_id_mod_dvcs		283
-#define OBJ_id_mod_dvcs		OBJ_id_pkix_mod,15L
-
-#define SN_id_mod_cmp2000		"id-mod-cmp2000"
-#define NID_id_mod_cmp2000		284
-#define OBJ_id_mod_cmp2000		OBJ_id_pkix_mod,16L
-
-#define SN_info_access		"authorityInfoAccess"
-#define LN_info_access		"Authority Information Access"
-#define NID_info_access		177
-#define OBJ_info_access		OBJ_id_pe,1L
-
-#define SN_biometricInfo		"biometricInfo"
-#define LN_biometricInfo		"Biometric Info"
-#define NID_biometricInfo		285
-#define OBJ_biometricInfo		OBJ_id_pe,2L
-
-#define SN_qcStatements		"qcStatements"
-#define NID_qcStatements		286
-#define OBJ_qcStatements		OBJ_id_pe,3L
-
-#define SN_ac_auditEntity		"ac-auditEntity"
-#define NID_ac_auditEntity		287
-#define OBJ_ac_auditEntity		OBJ_id_pe,4L
-
-#define SN_ac_targeting		"ac-targeting"
-#define NID_ac_targeting		288
-#define OBJ_ac_targeting		OBJ_id_pe,5L
-
-#define SN_aaControls		"aaControls"
-#define NID_aaControls		289
-#define OBJ_aaControls		OBJ_id_pe,6L
-
-#define SN_sbgp_ipAddrBlock		"sbgp-ipAddrBlock"
-#define NID_sbgp_ipAddrBlock		290
-#define OBJ_sbgp_ipAddrBlock		OBJ_id_pe,7L
-
-#define SN_sbgp_autonomousSysNum		"sbgp-autonomousSysNum"
-#define NID_sbgp_autonomousSysNum		291
-#define OBJ_sbgp_autonomousSysNum		OBJ_id_pe,8L
-
-#define SN_sbgp_routerIdentifier		"sbgp-routerIdentifier"
-#define NID_sbgp_routerIdentifier		292
-#define OBJ_sbgp_routerIdentifier		OBJ_id_pe,9L
-
-#define SN_ac_proxying		"ac-proxying"
-#define NID_ac_proxying		397
-#define OBJ_ac_proxying		OBJ_id_pe,10L
-
-#define SN_sinfo_access		"subjectInfoAccess"
-#define LN_sinfo_access		"Subject Information Access"
-#define NID_sinfo_access		398
-#define OBJ_sinfo_access		OBJ_id_pe,11L
-
-#define SN_proxyCertInfo		"proxyCertInfo"
-#define LN_proxyCertInfo		"Proxy Certificate Information"
-#define NID_proxyCertInfo		663
-#define OBJ_proxyCertInfo		OBJ_id_pe,14L
-
-#define SN_id_qt_cps		"id-qt-cps"
-#define LN_id_qt_cps		"Policy Qualifier CPS"
-#define NID_id_qt_cps		164
-#define OBJ_id_qt_cps		OBJ_id_qt,1L
-
-#define SN_id_qt_unotice		"id-qt-unotice"
-#define LN_id_qt_unotice		"Policy Qualifier User Notice"
-#define NID_id_qt_unotice		165
-#define OBJ_id_qt_unotice		OBJ_id_qt,2L
-
-#define SN_textNotice		"textNotice"
-#define NID_textNotice		293
-#define OBJ_textNotice		OBJ_id_qt,3L
-
-#define SN_server_auth		"serverAuth"
-#define LN_server_auth		"TLS Web Server Authentication"
-#define NID_server_auth		129
-#define OBJ_server_auth		OBJ_id_kp,1L
-
-#define SN_client_auth		"clientAuth"
-#define LN_client_auth		"TLS Web Client Authentication"
-#define NID_client_auth		130
-#define OBJ_client_auth		OBJ_id_kp,2L
-
-#define SN_code_sign		"codeSigning"
-#define LN_code_sign		"Code Signing"
-#define NID_code_sign		131
-#define OBJ_code_sign		OBJ_id_kp,3L
-
-#define SN_email_protect		"emailProtection"
-#define LN_email_protect		"E-mail Protection"
-#define NID_email_protect		132
-#define OBJ_email_protect		OBJ_id_kp,4L
-
-#define SN_ipsecEndSystem		"ipsecEndSystem"
-#define LN_ipsecEndSystem		"IPSec End System"
-#define NID_ipsecEndSystem		294
-#define OBJ_ipsecEndSystem		OBJ_id_kp,5L
-
-#define SN_ipsecTunnel		"ipsecTunnel"
-#define LN_ipsecTunnel		"IPSec Tunnel"
-#define NID_ipsecTunnel		295
-#define OBJ_ipsecTunnel		OBJ_id_kp,6L
-
-#define SN_ipsecUser		"ipsecUser"
-#define LN_ipsecUser		"IPSec User"
-#define NID_ipsecUser		296
-#define OBJ_ipsecUser		OBJ_id_kp,7L
-
-#define SN_time_stamp		"timeStamping"
-#define LN_time_stamp		"Time Stamping"
-#define NID_time_stamp		133
-#define OBJ_time_stamp		OBJ_id_kp,8L
-
-#define SN_OCSP_sign		"OCSPSigning"
-#define LN_OCSP_sign		"OCSP Signing"
-#define NID_OCSP_sign		180
-#define OBJ_OCSP_sign		OBJ_id_kp,9L
-
-#define SN_dvcs		"DVCS"
-#define LN_dvcs		"dvcs"
-#define NID_dvcs		297
-#define OBJ_dvcs		OBJ_id_kp,10L
-
-#define SN_id_it_caProtEncCert		"id-it-caProtEncCert"
-#define NID_id_it_caProtEncCert		298
-#define OBJ_id_it_caProtEncCert		OBJ_id_it,1L
-
-#define SN_id_it_signKeyPairTypes		"id-it-signKeyPairTypes"
-#define NID_id_it_signKeyPairTypes		299
-#define OBJ_id_it_signKeyPairTypes		OBJ_id_it,2L
-
-#define SN_id_it_encKeyPairTypes		"id-it-encKeyPairTypes"
-#define NID_id_it_encKeyPairTypes		300
-#define OBJ_id_it_encKeyPairTypes		OBJ_id_it,3L
-
-#define SN_id_it_preferredSymmAlg		"id-it-preferredSymmAlg"
-#define NID_id_it_preferredSymmAlg		301
-#define OBJ_id_it_preferredSymmAlg		OBJ_id_it,4L
-
-#define SN_id_it_caKeyUpdateInfo		"id-it-caKeyUpdateInfo"
-#define NID_id_it_caKeyUpdateInfo		302
-#define OBJ_id_it_caKeyUpdateInfo		OBJ_id_it,5L
-
-#define SN_id_it_currentCRL		"id-it-currentCRL"
-#define NID_id_it_currentCRL		303
-#define OBJ_id_it_currentCRL		OBJ_id_it,6L
-
-#define SN_id_it_unsupportedOIDs		"id-it-unsupportedOIDs"
-#define NID_id_it_unsupportedOIDs		304
-#define OBJ_id_it_unsupportedOIDs		OBJ_id_it,7L
-
-#define SN_id_it_subscriptionRequest		"id-it-subscriptionRequest"
-#define NID_id_it_subscriptionRequest		305
-#define OBJ_id_it_subscriptionRequest		OBJ_id_it,8L
-
-#define SN_id_it_subscriptionResponse		"id-it-subscriptionResponse"
-#define NID_id_it_subscriptionResponse		306
-#define OBJ_id_it_subscriptionResponse		OBJ_id_it,9L
-
-#define SN_id_it_keyPairParamReq		"id-it-keyPairParamReq"
-#define NID_id_it_keyPairParamReq		307
-#define OBJ_id_it_keyPairParamReq		OBJ_id_it,10L
-
-#define SN_id_it_keyPairParamRep		"id-it-keyPairParamRep"
-#define NID_id_it_keyPairParamRep		308
-#define OBJ_id_it_keyPairParamRep		OBJ_id_it,11L
-
-#define SN_id_it_revPassphrase		"id-it-revPassphrase"
-#define NID_id_it_revPassphrase		309
-#define OBJ_id_it_revPassphrase		OBJ_id_it,12L
-
-#define SN_id_it_implicitConfirm		"id-it-implicitConfirm"
-#define NID_id_it_implicitConfirm		310
-#define OBJ_id_it_implicitConfirm		OBJ_id_it,13L
-
-#define SN_id_it_confirmWaitTime		"id-it-confirmWaitTime"
-#define NID_id_it_confirmWaitTime		311
-#define OBJ_id_it_confirmWaitTime		OBJ_id_it,14L
-
-#define SN_id_it_origPKIMessage		"id-it-origPKIMessage"
-#define NID_id_it_origPKIMessage		312
-#define OBJ_id_it_origPKIMessage		OBJ_id_it,15L
-
-#define SN_id_it_suppLangTags		"id-it-suppLangTags"
-#define NID_id_it_suppLangTags		784
-#define OBJ_id_it_suppLangTags		OBJ_id_it,16L
-
-#define SN_id_regCtrl		"id-regCtrl"
-#define NID_id_regCtrl		313
-#define OBJ_id_regCtrl		OBJ_id_pkip,1L
-
-#define SN_id_regInfo		"id-regInfo"
-#define NID_id_regInfo		314
-#define OBJ_id_regInfo		OBJ_id_pkip,2L
-
-#define SN_id_regCtrl_regToken		"id-regCtrl-regToken"
-#define NID_id_regCtrl_regToken		315
-#define OBJ_id_regCtrl_regToken		OBJ_id_regCtrl,1L
-
-#define SN_id_regCtrl_authenticator		"id-regCtrl-authenticator"
-#define NID_id_regCtrl_authenticator		316
-#define OBJ_id_regCtrl_authenticator		OBJ_id_regCtrl,2L
-
-#define SN_id_regCtrl_pkiPublicationInfo		"id-regCtrl-pkiPublicationInfo"
-#define NID_id_regCtrl_pkiPublicationInfo		317
-#define OBJ_id_regCtrl_pkiPublicationInfo		OBJ_id_regCtrl,3L
-
-#define SN_id_regCtrl_pkiArchiveOptions		"id-regCtrl-pkiArchiveOptions"
-#define NID_id_regCtrl_pkiArchiveOptions		318
-#define OBJ_id_regCtrl_pkiArchiveOptions		OBJ_id_regCtrl,4L
-
-#define SN_id_regCtrl_oldCertID		"id-regCtrl-oldCertID"
-#define NID_id_regCtrl_oldCertID		319
-#define OBJ_id_regCtrl_oldCertID		OBJ_id_regCtrl,5L
-
-#define SN_id_regCtrl_protocolEncrKey		"id-regCtrl-protocolEncrKey"
-#define NID_id_regCtrl_protocolEncrKey		320
-#define OBJ_id_regCtrl_protocolEncrKey		OBJ_id_regCtrl,6L
-
-#define SN_id_regInfo_utf8Pairs		"id-regInfo-utf8Pairs"
-#define NID_id_regInfo_utf8Pairs		321
-#define OBJ_id_regInfo_utf8Pairs		OBJ_id_regInfo,1L
-
-#define SN_id_regInfo_certReq		"id-regInfo-certReq"
-#define NID_id_regInfo_certReq		322
-#define OBJ_id_regInfo_certReq		OBJ_id_regInfo,2L
-
-#define SN_id_alg_des40		"id-alg-des40"
-#define NID_id_alg_des40		323
-#define OBJ_id_alg_des40		OBJ_id_alg,1L
-
-#define SN_id_alg_noSignature		"id-alg-noSignature"
-#define NID_id_alg_noSignature		324
-#define OBJ_id_alg_noSignature		OBJ_id_alg,2L
-
-#define SN_id_alg_dh_sig_hmac_sha1		"id-alg-dh-sig-hmac-sha1"
-#define NID_id_alg_dh_sig_hmac_sha1		325
-#define OBJ_id_alg_dh_sig_hmac_sha1		OBJ_id_alg,3L
-
-#define SN_id_alg_dh_pop		"id-alg-dh-pop"
-#define NID_id_alg_dh_pop		326
-#define OBJ_id_alg_dh_pop		OBJ_id_alg,4L
-
-#define SN_id_cmc_statusInfo		"id-cmc-statusInfo"
-#define NID_id_cmc_statusInfo		327
-#define OBJ_id_cmc_statusInfo		OBJ_id_cmc,1L
-
-#define SN_id_cmc_identification		"id-cmc-identification"
-#define NID_id_cmc_identification		328
-#define OBJ_id_cmc_identification		OBJ_id_cmc,2L
-
-#define SN_id_cmc_identityProof		"id-cmc-identityProof"
-#define NID_id_cmc_identityProof		329
-#define OBJ_id_cmc_identityProof		OBJ_id_cmc,3L
-
-#define SN_id_cmc_dataReturn		"id-cmc-dataReturn"
-#define NID_id_cmc_dataReturn		330
-#define OBJ_id_cmc_dataReturn		OBJ_id_cmc,4L
-
-#define SN_id_cmc_transactionId		"id-cmc-transactionId"
-#define NID_id_cmc_transactionId		331
-#define OBJ_id_cmc_transactionId		OBJ_id_cmc,5L
-
-#define SN_id_cmc_senderNonce		"id-cmc-senderNonce"
-#define NID_id_cmc_senderNonce		332
-#define OBJ_id_cmc_senderNonce		OBJ_id_cmc,6L
-
-#define SN_id_cmc_recipientNonce		"id-cmc-recipientNonce"
-#define NID_id_cmc_recipientNonce		333
-#define OBJ_id_cmc_recipientNonce		OBJ_id_cmc,7L
-
-#define SN_id_cmc_addExtensions		"id-cmc-addExtensions"
-#define NID_id_cmc_addExtensions		334
-#define OBJ_id_cmc_addExtensions		OBJ_id_cmc,8L
-
-#define SN_id_cmc_encryptedPOP		"id-cmc-encryptedPOP"
-#define NID_id_cmc_encryptedPOP		335
-#define OBJ_id_cmc_encryptedPOP		OBJ_id_cmc,9L
-
-#define SN_id_cmc_decryptedPOP		"id-cmc-decryptedPOP"
-#define NID_id_cmc_decryptedPOP		336
-#define OBJ_id_cmc_decryptedPOP		OBJ_id_cmc,10L
-
-#define SN_id_cmc_lraPOPWitness		"id-cmc-lraPOPWitness"
-#define NID_id_cmc_lraPOPWitness		337
-#define OBJ_id_cmc_lraPOPWitness		OBJ_id_cmc,11L
-
-#define SN_id_cmc_getCert		"id-cmc-getCert"
-#define NID_id_cmc_getCert		338
-#define OBJ_id_cmc_getCert		OBJ_id_cmc,15L
-
-#define SN_id_cmc_getCRL		"id-cmc-getCRL"
-#define NID_id_cmc_getCRL		339
-#define OBJ_id_cmc_getCRL		OBJ_id_cmc,16L
-
-#define SN_id_cmc_revokeRequest		"id-cmc-revokeRequest"
-#define NID_id_cmc_revokeRequest		340
-#define OBJ_id_cmc_revokeRequest		OBJ_id_cmc,17L
-
-#define SN_id_cmc_regInfo		"id-cmc-regInfo"
-#define NID_id_cmc_regInfo		341
-#define OBJ_id_cmc_regInfo		OBJ_id_cmc,18L
-
-#define SN_id_cmc_responseInfo		"id-cmc-responseInfo"
-#define NID_id_cmc_responseInfo		342
-#define OBJ_id_cmc_responseInfo		OBJ_id_cmc,19L
-
-#define SN_id_cmc_queryPending		"id-cmc-queryPending"
-#define NID_id_cmc_queryPending		343
-#define OBJ_id_cmc_queryPending		OBJ_id_cmc,21L
-
-#define SN_id_cmc_popLinkRandom		"id-cmc-popLinkRandom"
-#define NID_id_cmc_popLinkRandom		344
-#define OBJ_id_cmc_popLinkRandom		OBJ_id_cmc,22L
-
-#define SN_id_cmc_popLinkWitness		"id-cmc-popLinkWitness"
-#define NID_id_cmc_popLinkWitness		345
-#define OBJ_id_cmc_popLinkWitness		OBJ_id_cmc,23L
-
-#define SN_id_cmc_confirmCertAcceptance		"id-cmc-confirmCertAcceptance"
-#define NID_id_cmc_confirmCertAcceptance		346
-#define OBJ_id_cmc_confirmCertAcceptance		OBJ_id_cmc,24L
-
-#define SN_id_on_personalData		"id-on-personalData"
-#define NID_id_on_personalData		347
-#define OBJ_id_on_personalData		OBJ_id_on,1L
-
-#define SN_id_on_permanentIdentifier		"id-on-permanentIdentifier"
-#define LN_id_on_permanentIdentifier		"Permanent Identifier"
-#define NID_id_on_permanentIdentifier		858
-#define OBJ_id_on_permanentIdentifier		OBJ_id_on,3L
-
-#define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
-#define NID_id_pda_dateOfBirth		348
-#define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
-
-#define SN_id_pda_placeOfBirth		"id-pda-placeOfBirth"
-#define NID_id_pda_placeOfBirth		349
-#define OBJ_id_pda_placeOfBirth		OBJ_id_pda,2L
-
-#define SN_id_pda_gender		"id-pda-gender"
-#define NID_id_pda_gender		351
-#define OBJ_id_pda_gender		OBJ_id_pda,3L
-
-#define SN_id_pda_countryOfCitizenship		"id-pda-countryOfCitizenship"
-#define NID_id_pda_countryOfCitizenship		352
-#define OBJ_id_pda_countryOfCitizenship		OBJ_id_pda,4L
-
-#define SN_id_pda_countryOfResidence		"id-pda-countryOfResidence"
-#define NID_id_pda_countryOfResidence		353
-#define OBJ_id_pda_countryOfResidence		OBJ_id_pda,5L
-
-#define SN_id_aca_authenticationInfo		"id-aca-authenticationInfo"
-#define NID_id_aca_authenticationInfo		354
-#define OBJ_id_aca_authenticationInfo		OBJ_id_aca,1L
-
-#define SN_id_aca_accessIdentity		"id-aca-accessIdentity"
-#define NID_id_aca_accessIdentity		355
-#define OBJ_id_aca_accessIdentity		OBJ_id_aca,2L
-
-#define SN_id_aca_chargingIdentity		"id-aca-chargingIdentity"
-#define NID_id_aca_chargingIdentity		356
-#define OBJ_id_aca_chargingIdentity		OBJ_id_aca,3L
-
-#define SN_id_aca_group		"id-aca-group"
-#define NID_id_aca_group		357
-#define OBJ_id_aca_group		OBJ_id_aca,4L
-
-#define SN_id_aca_role		"id-aca-role"
-#define NID_id_aca_role		358
-#define OBJ_id_aca_role		OBJ_id_aca,5L
-
-#define SN_id_aca_encAttrs		"id-aca-encAttrs"
-#define NID_id_aca_encAttrs		399
-#define OBJ_id_aca_encAttrs		OBJ_id_aca,6L
-
-#define SN_id_qcs_pkixQCSyntax_v1		"id-qcs-pkixQCSyntax-v1"
-#define NID_id_qcs_pkixQCSyntax_v1		359
-#define OBJ_id_qcs_pkixQCSyntax_v1		OBJ_id_qcs,1L
-
-#define SN_id_cct_crs		"id-cct-crs"
-#define NID_id_cct_crs		360
-#define OBJ_id_cct_crs		OBJ_id_cct,1L
-
-#define SN_id_cct_PKIData		"id-cct-PKIData"
-#define NID_id_cct_PKIData		361
-#define OBJ_id_cct_PKIData		OBJ_id_cct,2L
-
-#define SN_id_cct_PKIResponse		"id-cct-PKIResponse"
-#define NID_id_cct_PKIResponse		362
-#define OBJ_id_cct_PKIResponse		OBJ_id_cct,3L
-
-#define SN_id_ppl_anyLanguage		"id-ppl-anyLanguage"
-#define LN_id_ppl_anyLanguage		"Any language"
-#define NID_id_ppl_anyLanguage		664
-#define OBJ_id_ppl_anyLanguage		OBJ_id_ppl,0L
-
-#define SN_id_ppl_inheritAll		"id-ppl-inheritAll"
-#define LN_id_ppl_inheritAll		"Inherit all"
-#define NID_id_ppl_inheritAll		665
-#define OBJ_id_ppl_inheritAll		OBJ_id_ppl,1L
-
-#define SN_Independent		"id-ppl-independent"
-#define LN_Independent		"Independent"
-#define NID_Independent		667
-#define OBJ_Independent		OBJ_id_ppl,2L
-
-#define SN_ad_OCSP		"OCSP"
-#define LN_ad_OCSP		"OCSP"
-#define NID_ad_OCSP		178
-#define OBJ_ad_OCSP		OBJ_id_ad,1L
-
-#define SN_ad_ca_issuers		"caIssuers"
-#define LN_ad_ca_issuers		"CA Issuers"
-#define NID_ad_ca_issuers		179
-#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
-
-#define SN_ad_timeStamping		"ad_timestamping"
-#define LN_ad_timeStamping		"AD Time Stamping"
-#define NID_ad_timeStamping		363
-#define OBJ_ad_timeStamping		OBJ_id_ad,3L
-
-#define SN_ad_dvcs		"AD_DVCS"
-#define LN_ad_dvcs		"ad dvcs"
-#define NID_ad_dvcs		364
-#define OBJ_ad_dvcs		OBJ_id_ad,4L
-
-#define SN_caRepository		"caRepository"
-#define LN_caRepository		"CA Repository"
-#define NID_caRepository		785
-#define OBJ_caRepository		OBJ_id_ad,5L
-
-#define OBJ_id_pkix_OCSP		OBJ_ad_OCSP
-
-#define SN_id_pkix_OCSP_basic		"basicOCSPResponse"
-#define LN_id_pkix_OCSP_basic		"Basic OCSP Response"
-#define NID_id_pkix_OCSP_basic		365
-#define OBJ_id_pkix_OCSP_basic		OBJ_id_pkix_OCSP,1L
-
-#define SN_id_pkix_OCSP_Nonce		"Nonce"
-#define LN_id_pkix_OCSP_Nonce		"OCSP Nonce"
-#define NID_id_pkix_OCSP_Nonce		366
-#define OBJ_id_pkix_OCSP_Nonce		OBJ_id_pkix_OCSP,2L
-
-#define SN_id_pkix_OCSP_CrlID		"CrlID"
-#define LN_id_pkix_OCSP_CrlID		"OCSP CRL ID"
-#define NID_id_pkix_OCSP_CrlID		367
-#define OBJ_id_pkix_OCSP_CrlID		OBJ_id_pkix_OCSP,3L
-
-#define SN_id_pkix_OCSP_acceptableResponses		"acceptableResponses"
-#define LN_id_pkix_OCSP_acceptableResponses		"Acceptable OCSP Responses"
-#define NID_id_pkix_OCSP_acceptableResponses		368
-#define OBJ_id_pkix_OCSP_acceptableResponses		OBJ_id_pkix_OCSP,4L
-
-#define SN_id_pkix_OCSP_noCheck		"noCheck"
-#define LN_id_pkix_OCSP_noCheck		"OCSP No Check"
-#define NID_id_pkix_OCSP_noCheck		369
-#define OBJ_id_pkix_OCSP_noCheck		OBJ_id_pkix_OCSP,5L
-
-#define SN_id_pkix_OCSP_archiveCutoff		"archiveCutoff"
-#define LN_id_pkix_OCSP_archiveCutoff		"OCSP Archive Cutoff"
-#define NID_id_pkix_OCSP_archiveCutoff		370
-#define OBJ_id_pkix_OCSP_archiveCutoff		OBJ_id_pkix_OCSP,6L
-
-#define SN_id_pkix_OCSP_serviceLocator		"serviceLocator"
-#define LN_id_pkix_OCSP_serviceLocator		"OCSP Service Locator"
-#define NID_id_pkix_OCSP_serviceLocator		371
-#define OBJ_id_pkix_OCSP_serviceLocator		OBJ_id_pkix_OCSP,7L
-
-#define SN_id_pkix_OCSP_extendedStatus		"extendedStatus"
-#define LN_id_pkix_OCSP_extendedStatus		"Extended OCSP Status"
-#define NID_id_pkix_OCSP_extendedStatus		372
-#define OBJ_id_pkix_OCSP_extendedStatus		OBJ_id_pkix_OCSP,8L
-
-#define SN_id_pkix_OCSP_valid		"valid"
-#define NID_id_pkix_OCSP_valid		373
-#define OBJ_id_pkix_OCSP_valid		OBJ_id_pkix_OCSP,9L
-
-#define SN_id_pkix_OCSP_path		"path"
-#define NID_id_pkix_OCSP_path		374
-#define OBJ_id_pkix_OCSP_path		OBJ_id_pkix_OCSP,10L
-
-#define SN_id_pkix_OCSP_trustRoot		"trustRoot"
-#define LN_id_pkix_OCSP_trustRoot		"Trust Root"
-#define NID_id_pkix_OCSP_trustRoot		375
-#define OBJ_id_pkix_OCSP_trustRoot		OBJ_id_pkix_OCSP,11L
-
-#define SN_algorithm		"algorithm"
-#define LN_algorithm		"algorithm"
-#define NID_algorithm		376
-#define OBJ_algorithm		1L,3L,14L,3L,2L
-
-#define SN_md5WithRSA		"RSA-NP-MD5"
-#define LN_md5WithRSA		"md5WithRSA"
-#define NID_md5WithRSA		104
-#define OBJ_md5WithRSA		OBJ_algorithm,3L
-
-#define SN_des_ecb		"DES-ECB"
-#define LN_des_ecb		"des-ecb"
-#define NID_des_ecb		29
-#define OBJ_des_ecb		OBJ_algorithm,6L
-
-#define SN_des_cbc		"DES-CBC"
-#define LN_des_cbc		"des-cbc"
-#define NID_des_cbc		31
-#define OBJ_des_cbc		OBJ_algorithm,7L
-
-#define SN_des_ofb64		"DES-OFB"
-#define LN_des_ofb64		"des-ofb"
-#define NID_des_ofb64		45
-#define OBJ_des_ofb64		OBJ_algorithm,8L
-
-#define SN_des_cfb64		"DES-CFB"
-#define LN_des_cfb64		"des-cfb"
-#define NID_des_cfb64		30
-#define OBJ_des_cfb64		OBJ_algorithm,9L
-
-#define SN_rsaSignature		"rsaSignature"
-#define NID_rsaSignature		377
-#define OBJ_rsaSignature		OBJ_algorithm,11L
-
-#define SN_dsa_2		"DSA-old"
-#define LN_dsa_2		"dsaEncryption-old"
-#define NID_dsa_2		67
-#define OBJ_dsa_2		OBJ_algorithm,12L
-
-#define SN_dsaWithSHA		"DSA-SHA"
-#define LN_dsaWithSHA		"dsaWithSHA"
-#define NID_dsaWithSHA		66
-#define OBJ_dsaWithSHA		OBJ_algorithm,13L
-
-#define SN_shaWithRSAEncryption		"RSA-SHA"
-#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
-#define NID_shaWithRSAEncryption		42
-#define OBJ_shaWithRSAEncryption		OBJ_algorithm,15L
-
-#define SN_des_ede_ecb		"DES-EDE"
-#define LN_des_ede_ecb		"des-ede"
-#define NID_des_ede_ecb		32
-#define OBJ_des_ede_ecb		OBJ_algorithm,17L
-
-#define SN_des_ede3_ecb		"DES-EDE3"
-#define LN_des_ede3_ecb		"des-ede3"
-#define NID_des_ede3_ecb		33
-
-#define SN_des_ede_cbc		"DES-EDE-CBC"
-#define LN_des_ede_cbc		"des-ede-cbc"
-#define NID_des_ede_cbc		43
-
-#define SN_des_ede_cfb64		"DES-EDE-CFB"
-#define LN_des_ede_cfb64		"des-ede-cfb"
-#define NID_des_ede_cfb64		60
-
-#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
-#define LN_des_ede3_cfb64		"des-ede3-cfb"
-#define NID_des_ede3_cfb64		61
-
-#define SN_des_ede_ofb64		"DES-EDE-OFB"
-#define LN_des_ede_ofb64		"des-ede-ofb"
-#define NID_des_ede_ofb64		62
-
-#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
-#define LN_des_ede3_ofb64		"des-ede3-ofb"
-#define NID_des_ede3_ofb64		63
-
-#define SN_desx_cbc		"DESX-CBC"
-#define LN_desx_cbc		"desx-cbc"
-#define NID_desx_cbc		80
-
-#define SN_sha		"SHA"
-#define LN_sha		"sha"
-#define NID_sha		41
-#define OBJ_sha		OBJ_algorithm,18L
-
-#define SN_sha1		"SHA1"
-#define LN_sha1		"sha1"
-#define NID_sha1		64
-#define OBJ_sha1		OBJ_algorithm,26L
-
-#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
-#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
-#define NID_dsaWithSHA1_2		70
-#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
-
-#define SN_sha1WithRSA		"RSA-SHA1-2"
-#define LN_sha1WithRSA		"sha1WithRSA"
-#define NID_sha1WithRSA		115
-#define OBJ_sha1WithRSA		OBJ_algorithm,29L
-
-#define SN_ripemd160		"RIPEMD160"
-#define LN_ripemd160		"ripemd160"
-#define NID_ripemd160		117
-#define OBJ_ripemd160		1L,3L,36L,3L,2L,1L
-
-#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
-#define LN_ripemd160WithRSA		"ripemd160WithRSA"
-#define NID_ripemd160WithRSA		119
-#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
-
-#define SN_sxnet		"SXNetID"
-#define LN_sxnet		"Strong Extranet ID"
-#define NID_sxnet		143
-#define OBJ_sxnet		1L,3L,101L,1L,4L,1L
-
-#define SN_X500		"X500"
-#define LN_X500		"directory services (X.500)"
-#define NID_X500		11
-#define OBJ_X500		2L,5L
-
-#define SN_X509		"X509"
-#define NID_X509		12
-#define OBJ_X509		OBJ_X500,4L
-
-#define SN_commonName		"CN"
-#define LN_commonName		"commonName"
-#define NID_commonName		13
-#define OBJ_commonName		OBJ_X509,3L
-
-#define SN_surname		"SN"
-#define LN_surname		"surname"
-#define NID_surname		100
-#define OBJ_surname		OBJ_X509,4L
-
-#define LN_serialNumber		"serialNumber"
-#define NID_serialNumber		105
-#define OBJ_serialNumber		OBJ_X509,5L
-
-#define SN_countryName		"C"
-#define LN_countryName		"countryName"
-#define NID_countryName		14
-#define OBJ_countryName		OBJ_X509,6L
-
-#define SN_localityName		"L"
-#define LN_localityName		"localityName"
-#define NID_localityName		15
-#define OBJ_localityName		OBJ_X509,7L
-
-#define SN_stateOrProvinceName		"ST"
-#define LN_stateOrProvinceName		"stateOrProvinceName"
-#define NID_stateOrProvinceName		16
-#define OBJ_stateOrProvinceName		OBJ_X509,8L
-
-#define SN_streetAddress		"street"
-#define LN_streetAddress		"streetAddress"
-#define NID_streetAddress		660
-#define OBJ_streetAddress		OBJ_X509,9L
-
-#define SN_organizationName		"O"
-#define LN_organizationName		"organizationName"
-#define NID_organizationName		17
-#define OBJ_organizationName		OBJ_X509,10L
-
-#define SN_organizationalUnitName		"OU"
-#define LN_organizationalUnitName		"organizationalUnitName"
-#define NID_organizationalUnitName		18
-#define OBJ_organizationalUnitName		OBJ_X509,11L
-
-#define SN_title		"title"
-#define LN_title		"title"
-#define NID_title		106
-#define OBJ_title		OBJ_X509,12L
-
-#define LN_description		"description"
-#define NID_description		107
-#define OBJ_description		OBJ_X509,13L
-
-#define LN_searchGuide		"searchGuide"
-#define NID_searchGuide		859
-#define OBJ_searchGuide		OBJ_X509,14L
-
-#define LN_businessCategory		"businessCategory"
-#define NID_businessCategory		860
-#define OBJ_businessCategory		OBJ_X509,15L
-
-#define LN_postalAddress		"postalAddress"
-#define NID_postalAddress		861
-#define OBJ_postalAddress		OBJ_X509,16L
-
-#define LN_postalCode		"postalCode"
-#define NID_postalCode		661
-#define OBJ_postalCode		OBJ_X509,17L
-
-#define LN_postOfficeBox		"postOfficeBox"
-#define NID_postOfficeBox		862
-#define OBJ_postOfficeBox		OBJ_X509,18L
-
-#define LN_physicalDeliveryOfficeName		"physicalDeliveryOfficeName"
-#define NID_physicalDeliveryOfficeName		863
-#define OBJ_physicalDeliveryOfficeName		OBJ_X509,19L
-
-#define LN_telephoneNumber		"telephoneNumber"
-#define NID_telephoneNumber		864
-#define OBJ_telephoneNumber		OBJ_X509,20L
-
-#define LN_telexNumber		"telexNumber"
-#define NID_telexNumber		865
-#define OBJ_telexNumber		OBJ_X509,21L
-
-#define LN_teletexTerminalIdentifier		"teletexTerminalIdentifier"
-#define NID_teletexTerminalIdentifier		866
-#define OBJ_teletexTerminalIdentifier		OBJ_X509,22L
-
-#define LN_facsimileTelephoneNumber		"facsimileTelephoneNumber"
-#define NID_facsimileTelephoneNumber		867
-#define OBJ_facsimileTelephoneNumber		OBJ_X509,23L
-
-#define LN_x121Address		"x121Address"
-#define NID_x121Address		868
-#define OBJ_x121Address		OBJ_X509,24L
-
-#define LN_internationaliSDNNumber		"internationaliSDNNumber"
-#define NID_internationaliSDNNumber		869
-#define OBJ_internationaliSDNNumber		OBJ_X509,25L
-
-#define LN_registeredAddress		"registeredAddress"
-#define NID_registeredAddress		870
-#define OBJ_registeredAddress		OBJ_X509,26L
-
-#define LN_destinationIndicator		"destinationIndicator"
-#define NID_destinationIndicator		871
-#define OBJ_destinationIndicator		OBJ_X509,27L
-
-#define LN_preferredDeliveryMethod		"preferredDeliveryMethod"
-#define NID_preferredDeliveryMethod		872
-#define OBJ_preferredDeliveryMethod		OBJ_X509,28L
-
-#define LN_presentationAddress		"presentationAddress"
-#define NID_presentationAddress		873
-#define OBJ_presentationAddress		OBJ_X509,29L
-
-#define LN_supportedApplicationContext		"supportedApplicationContext"
-#define NID_supportedApplicationContext		874
-#define OBJ_supportedApplicationContext		OBJ_X509,30L
-
-#define SN_member		"member"
-#define NID_member		875
-#define OBJ_member		OBJ_X509,31L
-
-#define SN_owner		"owner"
-#define NID_owner		876
-#define OBJ_owner		OBJ_X509,32L
-
-#define LN_roleOccupant		"roleOccupant"
-#define NID_roleOccupant		877
-#define OBJ_roleOccupant		OBJ_X509,33L
-
-#define SN_seeAlso		"seeAlso"
-#define NID_seeAlso		878
-#define OBJ_seeAlso		OBJ_X509,34L
-
-#define LN_userPassword		"userPassword"
-#define NID_userPassword		879
-#define OBJ_userPassword		OBJ_X509,35L
-
-#define LN_userCertificate		"userCertificate"
-#define NID_userCertificate		880
-#define OBJ_userCertificate		OBJ_X509,36L
-
-#define LN_cACertificate		"cACertificate"
-#define NID_cACertificate		881
-#define OBJ_cACertificate		OBJ_X509,37L
-
-#define LN_authorityRevocationList		"authorityRevocationList"
-#define NID_authorityRevocationList		882
-#define OBJ_authorityRevocationList		OBJ_X509,38L
-
-#define LN_certificateRevocationList		"certificateRevocationList"
-#define NID_certificateRevocationList		883
-#define OBJ_certificateRevocationList		OBJ_X509,39L
-
-#define LN_crossCertificatePair		"crossCertificatePair"
-#define NID_crossCertificatePair		884
-#define OBJ_crossCertificatePair		OBJ_X509,40L
-
-#define SN_name		"name"
-#define LN_name		"name"
-#define NID_name		173
-#define OBJ_name		OBJ_X509,41L
-
-#define SN_givenName		"GN"
-#define LN_givenName		"givenName"
-#define NID_givenName		99
-#define OBJ_givenName		OBJ_X509,42L
-
-#define SN_initials		"initials"
-#define LN_initials		"initials"
-#define NID_initials		101
-#define OBJ_initials		OBJ_X509,43L
-
-#define LN_generationQualifier		"generationQualifier"
-#define NID_generationQualifier		509
-#define OBJ_generationQualifier		OBJ_X509,44L
-
-#define LN_x500UniqueIdentifier		"x500UniqueIdentifier"
-#define NID_x500UniqueIdentifier		503
-#define OBJ_x500UniqueIdentifier		OBJ_X509,45L
-
-#define SN_dnQualifier		"dnQualifier"
-#define LN_dnQualifier		"dnQualifier"
-#define NID_dnQualifier		174
-#define OBJ_dnQualifier		OBJ_X509,46L
-
-#define LN_enhancedSearchGuide		"enhancedSearchGuide"
-#define NID_enhancedSearchGuide		885
-#define OBJ_enhancedSearchGuide		OBJ_X509,47L
-
-#define LN_protocolInformation		"protocolInformation"
-#define NID_protocolInformation		886
-#define OBJ_protocolInformation		OBJ_X509,48L
-
-#define LN_distinguishedName		"distinguishedName"
-#define NID_distinguishedName		887
-#define OBJ_distinguishedName		OBJ_X509,49L
-
-#define LN_uniqueMember		"uniqueMember"
-#define NID_uniqueMember		888
-#define OBJ_uniqueMember		OBJ_X509,50L
-
-#define LN_houseIdentifier		"houseIdentifier"
-#define NID_houseIdentifier		889
-#define OBJ_houseIdentifier		OBJ_X509,51L
-
-#define LN_supportedAlgorithms		"supportedAlgorithms"
-#define NID_supportedAlgorithms		890
-#define OBJ_supportedAlgorithms		OBJ_X509,52L
-
-#define LN_deltaRevocationList		"deltaRevocationList"
-#define NID_deltaRevocationList		891
-#define OBJ_deltaRevocationList		OBJ_X509,53L
-
-#define SN_dmdName		"dmdName"
-#define NID_dmdName		892
-#define OBJ_dmdName		OBJ_X509,54L
-
-#define LN_pseudonym		"pseudonym"
-#define NID_pseudonym		510
-#define OBJ_pseudonym		OBJ_X509,65L
-
-#define SN_role		"role"
-#define LN_role		"role"
-#define NID_role		400
-#define OBJ_role		OBJ_X509,72L
-
-#define SN_X500algorithms		"X500algorithms"
-#define LN_X500algorithms		"directory services - algorithms"
-#define NID_X500algorithms		378
-#define OBJ_X500algorithms		OBJ_X500,8L
-
-#define SN_rsa		"RSA"
-#define LN_rsa		"rsa"
-#define NID_rsa		19
-#define OBJ_rsa		OBJ_X500algorithms,1L,1L
-
-#define SN_mdc2WithRSA		"RSA-MDC2"
-#define LN_mdc2WithRSA		"mdc2WithRSA"
-#define NID_mdc2WithRSA		96
-#define OBJ_mdc2WithRSA		OBJ_X500algorithms,3L,100L
-
-#define SN_mdc2		"MDC2"
-#define LN_mdc2		"mdc2"
-#define NID_mdc2		95
-#define OBJ_mdc2		OBJ_X500algorithms,3L,101L
-
-#define SN_id_ce		"id-ce"
-#define NID_id_ce		81
-#define OBJ_id_ce		OBJ_X500,29L
-
-#define SN_subject_directory_attributes		"subjectDirectoryAttributes"
-#define LN_subject_directory_attributes		"X509v3 Subject Directory Attributes"
-#define NID_subject_directory_attributes		769
-#define OBJ_subject_directory_attributes		OBJ_id_ce,9L
-
-#define SN_subject_key_identifier		"subjectKeyIdentifier"
-#define LN_subject_key_identifier		"X509v3 Subject Key Identifier"
-#define NID_subject_key_identifier		82
-#define OBJ_subject_key_identifier		OBJ_id_ce,14L
-
-#define SN_key_usage		"keyUsage"
-#define LN_key_usage		"X509v3 Key Usage"
-#define NID_key_usage		83
-#define OBJ_key_usage		OBJ_id_ce,15L
-
-#define SN_private_key_usage_period		"privateKeyUsagePeriod"
-#define LN_private_key_usage_period		"X509v3 Private Key Usage Period"
-#define NID_private_key_usage_period		84
-#define OBJ_private_key_usage_period		OBJ_id_ce,16L
-
-#define SN_subject_alt_name		"subjectAltName"
-#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
-#define NID_subject_alt_name		85
-#define OBJ_subject_alt_name		OBJ_id_ce,17L
-
-#define SN_issuer_alt_name		"issuerAltName"
-#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
-#define NID_issuer_alt_name		86
-#define OBJ_issuer_alt_name		OBJ_id_ce,18L
-
-#define SN_basic_constraints		"basicConstraints"
-#define LN_basic_constraints		"X509v3 Basic Constraints"
-#define NID_basic_constraints		87
-#define OBJ_basic_constraints		OBJ_id_ce,19L
-
-#define SN_crl_number		"crlNumber"
-#define LN_crl_number		"X509v3 CRL Number"
-#define NID_crl_number		88
-#define OBJ_crl_number		OBJ_id_ce,20L
-
-#define SN_crl_reason		"CRLReason"
-#define LN_crl_reason		"X509v3 CRL Reason Code"
-#define NID_crl_reason		141
-#define OBJ_crl_reason		OBJ_id_ce,21L
-
-#define SN_invalidity_date		"invalidityDate"
-#define LN_invalidity_date		"Invalidity Date"
-#define NID_invalidity_date		142
-#define OBJ_invalidity_date		OBJ_id_ce,24L
-
-#define SN_delta_crl		"deltaCRL"
-#define LN_delta_crl		"X509v3 Delta CRL Indicator"
-#define NID_delta_crl		140
-#define OBJ_delta_crl		OBJ_id_ce,27L
-
-#define SN_issuing_distribution_point		"issuingDistributionPoint"
-#define LN_issuing_distribution_point		"X509v3 Issuing Distribution Point"
-#define NID_issuing_distribution_point		770
-#define OBJ_issuing_distribution_point		OBJ_id_ce,28L
-
-#define SN_certificate_issuer		"certificateIssuer"
-#define LN_certificate_issuer		"X509v3 Certificate Issuer"
-#define NID_certificate_issuer		771
-#define OBJ_certificate_issuer		OBJ_id_ce,29L
-
-#define SN_name_constraints		"nameConstraints"
-#define LN_name_constraints		"X509v3 Name Constraints"
-#define NID_name_constraints		666
-#define OBJ_name_constraints		OBJ_id_ce,30L
-
-#define SN_crl_distribution_points		"crlDistributionPoints"
-#define LN_crl_distribution_points		"X509v3 CRL Distribution Points"
-#define NID_crl_distribution_points		103
-#define OBJ_crl_distribution_points		OBJ_id_ce,31L
-
-#define SN_certificate_policies		"certificatePolicies"
-#define LN_certificate_policies		"X509v3 Certificate Policies"
-#define NID_certificate_policies		89
-#define OBJ_certificate_policies		OBJ_id_ce,32L
-
-#define SN_any_policy		"anyPolicy"
-#define LN_any_policy		"X509v3 Any Policy"
-#define NID_any_policy		746
-#define OBJ_any_policy		OBJ_certificate_policies,0L
-
-#define SN_policy_mappings		"policyMappings"
-#define LN_policy_mappings		"X509v3 Policy Mappings"
-#define NID_policy_mappings		747
-#define OBJ_policy_mappings		OBJ_id_ce,33L
-
-#define SN_authority_key_identifier		"authorityKeyIdentifier"
-#define LN_authority_key_identifier		"X509v3 Authority Key Identifier"
-#define NID_authority_key_identifier		90
-#define OBJ_authority_key_identifier		OBJ_id_ce,35L
-
-#define SN_policy_constraints		"policyConstraints"
-#define LN_policy_constraints		"X509v3 Policy Constraints"
-#define NID_policy_constraints		401
-#define OBJ_policy_constraints		OBJ_id_ce,36L
-
-#define SN_ext_key_usage		"extendedKeyUsage"
-#define LN_ext_key_usage		"X509v3 Extended Key Usage"
-#define NID_ext_key_usage		126
-#define OBJ_ext_key_usage		OBJ_id_ce,37L
-
-#define SN_freshest_crl		"freshestCRL"
-#define LN_freshest_crl		"X509v3 Freshest CRL"
-#define NID_freshest_crl		857
-#define OBJ_freshest_crl		OBJ_id_ce,46L
-
-#define SN_inhibit_any_policy		"inhibitAnyPolicy"
-#define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
-#define NID_inhibit_any_policy		748
-#define OBJ_inhibit_any_policy		OBJ_id_ce,54L
-
-#define SN_target_information		"targetInformation"
-#define LN_target_information		"X509v3 AC Targeting"
-#define NID_target_information		402
-#define OBJ_target_information		OBJ_id_ce,55L
-
-#define SN_no_rev_avail		"noRevAvail"
-#define LN_no_rev_avail		"X509v3 No Revocation Available"
-#define NID_no_rev_avail		403
-#define OBJ_no_rev_avail		OBJ_id_ce,56L
-
-#define SN_anyExtendedKeyUsage		"anyExtendedKeyUsage"
-#define LN_anyExtendedKeyUsage		"Any Extended Key Usage"
-#define NID_anyExtendedKeyUsage		910
-#define OBJ_anyExtendedKeyUsage		OBJ_ext_key_usage,0L
-
-#define SN_netscape		"Netscape"
-#define LN_netscape		"Netscape Communications Corp."
-#define NID_netscape		57
-#define OBJ_netscape		2L,16L,840L,1L,113730L
-
-#define SN_netscape_cert_extension		"nsCertExt"
-#define LN_netscape_cert_extension		"Netscape Certificate Extension"
-#define NID_netscape_cert_extension		58
-#define OBJ_netscape_cert_extension		OBJ_netscape,1L
-
-#define SN_netscape_data_type		"nsDataType"
-#define LN_netscape_data_type		"Netscape Data Type"
-#define NID_netscape_data_type		59
-#define OBJ_netscape_data_type		OBJ_netscape,2L
-
-#define SN_netscape_cert_type		"nsCertType"
-#define LN_netscape_cert_type		"Netscape Cert Type"
-#define NID_netscape_cert_type		71
-#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
-
-#define SN_netscape_base_url		"nsBaseUrl"
-#define LN_netscape_base_url		"Netscape Base Url"
-#define NID_netscape_base_url		72
-#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
-
-#define SN_netscape_revocation_url		"nsRevocationUrl"
-#define LN_netscape_revocation_url		"Netscape Revocation Url"
-#define NID_netscape_revocation_url		73
-#define OBJ_netscape_revocation_url		OBJ_netscape_cert_extension,3L
-
-#define SN_netscape_ca_revocation_url		"nsCaRevocationUrl"
-#define LN_netscape_ca_revocation_url		"Netscape CA Revocation Url"
-#define NID_netscape_ca_revocation_url		74
-#define OBJ_netscape_ca_revocation_url		OBJ_netscape_cert_extension,4L
-
-#define SN_netscape_renewal_url		"nsRenewalUrl"
-#define LN_netscape_renewal_url		"Netscape Renewal Url"
-#define NID_netscape_renewal_url		75
-#define OBJ_netscape_renewal_url		OBJ_netscape_cert_extension,7L
-
-#define SN_netscape_ca_policy_url		"nsCaPolicyUrl"
-#define LN_netscape_ca_policy_url		"Netscape CA Policy Url"
-#define NID_netscape_ca_policy_url		76
-#define OBJ_netscape_ca_policy_url		OBJ_netscape_cert_extension,8L
-
-#define SN_netscape_ssl_server_name		"nsSslServerName"
-#define LN_netscape_ssl_server_name		"Netscape SSL Server Name"
-#define NID_netscape_ssl_server_name		77
-#define OBJ_netscape_ssl_server_name		OBJ_netscape_cert_extension,12L
-
-#define SN_netscape_comment		"nsComment"
-#define LN_netscape_comment		"Netscape Comment"
-#define NID_netscape_comment		78
-#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
-
-#define SN_netscape_cert_sequence		"nsCertSequence"
-#define LN_netscape_cert_sequence		"Netscape Certificate Sequence"
-#define NID_netscape_cert_sequence		79
-#define OBJ_netscape_cert_sequence		OBJ_netscape_data_type,5L
-
-#define SN_ns_sgc		"nsSGC"
-#define LN_ns_sgc		"Netscape Server Gated Crypto"
-#define NID_ns_sgc		139
-#define OBJ_ns_sgc		OBJ_netscape,4L,1L
-
-#define SN_org		"ORG"
-#define LN_org		"org"
-#define NID_org		379
-#define OBJ_org		OBJ_iso,3L
-
-#define SN_dod		"DOD"
-#define LN_dod		"dod"
-#define NID_dod		380
-#define OBJ_dod		OBJ_org,6L
-
-#define SN_iana		"IANA"
-#define LN_iana		"iana"
-#define NID_iana		381
-#define OBJ_iana		OBJ_dod,1L
-
-#define OBJ_internet		OBJ_iana
-
-#define SN_Directory		"directory"
-#define LN_Directory		"Directory"
-#define NID_Directory		382
-#define OBJ_Directory		OBJ_internet,1L
-
-#define SN_Management		"mgmt"
-#define LN_Management		"Management"
-#define NID_Management		383
-#define OBJ_Management		OBJ_internet,2L
-
-#define SN_Experimental		"experimental"
-#define LN_Experimental		"Experimental"
-#define NID_Experimental		384
-#define OBJ_Experimental		OBJ_internet,3L
-
-#define SN_Private		"private"
-#define LN_Private		"Private"
-#define NID_Private		385
-#define OBJ_Private		OBJ_internet,4L
-
-#define SN_Security		"security"
-#define LN_Security		"Security"
-#define NID_Security		386
-#define OBJ_Security		OBJ_internet,5L
-
-#define SN_SNMPv2		"snmpv2"
-#define LN_SNMPv2		"SNMPv2"
-#define NID_SNMPv2		387
-#define OBJ_SNMPv2		OBJ_internet,6L
-
-#define LN_Mail		"Mail"
-#define NID_Mail		388
-#define OBJ_Mail		OBJ_internet,7L
-
-#define SN_Enterprises		"enterprises"
-#define LN_Enterprises		"Enterprises"
-#define NID_Enterprises		389
-#define OBJ_Enterprises		OBJ_Private,1L
-
-#define SN_dcObject		"dcobject"
-#define LN_dcObject		"dcObject"
-#define NID_dcObject		390
-#define OBJ_dcObject		OBJ_Enterprises,1466L,344L
-
-#define SN_mime_mhs		"mime-mhs"
-#define LN_mime_mhs		"MIME MHS"
-#define NID_mime_mhs		504
-#define OBJ_mime_mhs		OBJ_Mail,1L
-
-#define SN_mime_mhs_headings		"mime-mhs-headings"
-#define LN_mime_mhs_headings		"mime-mhs-headings"
-#define NID_mime_mhs_headings		505
-#define OBJ_mime_mhs_headings		OBJ_mime_mhs,1L
-
-#define SN_mime_mhs_bodies		"mime-mhs-bodies"
-#define LN_mime_mhs_bodies		"mime-mhs-bodies"
-#define NID_mime_mhs_bodies		506
-#define OBJ_mime_mhs_bodies		OBJ_mime_mhs,2L
-
-#define SN_id_hex_partial_message		"id-hex-partial-message"
-#define LN_id_hex_partial_message		"id-hex-partial-message"
-#define NID_id_hex_partial_message		507
-#define OBJ_id_hex_partial_message		OBJ_mime_mhs_headings,1L
-
-#define SN_id_hex_multipart_message		"id-hex-multipart-message"
-#define LN_id_hex_multipart_message		"id-hex-multipart-message"
-#define NID_id_hex_multipart_message		508
-#define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
-
-#define SN_zlib_compression		"ZLIB"
-#define LN_zlib_compression		"zlib compression"
-#define NID_zlib_compression		125
-#define OBJ_zlib_compression		OBJ_id_smime_alg,8L
-
-#define OBJ_csor		2L,16L,840L,1L,101L,3L
-
-#define OBJ_nistAlgorithms		OBJ_csor,4L
-
-#define OBJ_aes		OBJ_nistAlgorithms,1L
-
-#define SN_aes_128_ecb		"AES-128-ECB"
-#define LN_aes_128_ecb		"aes-128-ecb"
-#define NID_aes_128_ecb		418
-#define OBJ_aes_128_ecb		OBJ_aes,1L
-
-#define SN_aes_128_cbc		"AES-128-CBC"
-#define LN_aes_128_cbc		"aes-128-cbc"
-#define NID_aes_128_cbc		419
-#define OBJ_aes_128_cbc		OBJ_aes,2L
-
-#define SN_aes_128_ofb128		"AES-128-OFB"
-#define LN_aes_128_ofb128		"aes-128-ofb"
-#define NID_aes_128_ofb128		420
-#define OBJ_aes_128_ofb128		OBJ_aes,3L
-
-#define SN_aes_128_cfb128		"AES-128-CFB"
-#define LN_aes_128_cfb128		"aes-128-cfb"
-#define NID_aes_128_cfb128		421
-#define OBJ_aes_128_cfb128		OBJ_aes,4L
-
-#define SN_id_aes128_wrap		"id-aes128-wrap"
-#define NID_id_aes128_wrap		788
-#define OBJ_id_aes128_wrap		OBJ_aes,5L
-
-#define SN_aes_128_gcm		"id-aes128-GCM"
-#define LN_aes_128_gcm		"aes-128-gcm"
-#define NID_aes_128_gcm		895
-#define OBJ_aes_128_gcm		OBJ_aes,6L
-
-#define SN_aes_128_ccm		"id-aes128-CCM"
-#define LN_aes_128_ccm		"aes-128-ccm"
-#define NID_aes_128_ccm		896
-#define OBJ_aes_128_ccm		OBJ_aes,7L
-
-#define SN_id_aes128_wrap_pad		"id-aes128-wrap-pad"
-#define NID_id_aes128_wrap_pad		897
-#define OBJ_id_aes128_wrap_pad		OBJ_aes,8L
-
-#define SN_aes_192_ecb		"AES-192-ECB"
-#define LN_aes_192_ecb		"aes-192-ecb"
-#define NID_aes_192_ecb		422
-#define OBJ_aes_192_ecb		OBJ_aes,21L
-
-#define SN_aes_192_cbc		"AES-192-CBC"
-#define LN_aes_192_cbc		"aes-192-cbc"
-#define NID_aes_192_cbc		423
-#define OBJ_aes_192_cbc		OBJ_aes,22L
-
-#define SN_aes_192_ofb128		"AES-192-OFB"
-#define LN_aes_192_ofb128		"aes-192-ofb"
-#define NID_aes_192_ofb128		424
-#define OBJ_aes_192_ofb128		OBJ_aes,23L
-
-#define SN_aes_192_cfb128		"AES-192-CFB"
-#define LN_aes_192_cfb128		"aes-192-cfb"
-#define NID_aes_192_cfb128		425
-#define OBJ_aes_192_cfb128		OBJ_aes,24L
-
-#define SN_id_aes192_wrap		"id-aes192-wrap"
-#define NID_id_aes192_wrap		789
-#define OBJ_id_aes192_wrap		OBJ_aes,25L
-
-#define SN_aes_192_gcm		"id-aes192-GCM"
-#define LN_aes_192_gcm		"aes-192-gcm"
-#define NID_aes_192_gcm		898
-#define OBJ_aes_192_gcm		OBJ_aes,26L
-
-#define SN_aes_192_ccm		"id-aes192-CCM"
-#define LN_aes_192_ccm		"aes-192-ccm"
-#define NID_aes_192_ccm		899
-#define OBJ_aes_192_ccm		OBJ_aes,27L
-
-#define SN_id_aes192_wrap_pad		"id-aes192-wrap-pad"
-#define NID_id_aes192_wrap_pad		900
-#define OBJ_id_aes192_wrap_pad		OBJ_aes,28L
-
-#define SN_aes_256_ecb		"AES-256-ECB"
-#define LN_aes_256_ecb		"aes-256-ecb"
-#define NID_aes_256_ecb		426
-#define OBJ_aes_256_ecb		OBJ_aes,41L
-
-#define SN_aes_256_cbc		"AES-256-CBC"
-#define LN_aes_256_cbc		"aes-256-cbc"
-#define NID_aes_256_cbc		427
-#define OBJ_aes_256_cbc		OBJ_aes,42L
-
-#define SN_aes_256_ofb128		"AES-256-OFB"
-#define LN_aes_256_ofb128		"aes-256-ofb"
-#define NID_aes_256_ofb128		428
-#define OBJ_aes_256_ofb128		OBJ_aes,43L
-
-#define SN_aes_256_cfb128		"AES-256-CFB"
-#define LN_aes_256_cfb128		"aes-256-cfb"
-#define NID_aes_256_cfb128		429
-#define OBJ_aes_256_cfb128		OBJ_aes,44L
-
-#define SN_id_aes256_wrap		"id-aes256-wrap"
-#define NID_id_aes256_wrap		790
-#define OBJ_id_aes256_wrap		OBJ_aes,45L
-
-#define SN_aes_256_gcm		"id-aes256-GCM"
-#define LN_aes_256_gcm		"aes-256-gcm"
-#define NID_aes_256_gcm		901
-#define OBJ_aes_256_gcm		OBJ_aes,46L
-
-#define SN_aes_256_ccm		"id-aes256-CCM"
-#define LN_aes_256_ccm		"aes-256-ccm"
-#define NID_aes_256_ccm		902
-#define OBJ_aes_256_ccm		OBJ_aes,47L
-
-#define SN_id_aes256_wrap_pad		"id-aes256-wrap-pad"
-#define NID_id_aes256_wrap_pad		903
-#define OBJ_id_aes256_wrap_pad		OBJ_aes,48L
-
-#define SN_aes_128_cfb1		"AES-128-CFB1"
-#define LN_aes_128_cfb1		"aes-128-cfb1"
-#define NID_aes_128_cfb1		650
-
-#define SN_aes_192_cfb1		"AES-192-CFB1"
-#define LN_aes_192_cfb1		"aes-192-cfb1"
-#define NID_aes_192_cfb1		651
-
-#define SN_aes_256_cfb1		"AES-256-CFB1"
-#define LN_aes_256_cfb1		"aes-256-cfb1"
-#define NID_aes_256_cfb1		652
-
-#define SN_aes_128_cfb8		"AES-128-CFB8"
-#define LN_aes_128_cfb8		"aes-128-cfb8"
-#define NID_aes_128_cfb8		653
-
-#define SN_aes_192_cfb8		"AES-192-CFB8"
-#define LN_aes_192_cfb8		"aes-192-cfb8"
-#define NID_aes_192_cfb8		654
-
-#define SN_aes_256_cfb8		"AES-256-CFB8"
-#define LN_aes_256_cfb8		"aes-256-cfb8"
-#define NID_aes_256_cfb8		655
-
-#define SN_aes_128_ctr		"AES-128-CTR"
-#define LN_aes_128_ctr		"aes-128-ctr"
-#define NID_aes_128_ctr		904
-
-#define SN_aes_192_ctr		"AES-192-CTR"
-#define LN_aes_192_ctr		"aes-192-ctr"
-#define NID_aes_192_ctr		905
-
-#define SN_aes_256_ctr		"AES-256-CTR"
-#define LN_aes_256_ctr		"aes-256-ctr"
-#define NID_aes_256_ctr		906
-
-#define SN_aes_128_xts		"AES-128-XTS"
-#define LN_aes_128_xts		"aes-128-xts"
-#define NID_aes_128_xts		913
-
-#define SN_aes_256_xts		"AES-256-XTS"
-#define LN_aes_256_xts		"aes-256-xts"
-#define NID_aes_256_xts		914
-
-#define SN_des_cfb1		"DES-CFB1"
-#define LN_des_cfb1		"des-cfb1"
-#define NID_des_cfb1		656
-
-#define SN_des_cfb8		"DES-CFB8"
-#define LN_des_cfb8		"des-cfb8"
-#define NID_des_cfb8		657
-
-#define SN_des_ede3_cfb1		"DES-EDE3-CFB1"
-#define LN_des_ede3_cfb1		"des-ede3-cfb1"
-#define NID_des_ede3_cfb1		658
-
-#define SN_des_ede3_cfb8		"DES-EDE3-CFB8"
-#define LN_des_ede3_cfb8		"des-ede3-cfb8"
-#define NID_des_ede3_cfb8		659
-
-#define OBJ_nist_hashalgs		OBJ_nistAlgorithms,2L
-
-#define SN_sha256		"SHA256"
-#define LN_sha256		"sha256"
-#define NID_sha256		672
-#define OBJ_sha256		OBJ_nist_hashalgs,1L
-
-#define SN_sha384		"SHA384"
-#define LN_sha384		"sha384"
-#define NID_sha384		673
-#define OBJ_sha384		OBJ_nist_hashalgs,2L
-
-#define SN_sha512		"SHA512"
-#define LN_sha512		"sha512"
-#define NID_sha512		674
-#define OBJ_sha512		OBJ_nist_hashalgs,3L
-
-#define SN_sha224		"SHA224"
-#define LN_sha224		"sha224"
-#define NID_sha224		675
-#define OBJ_sha224		OBJ_nist_hashalgs,4L
-
-#define OBJ_dsa_with_sha2		OBJ_nistAlgorithms,3L
-
-#define SN_dsa_with_SHA224		"dsa_with_SHA224"
-#define NID_dsa_with_SHA224		802
-#define OBJ_dsa_with_SHA224		OBJ_dsa_with_sha2,1L
-
-#define SN_dsa_with_SHA256		"dsa_with_SHA256"
-#define NID_dsa_with_SHA256		803
-#define OBJ_dsa_with_SHA256		OBJ_dsa_with_sha2,2L
-
-#define SN_hold_instruction_code		"holdInstructionCode"
-#define LN_hold_instruction_code		"Hold Instruction Code"
-#define NID_hold_instruction_code		430
-#define OBJ_hold_instruction_code		OBJ_id_ce,23L
-
-#define OBJ_holdInstruction		OBJ_X9_57,2L
-
-#define SN_hold_instruction_none		"holdInstructionNone"
-#define LN_hold_instruction_none		"Hold Instruction None"
-#define NID_hold_instruction_none		431
-#define OBJ_hold_instruction_none		OBJ_holdInstruction,1L
-
-#define SN_hold_instruction_call_issuer		"holdInstructionCallIssuer"
-#define LN_hold_instruction_call_issuer		"Hold Instruction Call Issuer"
-#define NID_hold_instruction_call_issuer		432
-#define OBJ_hold_instruction_call_issuer		OBJ_holdInstruction,2L
-
-#define SN_hold_instruction_reject		"holdInstructionReject"
-#define LN_hold_instruction_reject		"Hold Instruction Reject"
-#define NID_hold_instruction_reject		433
-#define OBJ_hold_instruction_reject		OBJ_holdInstruction,3L
-
-#define SN_data		"data"
-#define NID_data		434
-#define OBJ_data		OBJ_itu_t,9L
-
-#define SN_pss		"pss"
-#define NID_pss		435
-#define OBJ_pss		OBJ_data,2342L
-
-#define SN_ucl		"ucl"
-#define NID_ucl		436
-#define OBJ_ucl		OBJ_pss,19200300L
-
-#define SN_pilot		"pilot"
-#define NID_pilot		437
-#define OBJ_pilot		OBJ_ucl,100L
-
-#define LN_pilotAttributeType		"pilotAttributeType"
-#define NID_pilotAttributeType		438
-#define OBJ_pilotAttributeType		OBJ_pilot,1L
-
-#define LN_pilotAttributeSyntax		"pilotAttributeSyntax"
-#define NID_pilotAttributeSyntax		439
-#define OBJ_pilotAttributeSyntax		OBJ_pilot,3L
-
-#define LN_pilotObjectClass		"pilotObjectClass"
-#define NID_pilotObjectClass		440
-#define OBJ_pilotObjectClass		OBJ_pilot,4L
-
-#define LN_pilotGroups		"pilotGroups"
-#define NID_pilotGroups		441
-#define OBJ_pilotGroups		OBJ_pilot,10L
-
-#define LN_iA5StringSyntax		"iA5StringSyntax"
-#define NID_iA5StringSyntax		442
-#define OBJ_iA5StringSyntax		OBJ_pilotAttributeSyntax,4L
-
-#define LN_caseIgnoreIA5StringSyntax		"caseIgnoreIA5StringSyntax"
-#define NID_caseIgnoreIA5StringSyntax		443
-#define OBJ_caseIgnoreIA5StringSyntax		OBJ_pilotAttributeSyntax,5L
-
-#define LN_pilotObject		"pilotObject"
-#define NID_pilotObject		444
-#define OBJ_pilotObject		OBJ_pilotObjectClass,3L
-
-#define LN_pilotPerson		"pilotPerson"
-#define NID_pilotPerson		445
-#define OBJ_pilotPerson		OBJ_pilotObjectClass,4L
-
-#define SN_account		"account"
-#define NID_account		446
-#define OBJ_account		OBJ_pilotObjectClass,5L
-
-#define SN_document		"document"
-#define NID_document		447
-#define OBJ_document		OBJ_pilotObjectClass,6L
-
-#define SN_room		"room"
-#define NID_room		448
-#define OBJ_room		OBJ_pilotObjectClass,7L
-
-#define LN_documentSeries		"documentSeries"
-#define NID_documentSeries		449
-#define OBJ_documentSeries		OBJ_pilotObjectClass,9L
-
-#define SN_Domain		"domain"
-#define LN_Domain		"Domain"
-#define NID_Domain		392
-#define OBJ_Domain		OBJ_pilotObjectClass,13L
-
-#define LN_rFC822localPart		"rFC822localPart"
-#define NID_rFC822localPart		450
-#define OBJ_rFC822localPart		OBJ_pilotObjectClass,14L
-
-#define LN_dNSDomain		"dNSDomain"
-#define NID_dNSDomain		451
-#define OBJ_dNSDomain		OBJ_pilotObjectClass,15L
-
-#define LN_domainRelatedObject		"domainRelatedObject"
-#define NID_domainRelatedObject		452
-#define OBJ_domainRelatedObject		OBJ_pilotObjectClass,17L
-
-#define LN_friendlyCountry		"friendlyCountry"
-#define NID_friendlyCountry		453
-#define OBJ_friendlyCountry		OBJ_pilotObjectClass,18L
-
-#define LN_simpleSecurityObject		"simpleSecurityObject"
-#define NID_simpleSecurityObject		454
-#define OBJ_simpleSecurityObject		OBJ_pilotObjectClass,19L
-
-#define LN_pilotOrganization		"pilotOrganization"
-#define NID_pilotOrganization		455
-#define OBJ_pilotOrganization		OBJ_pilotObjectClass,20L
-
-#define LN_pilotDSA		"pilotDSA"
-#define NID_pilotDSA		456
-#define OBJ_pilotDSA		OBJ_pilotObjectClass,21L
-
-#define LN_qualityLabelledData		"qualityLabelledData"
-#define NID_qualityLabelledData		457
-#define OBJ_qualityLabelledData		OBJ_pilotObjectClass,22L
-
-#define SN_userId		"UID"
-#define LN_userId		"userId"
-#define NID_userId		458
-#define OBJ_userId		OBJ_pilotAttributeType,1L
-
-#define LN_textEncodedORAddress		"textEncodedORAddress"
-#define NID_textEncodedORAddress		459
-#define OBJ_textEncodedORAddress		OBJ_pilotAttributeType,2L
-
-#define SN_rfc822Mailbox		"mail"
-#define LN_rfc822Mailbox		"rfc822Mailbox"
-#define NID_rfc822Mailbox		460
-#define OBJ_rfc822Mailbox		OBJ_pilotAttributeType,3L
-
-#define SN_info		"info"
-#define NID_info		461
-#define OBJ_info		OBJ_pilotAttributeType,4L
-
-#define LN_favouriteDrink		"favouriteDrink"
-#define NID_favouriteDrink		462
-#define OBJ_favouriteDrink		OBJ_pilotAttributeType,5L
-
-#define LN_roomNumber		"roomNumber"
-#define NID_roomNumber		463
-#define OBJ_roomNumber		OBJ_pilotAttributeType,6L
-
-#define SN_photo		"photo"
-#define NID_photo		464
-#define OBJ_photo		OBJ_pilotAttributeType,7L
-
-#define LN_userClass		"userClass"
-#define NID_userClass		465
-#define OBJ_userClass		OBJ_pilotAttributeType,8L
-
-#define SN_host		"host"
-#define NID_host		466
-#define OBJ_host		OBJ_pilotAttributeType,9L
-
-#define SN_manager		"manager"
-#define NID_manager		467
-#define OBJ_manager		OBJ_pilotAttributeType,10L
-
-#define LN_documentIdentifier		"documentIdentifier"
-#define NID_documentIdentifier		468
-#define OBJ_documentIdentifier		OBJ_pilotAttributeType,11L
-
-#define LN_documentTitle		"documentTitle"
-#define NID_documentTitle		469
-#define OBJ_documentTitle		OBJ_pilotAttributeType,12L
-
-#define LN_documentVersion		"documentVersion"
-#define NID_documentVersion		470
-#define OBJ_documentVersion		OBJ_pilotAttributeType,13L
-
-#define LN_documentAuthor		"documentAuthor"
-#define NID_documentAuthor		471
-#define OBJ_documentAuthor		OBJ_pilotAttributeType,14L
-
-#define LN_documentLocation		"documentLocation"
-#define NID_documentLocation		472
-#define OBJ_documentLocation		OBJ_pilotAttributeType,15L
-
-#define LN_homeTelephoneNumber		"homeTelephoneNumber"
-#define NID_homeTelephoneNumber		473
-#define OBJ_homeTelephoneNumber		OBJ_pilotAttributeType,20L
-
-#define SN_secretary		"secretary"
-#define NID_secretary		474
-#define OBJ_secretary		OBJ_pilotAttributeType,21L
-
-#define LN_otherMailbox		"otherMailbox"
-#define NID_otherMailbox		475
-#define OBJ_otherMailbox		OBJ_pilotAttributeType,22L
-
-#define LN_lastModifiedTime		"lastModifiedTime"
-#define NID_lastModifiedTime		476
-#define OBJ_lastModifiedTime		OBJ_pilotAttributeType,23L
-
-#define LN_lastModifiedBy		"lastModifiedBy"
-#define NID_lastModifiedBy		477
-#define OBJ_lastModifiedBy		OBJ_pilotAttributeType,24L
-
-#define SN_domainComponent		"DC"
-#define LN_domainComponent		"domainComponent"
-#define NID_domainComponent		391
-#define OBJ_domainComponent		OBJ_pilotAttributeType,25L
-
-#define LN_aRecord		"aRecord"
-#define NID_aRecord		478
-#define OBJ_aRecord		OBJ_pilotAttributeType,26L
-
-#define LN_pilotAttributeType27		"pilotAttributeType27"
-#define NID_pilotAttributeType27		479
-#define OBJ_pilotAttributeType27		OBJ_pilotAttributeType,27L
-
-#define LN_mXRecord		"mXRecord"
-#define NID_mXRecord		480
-#define OBJ_mXRecord		OBJ_pilotAttributeType,28L
-
-#define LN_nSRecord		"nSRecord"
-#define NID_nSRecord		481
-#define OBJ_nSRecord		OBJ_pilotAttributeType,29L
-
-#define LN_sOARecord		"sOARecord"
-#define NID_sOARecord		482
-#define OBJ_sOARecord		OBJ_pilotAttributeType,30L
-
-#define LN_cNAMERecord		"cNAMERecord"
-#define NID_cNAMERecord		483
-#define OBJ_cNAMERecord		OBJ_pilotAttributeType,31L
-
-#define LN_associatedDomain		"associatedDomain"
-#define NID_associatedDomain		484
-#define OBJ_associatedDomain		OBJ_pilotAttributeType,37L
-
-#define LN_associatedName		"associatedName"
-#define NID_associatedName		485
-#define OBJ_associatedName		OBJ_pilotAttributeType,38L
-
-#define LN_homePostalAddress		"homePostalAddress"
-#define NID_homePostalAddress		486
-#define OBJ_homePostalAddress		OBJ_pilotAttributeType,39L
-
-#define LN_personalTitle		"personalTitle"
-#define NID_personalTitle		487
-#define OBJ_personalTitle		OBJ_pilotAttributeType,40L
-
-#define LN_mobileTelephoneNumber		"mobileTelephoneNumber"
-#define NID_mobileTelephoneNumber		488
-#define OBJ_mobileTelephoneNumber		OBJ_pilotAttributeType,41L
-
-#define LN_pagerTelephoneNumber		"pagerTelephoneNumber"
-#define NID_pagerTelephoneNumber		489
-#define OBJ_pagerTelephoneNumber		OBJ_pilotAttributeType,42L
-
-#define LN_friendlyCountryName		"friendlyCountryName"
-#define NID_friendlyCountryName		490
-#define OBJ_friendlyCountryName		OBJ_pilotAttributeType,43L
-
-#define LN_organizationalStatus		"organizationalStatus"
-#define NID_organizationalStatus		491
-#define OBJ_organizationalStatus		OBJ_pilotAttributeType,45L
-
-#define LN_janetMailbox		"janetMailbox"
-#define NID_janetMailbox		492
-#define OBJ_janetMailbox		OBJ_pilotAttributeType,46L
-
-#define LN_mailPreferenceOption		"mailPreferenceOption"
-#define NID_mailPreferenceOption		493
-#define OBJ_mailPreferenceOption		OBJ_pilotAttributeType,47L
-
-#define LN_buildingName		"buildingName"
-#define NID_buildingName		494
-#define OBJ_buildingName		OBJ_pilotAttributeType,48L
-
-#define LN_dSAQuality		"dSAQuality"
-#define NID_dSAQuality		495
-#define OBJ_dSAQuality		OBJ_pilotAttributeType,49L
-
-#define LN_singleLevelQuality		"singleLevelQuality"
-#define NID_singleLevelQuality		496
-#define OBJ_singleLevelQuality		OBJ_pilotAttributeType,50L
-
-#define LN_subtreeMinimumQuality		"subtreeMinimumQuality"
-#define NID_subtreeMinimumQuality		497
-#define OBJ_subtreeMinimumQuality		OBJ_pilotAttributeType,51L
-
-#define LN_subtreeMaximumQuality		"subtreeMaximumQuality"
-#define NID_subtreeMaximumQuality		498
-#define OBJ_subtreeMaximumQuality		OBJ_pilotAttributeType,52L
-
-#define LN_personalSignature		"personalSignature"
-#define NID_personalSignature		499
-#define OBJ_personalSignature		OBJ_pilotAttributeType,53L
-
-#define LN_dITRedirect		"dITRedirect"
-#define NID_dITRedirect		500
-#define OBJ_dITRedirect		OBJ_pilotAttributeType,54L
-
-#define SN_audio		"audio"
-#define NID_audio		501
-#define OBJ_audio		OBJ_pilotAttributeType,55L
-
-#define LN_documentPublisher		"documentPublisher"
-#define NID_documentPublisher		502
-#define OBJ_documentPublisher		OBJ_pilotAttributeType,56L
-
-#define SN_id_set		"id-set"
-#define LN_id_set		"Secure Electronic Transactions"
-#define NID_id_set		512
-#define OBJ_id_set		OBJ_international_organizations,42L
-
-#define SN_set_ctype		"set-ctype"
-#define LN_set_ctype		"content types"
-#define NID_set_ctype		513
-#define OBJ_set_ctype		OBJ_id_set,0L
-
-#define SN_set_msgExt		"set-msgExt"
-#define LN_set_msgExt		"message extensions"
-#define NID_set_msgExt		514
-#define OBJ_set_msgExt		OBJ_id_set,1L
-
-#define SN_set_attr		"set-attr"
-#define NID_set_attr		515
-#define OBJ_set_attr		OBJ_id_set,3L
-
-#define SN_set_policy		"set-policy"
-#define NID_set_policy		516
-#define OBJ_set_policy		OBJ_id_set,5L
-
-#define SN_set_certExt		"set-certExt"
-#define LN_set_certExt		"certificate extensions"
-#define NID_set_certExt		517
-#define OBJ_set_certExt		OBJ_id_set,7L
-
-#define SN_set_brand		"set-brand"
-#define NID_set_brand		518
-#define OBJ_set_brand		OBJ_id_set,8L
-
-#define SN_setct_PANData		"setct-PANData"
-#define NID_setct_PANData		519
-#define OBJ_setct_PANData		OBJ_set_ctype,0L
-
-#define SN_setct_PANToken		"setct-PANToken"
-#define NID_setct_PANToken		520
-#define OBJ_setct_PANToken		OBJ_set_ctype,1L
-
-#define SN_setct_PANOnly		"setct-PANOnly"
-#define NID_setct_PANOnly		521
-#define OBJ_setct_PANOnly		OBJ_set_ctype,2L
-
-#define SN_setct_OIData		"setct-OIData"
-#define NID_setct_OIData		522
-#define OBJ_setct_OIData		OBJ_set_ctype,3L
-
-#define SN_setct_PI		"setct-PI"
-#define NID_setct_PI		523
-#define OBJ_setct_PI		OBJ_set_ctype,4L
-
-#define SN_setct_PIData		"setct-PIData"
-#define NID_setct_PIData		524
-#define OBJ_setct_PIData		OBJ_set_ctype,5L
-
-#define SN_setct_PIDataUnsigned		"setct-PIDataUnsigned"
-#define NID_setct_PIDataUnsigned		525
-#define OBJ_setct_PIDataUnsigned		OBJ_set_ctype,6L
-
-#define SN_setct_HODInput		"setct-HODInput"
-#define NID_setct_HODInput		526
-#define OBJ_setct_HODInput		OBJ_set_ctype,7L
-
-#define SN_setct_AuthResBaggage		"setct-AuthResBaggage"
-#define NID_setct_AuthResBaggage		527
-#define OBJ_setct_AuthResBaggage		OBJ_set_ctype,8L
-
-#define SN_setct_AuthRevReqBaggage		"setct-AuthRevReqBaggage"
-#define NID_setct_AuthRevReqBaggage		528
-#define OBJ_setct_AuthRevReqBaggage		OBJ_set_ctype,9L
-
-#define SN_setct_AuthRevResBaggage		"setct-AuthRevResBaggage"
-#define NID_setct_AuthRevResBaggage		529
-#define OBJ_setct_AuthRevResBaggage		OBJ_set_ctype,10L
-
-#define SN_setct_CapTokenSeq		"setct-CapTokenSeq"
-#define NID_setct_CapTokenSeq		530
-#define OBJ_setct_CapTokenSeq		OBJ_set_ctype,11L
-
-#define SN_setct_PInitResData		"setct-PInitResData"
-#define NID_setct_PInitResData		531
-#define OBJ_setct_PInitResData		OBJ_set_ctype,12L
-
-#define SN_setct_PI_TBS		"setct-PI-TBS"
-#define NID_setct_PI_TBS		532
-#define OBJ_setct_PI_TBS		OBJ_set_ctype,13L
-
-#define SN_setct_PResData		"setct-PResData"
-#define NID_setct_PResData		533
-#define OBJ_setct_PResData		OBJ_set_ctype,14L
-
-#define SN_setct_AuthReqTBS		"setct-AuthReqTBS"
-#define NID_setct_AuthReqTBS		534
-#define OBJ_setct_AuthReqTBS		OBJ_set_ctype,16L
-
-#define SN_setct_AuthResTBS		"setct-AuthResTBS"
-#define NID_setct_AuthResTBS		535
-#define OBJ_setct_AuthResTBS		OBJ_set_ctype,17L
-
-#define SN_setct_AuthResTBSX		"setct-AuthResTBSX"
-#define NID_setct_AuthResTBSX		536
-#define OBJ_setct_AuthResTBSX		OBJ_set_ctype,18L
-
-#define SN_setct_AuthTokenTBS		"setct-AuthTokenTBS"
-#define NID_setct_AuthTokenTBS		537
-#define OBJ_setct_AuthTokenTBS		OBJ_set_ctype,19L
-
-#define SN_setct_CapTokenData		"setct-CapTokenData"
-#define NID_setct_CapTokenData		538
-#define OBJ_setct_CapTokenData		OBJ_set_ctype,20L
-
-#define SN_setct_CapTokenTBS		"setct-CapTokenTBS"
-#define NID_setct_CapTokenTBS		539
-#define OBJ_setct_CapTokenTBS		OBJ_set_ctype,21L
-
-#define SN_setct_AcqCardCodeMsg		"setct-AcqCardCodeMsg"
-#define NID_setct_AcqCardCodeMsg		540
-#define OBJ_setct_AcqCardCodeMsg		OBJ_set_ctype,22L
-
-#define SN_setct_AuthRevReqTBS		"setct-AuthRevReqTBS"
-#define NID_setct_AuthRevReqTBS		541
-#define OBJ_setct_AuthRevReqTBS		OBJ_set_ctype,23L
-
-#define SN_setct_AuthRevResData		"setct-AuthRevResData"
-#define NID_setct_AuthRevResData		542
-#define OBJ_setct_AuthRevResData		OBJ_set_ctype,24L
-
-#define SN_setct_AuthRevResTBS		"setct-AuthRevResTBS"
-#define NID_setct_AuthRevResTBS		543
-#define OBJ_setct_AuthRevResTBS		OBJ_set_ctype,25L
-
-#define SN_setct_CapReqTBS		"setct-CapReqTBS"
-#define NID_setct_CapReqTBS		544
-#define OBJ_setct_CapReqTBS		OBJ_set_ctype,26L
-
-#define SN_setct_CapReqTBSX		"setct-CapReqTBSX"
-#define NID_setct_CapReqTBSX		545
-#define OBJ_setct_CapReqTBSX		OBJ_set_ctype,27L
-
-#define SN_setct_CapResData		"setct-CapResData"
-#define NID_setct_CapResData		546
-#define OBJ_setct_CapResData		OBJ_set_ctype,28L
-
-#define SN_setct_CapRevReqTBS		"setct-CapRevReqTBS"
-#define NID_setct_CapRevReqTBS		547
-#define OBJ_setct_CapRevReqTBS		OBJ_set_ctype,29L
-
-#define SN_setct_CapRevReqTBSX		"setct-CapRevReqTBSX"
-#define NID_setct_CapRevReqTBSX		548
-#define OBJ_setct_CapRevReqTBSX		OBJ_set_ctype,30L
-
-#define SN_setct_CapRevResData		"setct-CapRevResData"
-#define NID_setct_CapRevResData		549
-#define OBJ_setct_CapRevResData		OBJ_set_ctype,31L
-
-#define SN_setct_CredReqTBS		"setct-CredReqTBS"
-#define NID_setct_CredReqTBS		550
-#define OBJ_setct_CredReqTBS		OBJ_set_ctype,32L
-
-#define SN_setct_CredReqTBSX		"setct-CredReqTBSX"
-#define NID_setct_CredReqTBSX		551
-#define OBJ_setct_CredReqTBSX		OBJ_set_ctype,33L
-
-#define SN_setct_CredResData		"setct-CredResData"
-#define NID_setct_CredResData		552
-#define OBJ_setct_CredResData		OBJ_set_ctype,34L
-
-#define SN_setct_CredRevReqTBS		"setct-CredRevReqTBS"
-#define NID_setct_CredRevReqTBS		553
-#define OBJ_setct_CredRevReqTBS		OBJ_set_ctype,35L
-
-#define SN_setct_CredRevReqTBSX		"setct-CredRevReqTBSX"
-#define NID_setct_CredRevReqTBSX		554
-#define OBJ_setct_CredRevReqTBSX		OBJ_set_ctype,36L
-
-#define SN_setct_CredRevResData		"setct-CredRevResData"
-#define NID_setct_CredRevResData		555
-#define OBJ_setct_CredRevResData		OBJ_set_ctype,37L
-
-#define SN_setct_PCertReqData		"setct-PCertReqData"
-#define NID_setct_PCertReqData		556
-#define OBJ_setct_PCertReqData		OBJ_set_ctype,38L
-
-#define SN_setct_PCertResTBS		"setct-PCertResTBS"
-#define NID_setct_PCertResTBS		557
-#define OBJ_setct_PCertResTBS		OBJ_set_ctype,39L
-
-#define SN_setct_BatchAdminReqData		"setct-BatchAdminReqData"
-#define NID_setct_BatchAdminReqData		558
-#define OBJ_setct_BatchAdminReqData		OBJ_set_ctype,40L
-
-#define SN_setct_BatchAdminResData		"setct-BatchAdminResData"
-#define NID_setct_BatchAdminResData		559
-#define OBJ_setct_BatchAdminResData		OBJ_set_ctype,41L
-
-#define SN_setct_CardCInitResTBS		"setct-CardCInitResTBS"
-#define NID_setct_CardCInitResTBS		560
-#define OBJ_setct_CardCInitResTBS		OBJ_set_ctype,42L
-
-#define SN_setct_MeAqCInitResTBS		"setct-MeAqCInitResTBS"
-#define NID_setct_MeAqCInitResTBS		561
-#define OBJ_setct_MeAqCInitResTBS		OBJ_set_ctype,43L
-
-#define SN_setct_RegFormResTBS		"setct-RegFormResTBS"
-#define NID_setct_RegFormResTBS		562
-#define OBJ_setct_RegFormResTBS		OBJ_set_ctype,44L
-
-#define SN_setct_CertReqData		"setct-CertReqData"
-#define NID_setct_CertReqData		563
-#define OBJ_setct_CertReqData		OBJ_set_ctype,45L
-
-#define SN_setct_CertReqTBS		"setct-CertReqTBS"
-#define NID_setct_CertReqTBS		564
-#define OBJ_setct_CertReqTBS		OBJ_set_ctype,46L
-
-#define SN_setct_CertResData		"setct-CertResData"
-#define NID_setct_CertResData		565
-#define OBJ_setct_CertResData		OBJ_set_ctype,47L
-
-#define SN_setct_CertInqReqTBS		"setct-CertInqReqTBS"
-#define NID_setct_CertInqReqTBS		566
-#define OBJ_setct_CertInqReqTBS		OBJ_set_ctype,48L
-
-#define SN_setct_ErrorTBS		"setct-ErrorTBS"
-#define NID_setct_ErrorTBS		567
-#define OBJ_setct_ErrorTBS		OBJ_set_ctype,49L
-
-#define SN_setct_PIDualSignedTBE		"setct-PIDualSignedTBE"
-#define NID_setct_PIDualSignedTBE		568
-#define OBJ_setct_PIDualSignedTBE		OBJ_set_ctype,50L
-
-#define SN_setct_PIUnsignedTBE		"setct-PIUnsignedTBE"
-#define NID_setct_PIUnsignedTBE		569
-#define OBJ_setct_PIUnsignedTBE		OBJ_set_ctype,51L
-
-#define SN_setct_AuthReqTBE		"setct-AuthReqTBE"
-#define NID_setct_AuthReqTBE		570
-#define OBJ_setct_AuthReqTBE		OBJ_set_ctype,52L
-
-#define SN_setct_AuthResTBE		"setct-AuthResTBE"
-#define NID_setct_AuthResTBE		571
-#define OBJ_setct_AuthResTBE		OBJ_set_ctype,53L
-
-#define SN_setct_AuthResTBEX		"setct-AuthResTBEX"
-#define NID_setct_AuthResTBEX		572
-#define OBJ_setct_AuthResTBEX		OBJ_set_ctype,54L
-
-#define SN_setct_AuthTokenTBE		"setct-AuthTokenTBE"
-#define NID_setct_AuthTokenTBE		573
-#define OBJ_setct_AuthTokenTBE		OBJ_set_ctype,55L
-
-#define SN_setct_CapTokenTBE		"setct-CapTokenTBE"
-#define NID_setct_CapTokenTBE		574
-#define OBJ_setct_CapTokenTBE		OBJ_set_ctype,56L
-
-#define SN_setct_CapTokenTBEX		"setct-CapTokenTBEX"
-#define NID_setct_CapTokenTBEX		575
-#define OBJ_setct_CapTokenTBEX		OBJ_set_ctype,57L
-
-#define SN_setct_AcqCardCodeMsgTBE		"setct-AcqCardCodeMsgTBE"
-#define NID_setct_AcqCardCodeMsgTBE		576
-#define OBJ_setct_AcqCardCodeMsgTBE		OBJ_set_ctype,58L
-
-#define SN_setct_AuthRevReqTBE		"setct-AuthRevReqTBE"
-#define NID_setct_AuthRevReqTBE		577
-#define OBJ_setct_AuthRevReqTBE		OBJ_set_ctype,59L
-
-#define SN_setct_AuthRevResTBE		"setct-AuthRevResTBE"
-#define NID_setct_AuthRevResTBE		578
-#define OBJ_setct_AuthRevResTBE		OBJ_set_ctype,60L
-
-#define SN_setct_AuthRevResTBEB		"setct-AuthRevResTBEB"
-#define NID_setct_AuthRevResTBEB		579
-#define OBJ_setct_AuthRevResTBEB		OBJ_set_ctype,61L
-
-#define SN_setct_CapReqTBE		"setct-CapReqTBE"
-#define NID_setct_CapReqTBE		580
-#define OBJ_setct_CapReqTBE		OBJ_set_ctype,62L
-
-#define SN_setct_CapReqTBEX		"setct-CapReqTBEX"
-#define NID_setct_CapReqTBEX		581
-#define OBJ_setct_CapReqTBEX		OBJ_set_ctype,63L
-
-#define SN_setct_CapResTBE		"setct-CapResTBE"
-#define NID_setct_CapResTBE		582
-#define OBJ_setct_CapResTBE		OBJ_set_ctype,64L
-
-#define SN_setct_CapRevReqTBE		"setct-CapRevReqTBE"
-#define NID_setct_CapRevReqTBE		583
-#define OBJ_setct_CapRevReqTBE		OBJ_set_ctype,65L
-
-#define SN_setct_CapRevReqTBEX		"setct-CapRevReqTBEX"
-#define NID_setct_CapRevReqTBEX		584
-#define OBJ_setct_CapRevReqTBEX		OBJ_set_ctype,66L
-
-#define SN_setct_CapRevResTBE		"setct-CapRevResTBE"
-#define NID_setct_CapRevResTBE		585
-#define OBJ_setct_CapRevResTBE		OBJ_set_ctype,67L
-
-#define SN_setct_CredReqTBE		"setct-CredReqTBE"
-#define NID_setct_CredReqTBE		586
-#define OBJ_setct_CredReqTBE		OBJ_set_ctype,68L
-
-#define SN_setct_CredReqTBEX		"setct-CredReqTBEX"
-#define NID_setct_CredReqTBEX		587
-#define OBJ_setct_CredReqTBEX		OBJ_set_ctype,69L
-
-#define SN_setct_CredResTBE		"setct-CredResTBE"
-#define NID_setct_CredResTBE		588
-#define OBJ_setct_CredResTBE		OBJ_set_ctype,70L
-
-#define SN_setct_CredRevReqTBE		"setct-CredRevReqTBE"
-#define NID_setct_CredRevReqTBE		589
-#define OBJ_setct_CredRevReqTBE		OBJ_set_ctype,71L
-
-#define SN_setct_CredRevReqTBEX		"setct-CredRevReqTBEX"
-#define NID_setct_CredRevReqTBEX		590
-#define OBJ_setct_CredRevReqTBEX		OBJ_set_ctype,72L
-
-#define SN_setct_CredRevResTBE		"setct-CredRevResTBE"
-#define NID_setct_CredRevResTBE		591
-#define OBJ_setct_CredRevResTBE		OBJ_set_ctype,73L
-
-#define SN_setct_BatchAdminReqTBE		"setct-BatchAdminReqTBE"
-#define NID_setct_BatchAdminReqTBE		592
-#define OBJ_setct_BatchAdminReqTBE		OBJ_set_ctype,74L
-
-#define SN_setct_BatchAdminResTBE		"setct-BatchAdminResTBE"
-#define NID_setct_BatchAdminResTBE		593
-#define OBJ_setct_BatchAdminResTBE		OBJ_set_ctype,75L
-
-#define SN_setct_RegFormReqTBE		"setct-RegFormReqTBE"
-#define NID_setct_RegFormReqTBE		594
-#define OBJ_setct_RegFormReqTBE		OBJ_set_ctype,76L
-
-#define SN_setct_CertReqTBE		"setct-CertReqTBE"
-#define NID_setct_CertReqTBE		595
-#define OBJ_setct_CertReqTBE		OBJ_set_ctype,77L
-
-#define SN_setct_CertReqTBEX		"setct-CertReqTBEX"
-#define NID_setct_CertReqTBEX		596
-#define OBJ_setct_CertReqTBEX		OBJ_set_ctype,78L
-
-#define SN_setct_CertResTBE		"setct-CertResTBE"
-#define NID_setct_CertResTBE		597
-#define OBJ_setct_CertResTBE		OBJ_set_ctype,79L
-
-#define SN_setct_CRLNotificationTBS		"setct-CRLNotificationTBS"
-#define NID_setct_CRLNotificationTBS		598
-#define OBJ_setct_CRLNotificationTBS		OBJ_set_ctype,80L
-
-#define SN_setct_CRLNotificationResTBS		"setct-CRLNotificationResTBS"
-#define NID_setct_CRLNotificationResTBS		599
-#define OBJ_setct_CRLNotificationResTBS		OBJ_set_ctype,81L
-
-#define SN_setct_BCIDistributionTBS		"setct-BCIDistributionTBS"
-#define NID_setct_BCIDistributionTBS		600
-#define OBJ_setct_BCIDistributionTBS		OBJ_set_ctype,82L
-
-#define SN_setext_genCrypt		"setext-genCrypt"
-#define LN_setext_genCrypt		"generic cryptogram"
-#define NID_setext_genCrypt		601
-#define OBJ_setext_genCrypt		OBJ_set_msgExt,1L
-
-#define SN_setext_miAuth		"setext-miAuth"
-#define LN_setext_miAuth		"merchant initiated auth"
-#define NID_setext_miAuth		602
-#define OBJ_setext_miAuth		OBJ_set_msgExt,3L
-
-#define SN_setext_pinSecure		"setext-pinSecure"
-#define NID_setext_pinSecure		603
-#define OBJ_setext_pinSecure		OBJ_set_msgExt,4L
-
-#define SN_setext_pinAny		"setext-pinAny"
-#define NID_setext_pinAny		604
-#define OBJ_setext_pinAny		OBJ_set_msgExt,5L
-
-#define SN_setext_track2		"setext-track2"
-#define NID_setext_track2		605
-#define OBJ_setext_track2		OBJ_set_msgExt,7L
-
-#define SN_setext_cv		"setext-cv"
-#define LN_setext_cv		"additional verification"
-#define NID_setext_cv		606
-#define OBJ_setext_cv		OBJ_set_msgExt,8L
-
-#define SN_set_policy_root		"set-policy-root"
-#define NID_set_policy_root		607
-#define OBJ_set_policy_root		OBJ_set_policy,0L
-
-#define SN_setCext_hashedRoot		"setCext-hashedRoot"
-#define NID_setCext_hashedRoot		608
-#define OBJ_setCext_hashedRoot		OBJ_set_certExt,0L
-
-#define SN_setCext_certType		"setCext-certType"
-#define NID_setCext_certType		609
-#define OBJ_setCext_certType		OBJ_set_certExt,1L
-
-#define SN_setCext_merchData		"setCext-merchData"
-#define NID_setCext_merchData		610
-#define OBJ_setCext_merchData		OBJ_set_certExt,2L
-
-#define SN_setCext_cCertRequired		"setCext-cCertRequired"
-#define NID_setCext_cCertRequired		611
-#define OBJ_setCext_cCertRequired		OBJ_set_certExt,3L
-
-#define SN_setCext_tunneling		"setCext-tunneling"
-#define NID_setCext_tunneling		612
-#define OBJ_setCext_tunneling		OBJ_set_certExt,4L
-
-#define SN_setCext_setExt		"setCext-setExt"
-#define NID_setCext_setExt		613
-#define OBJ_setCext_setExt		OBJ_set_certExt,5L
-
-#define SN_setCext_setQualf		"setCext-setQualf"
-#define NID_setCext_setQualf		614
-#define OBJ_setCext_setQualf		OBJ_set_certExt,6L
-
-#define SN_setCext_PGWYcapabilities		"setCext-PGWYcapabilities"
-#define NID_setCext_PGWYcapabilities		615
-#define OBJ_setCext_PGWYcapabilities		OBJ_set_certExt,7L
-
-#define SN_setCext_TokenIdentifier		"setCext-TokenIdentifier"
-#define NID_setCext_TokenIdentifier		616
-#define OBJ_setCext_TokenIdentifier		OBJ_set_certExt,8L
-
-#define SN_setCext_Track2Data		"setCext-Track2Data"
-#define NID_setCext_Track2Data		617
-#define OBJ_setCext_Track2Data		OBJ_set_certExt,9L
-
-#define SN_setCext_TokenType		"setCext-TokenType"
-#define NID_setCext_TokenType		618
-#define OBJ_setCext_TokenType		OBJ_set_certExt,10L
-
-#define SN_setCext_IssuerCapabilities		"setCext-IssuerCapabilities"
-#define NID_setCext_IssuerCapabilities		619
-#define OBJ_setCext_IssuerCapabilities		OBJ_set_certExt,11L
-
-#define SN_setAttr_Cert		"setAttr-Cert"
-#define NID_setAttr_Cert		620
-#define OBJ_setAttr_Cert		OBJ_set_attr,0L
-
-#define SN_setAttr_PGWYcap		"setAttr-PGWYcap"
-#define LN_setAttr_PGWYcap		"payment gateway capabilities"
-#define NID_setAttr_PGWYcap		621
-#define OBJ_setAttr_PGWYcap		OBJ_set_attr,1L
-
-#define SN_setAttr_TokenType		"setAttr-TokenType"
-#define NID_setAttr_TokenType		622
-#define OBJ_setAttr_TokenType		OBJ_set_attr,2L
-
-#define SN_setAttr_IssCap		"setAttr-IssCap"
-#define LN_setAttr_IssCap		"issuer capabilities"
-#define NID_setAttr_IssCap		623
-#define OBJ_setAttr_IssCap		OBJ_set_attr,3L
-
-#define SN_set_rootKeyThumb		"set-rootKeyThumb"
-#define NID_set_rootKeyThumb		624
-#define OBJ_set_rootKeyThumb		OBJ_setAttr_Cert,0L
-
-#define SN_set_addPolicy		"set-addPolicy"
-#define NID_set_addPolicy		625
-#define OBJ_set_addPolicy		OBJ_setAttr_Cert,1L
-
-#define SN_setAttr_Token_EMV		"setAttr-Token-EMV"
-#define NID_setAttr_Token_EMV		626
-#define OBJ_setAttr_Token_EMV		OBJ_setAttr_TokenType,1L
-
-#define SN_setAttr_Token_B0Prime		"setAttr-Token-B0Prime"
-#define NID_setAttr_Token_B0Prime		627
-#define OBJ_setAttr_Token_B0Prime		OBJ_setAttr_TokenType,2L
-
-#define SN_setAttr_IssCap_CVM		"setAttr-IssCap-CVM"
-#define NID_setAttr_IssCap_CVM		628
-#define OBJ_setAttr_IssCap_CVM		OBJ_setAttr_IssCap,3L
-
-#define SN_setAttr_IssCap_T2		"setAttr-IssCap-T2"
-#define NID_setAttr_IssCap_T2		629
-#define OBJ_setAttr_IssCap_T2		OBJ_setAttr_IssCap,4L
-
-#define SN_setAttr_IssCap_Sig		"setAttr-IssCap-Sig"
-#define NID_setAttr_IssCap_Sig		630
-#define OBJ_setAttr_IssCap_Sig		OBJ_setAttr_IssCap,5L
-
-#define SN_setAttr_GenCryptgrm		"setAttr-GenCryptgrm"
-#define LN_setAttr_GenCryptgrm		"generate cryptogram"
-#define NID_setAttr_GenCryptgrm		631
-#define OBJ_setAttr_GenCryptgrm		OBJ_setAttr_IssCap_CVM,1L
-
-#define SN_setAttr_T2Enc		"setAttr-T2Enc"
-#define LN_setAttr_T2Enc		"encrypted track 2"
-#define NID_setAttr_T2Enc		632
-#define OBJ_setAttr_T2Enc		OBJ_setAttr_IssCap_T2,1L
-
-#define SN_setAttr_T2cleartxt		"setAttr-T2cleartxt"
-#define LN_setAttr_T2cleartxt		"cleartext track 2"
-#define NID_setAttr_T2cleartxt		633
-#define OBJ_setAttr_T2cleartxt		OBJ_setAttr_IssCap_T2,2L
-
-#define SN_setAttr_TokICCsig		"setAttr-TokICCsig"
-#define LN_setAttr_TokICCsig		"ICC or token signature"
-#define NID_setAttr_TokICCsig		634
-#define OBJ_setAttr_TokICCsig		OBJ_setAttr_IssCap_Sig,1L
-
-#define SN_setAttr_SecDevSig		"setAttr-SecDevSig"
-#define LN_setAttr_SecDevSig		"secure device signature"
-#define NID_setAttr_SecDevSig		635
-#define OBJ_setAttr_SecDevSig		OBJ_setAttr_IssCap_Sig,2L
-
-#define SN_set_brand_IATA_ATA		"set-brand-IATA-ATA"
-#define NID_set_brand_IATA_ATA		636
-#define OBJ_set_brand_IATA_ATA		OBJ_set_brand,1L
-
-#define SN_set_brand_Diners		"set-brand-Diners"
-#define NID_set_brand_Diners		637
-#define OBJ_set_brand_Diners		OBJ_set_brand,30L
-
-#define SN_set_brand_AmericanExpress		"set-brand-AmericanExpress"
-#define NID_set_brand_AmericanExpress		638
-#define OBJ_set_brand_AmericanExpress		OBJ_set_brand,34L
-
-#define SN_set_brand_JCB		"set-brand-JCB"
-#define NID_set_brand_JCB		639
-#define OBJ_set_brand_JCB		OBJ_set_brand,35L
-
-#define SN_set_brand_Visa		"set-brand-Visa"
-#define NID_set_brand_Visa		640
-#define OBJ_set_brand_Visa		OBJ_set_brand,4L
-
-#define SN_set_brand_MasterCard		"set-brand-MasterCard"
-#define NID_set_brand_MasterCard		641
-#define OBJ_set_brand_MasterCard		OBJ_set_brand,5L
-
-#define SN_set_brand_Novus		"set-brand-Novus"
-#define NID_set_brand_Novus		642
-#define OBJ_set_brand_Novus		OBJ_set_brand,6011L
-
-#define SN_des_cdmf		"DES-CDMF"
-#define LN_des_cdmf		"des-cdmf"
-#define NID_des_cdmf		643
-#define OBJ_des_cdmf		OBJ_rsadsi,3L,10L
-
-#define SN_rsaOAEPEncryptionSET		"rsaOAEPEncryptionSET"
-#define NID_rsaOAEPEncryptionSET		644
-#define OBJ_rsaOAEPEncryptionSET		OBJ_rsadsi,1L,1L,6L
-
-#define SN_ipsec3		"Oakley-EC2N-3"
-#define LN_ipsec3		"ipsec3"
-#define NID_ipsec3		749
-
-#define SN_ipsec4		"Oakley-EC2N-4"
-#define LN_ipsec4		"ipsec4"
-#define NID_ipsec4		750
-
-#define SN_whirlpool		"whirlpool"
-#define NID_whirlpool		804
-#define OBJ_whirlpool		OBJ_iso,0L,10118L,3L,0L,55L
-
-#define SN_cryptopro		"cryptopro"
-#define NID_cryptopro		805
-#define OBJ_cryptopro		OBJ_member_body,643L,2L,2L
-
-#define SN_cryptocom		"cryptocom"
-#define NID_cryptocom		806
-#define OBJ_cryptocom		OBJ_member_body,643L,2L,9L
-
-#define SN_id_GostR3411_94_with_GostR3410_2001		"id-GostR3411-94-with-GostR3410-2001"
-#define LN_id_GostR3411_94_with_GostR3410_2001		"GOST R 34.11-94 with GOST R 34.10-2001"
-#define NID_id_GostR3411_94_with_GostR3410_2001		807
-#define OBJ_id_GostR3411_94_with_GostR3410_2001		OBJ_cryptopro,3L
-
-#define SN_id_GostR3411_94_with_GostR3410_94		"id-GostR3411-94-with-GostR3410-94"
-#define LN_id_GostR3411_94_with_GostR3410_94		"GOST R 34.11-94 with GOST R 34.10-94"
-#define NID_id_GostR3411_94_with_GostR3410_94		808
-#define OBJ_id_GostR3411_94_with_GostR3410_94		OBJ_cryptopro,4L
-
-#define SN_id_GostR3411_94		"md_gost94"
-#define LN_id_GostR3411_94		"GOST R 34.11-94"
-#define NID_id_GostR3411_94		809
-#define OBJ_id_GostR3411_94		OBJ_cryptopro,9L
-
-#define SN_id_HMACGostR3411_94		"id-HMACGostR3411-94"
-#define LN_id_HMACGostR3411_94		"HMAC GOST 34.11-94"
-#define NID_id_HMACGostR3411_94		810
-#define OBJ_id_HMACGostR3411_94		OBJ_cryptopro,10L
-
-#define SN_id_GostR3410_2001		"gost2001"
-#define LN_id_GostR3410_2001		"GOST R 34.10-2001"
-#define NID_id_GostR3410_2001		811
-#define OBJ_id_GostR3410_2001		OBJ_cryptopro,19L
-
-#define SN_id_GostR3410_94		"gost94"
-#define LN_id_GostR3410_94		"GOST R 34.10-94"
-#define NID_id_GostR3410_94		812
-#define OBJ_id_GostR3410_94		OBJ_cryptopro,20L
-
-#define SN_id_Gost28147_89		"gost89"
-#define LN_id_Gost28147_89		"GOST 28147-89"
-#define NID_id_Gost28147_89		813
-#define OBJ_id_Gost28147_89		OBJ_cryptopro,21L
-
-#define SN_gost89_cnt		"gost89-cnt"
-#define NID_gost89_cnt		814
-
-#define SN_id_Gost28147_89_MAC		"gost-mac"
-#define LN_id_Gost28147_89_MAC		"GOST 28147-89 MAC"
-#define NID_id_Gost28147_89_MAC		815
-#define OBJ_id_Gost28147_89_MAC		OBJ_cryptopro,22L
-
-#define SN_id_GostR3411_94_prf		"prf-gostr3411-94"
-#define LN_id_GostR3411_94_prf		"GOST R 34.11-94 PRF"
-#define NID_id_GostR3411_94_prf		816
-#define OBJ_id_GostR3411_94_prf		OBJ_cryptopro,23L
-
-#define SN_id_GostR3410_2001DH		"id-GostR3410-2001DH"
-#define LN_id_GostR3410_2001DH		"GOST R 34.10-2001 DH"
-#define NID_id_GostR3410_2001DH		817
-#define OBJ_id_GostR3410_2001DH		OBJ_cryptopro,98L
-
-#define SN_id_GostR3410_94DH		"id-GostR3410-94DH"
-#define LN_id_GostR3410_94DH		"GOST R 34.10-94 DH"
-#define NID_id_GostR3410_94DH		818
-#define OBJ_id_GostR3410_94DH		OBJ_cryptopro,99L
-
-#define SN_id_Gost28147_89_CryptoPro_KeyMeshing		"id-Gost28147-89-CryptoPro-KeyMeshing"
-#define NID_id_Gost28147_89_CryptoPro_KeyMeshing		819
-#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing		OBJ_cryptopro,14L,1L
-
-#define SN_id_Gost28147_89_None_KeyMeshing		"id-Gost28147-89-None-KeyMeshing"
-#define NID_id_Gost28147_89_None_KeyMeshing		820
-#define OBJ_id_Gost28147_89_None_KeyMeshing		OBJ_cryptopro,14L,0L
-
-#define SN_id_GostR3411_94_TestParamSet		"id-GostR3411-94-TestParamSet"
-#define NID_id_GostR3411_94_TestParamSet		821
-#define OBJ_id_GostR3411_94_TestParamSet		OBJ_cryptopro,30L,0L
-
-#define SN_id_GostR3411_94_CryptoProParamSet		"id-GostR3411-94-CryptoProParamSet"
-#define NID_id_GostR3411_94_CryptoProParamSet		822
-#define OBJ_id_GostR3411_94_CryptoProParamSet		OBJ_cryptopro,30L,1L
-
-#define SN_id_Gost28147_89_TestParamSet		"id-Gost28147-89-TestParamSet"
-#define NID_id_Gost28147_89_TestParamSet		823
-#define OBJ_id_Gost28147_89_TestParamSet		OBJ_cryptopro,31L,0L
-
-#define SN_id_Gost28147_89_CryptoPro_A_ParamSet		"id-Gost28147-89-CryptoPro-A-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_A_ParamSet		824
-#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet		OBJ_cryptopro,31L,1L
-
-#define SN_id_Gost28147_89_CryptoPro_B_ParamSet		"id-Gost28147-89-CryptoPro-B-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_B_ParamSet		825
-#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet		OBJ_cryptopro,31L,2L
-
-#define SN_id_Gost28147_89_CryptoPro_C_ParamSet		"id-Gost28147-89-CryptoPro-C-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_C_ParamSet		826
-#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet		OBJ_cryptopro,31L,3L
-
-#define SN_id_Gost28147_89_CryptoPro_D_ParamSet		"id-Gost28147-89-CryptoPro-D-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_D_ParamSet		827
-#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet		OBJ_cryptopro,31L,4L
-
-#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
-#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		OBJ_cryptopro,31L,5L
-
-#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
-#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		OBJ_cryptopro,31L,6L
-
-#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		"id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
-#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		OBJ_cryptopro,31L,7L
-
-#define SN_id_GostR3410_94_TestParamSet		"id-GostR3410-94-TestParamSet"
-#define NID_id_GostR3410_94_TestParamSet		831
-#define OBJ_id_GostR3410_94_TestParamSet		OBJ_cryptopro,32L,0L
-
-#define SN_id_GostR3410_94_CryptoPro_A_ParamSet		"id-GostR3410-94-CryptoPro-A-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_A_ParamSet		832
-#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet		OBJ_cryptopro,32L,2L
-
-#define SN_id_GostR3410_94_CryptoPro_B_ParamSet		"id-GostR3410-94-CryptoPro-B-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_B_ParamSet		833
-#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet		OBJ_cryptopro,32L,3L
-
-#define SN_id_GostR3410_94_CryptoPro_C_ParamSet		"id-GostR3410-94-CryptoPro-C-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_C_ParamSet		834
-#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet		OBJ_cryptopro,32L,4L
-
-#define SN_id_GostR3410_94_CryptoPro_D_ParamSet		"id-GostR3410-94-CryptoPro-D-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_D_ParamSet		835
-#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet		OBJ_cryptopro,32L,5L
-
-#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet		"id-GostR3410-94-CryptoPro-XchA-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet		836
-#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet		OBJ_cryptopro,33L,1L
-
-#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet		"id-GostR3410-94-CryptoPro-XchB-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet		837
-#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet		OBJ_cryptopro,33L,2L
-
-#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet		"id-GostR3410-94-CryptoPro-XchC-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet		838
-#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet		OBJ_cryptopro,33L,3L
-
-#define SN_id_GostR3410_2001_TestParamSet		"id-GostR3410-2001-TestParamSet"
-#define NID_id_GostR3410_2001_TestParamSet		839
-#define OBJ_id_GostR3410_2001_TestParamSet		OBJ_cryptopro,35L,0L
-
-#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet		"id-GostR3410-2001-CryptoPro-A-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet		840
-#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet		OBJ_cryptopro,35L,1L
-
-#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet		"id-GostR3410-2001-CryptoPro-B-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet		841
-#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet		OBJ_cryptopro,35L,2L
-
-#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet		"id-GostR3410-2001-CryptoPro-C-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet		842
-#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet		OBJ_cryptopro,35L,3L
-
-#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet		"id-GostR3410-2001-CryptoPro-XchA-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
-#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet		OBJ_cryptopro,36L,0L
-
-#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet		"id-GostR3410-2001-CryptoPro-XchB-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
-#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet		OBJ_cryptopro,36L,1L
-
-#define SN_id_GostR3410_94_a		"id-GostR3410-94-a"
-#define NID_id_GostR3410_94_a		845
-#define OBJ_id_GostR3410_94_a		OBJ_id_GostR3410_94,1L
-
-#define SN_id_GostR3410_94_aBis		"id-GostR3410-94-aBis"
-#define NID_id_GostR3410_94_aBis		846
-#define OBJ_id_GostR3410_94_aBis		OBJ_id_GostR3410_94,2L
-
-#define SN_id_GostR3410_94_b		"id-GostR3410-94-b"
-#define NID_id_GostR3410_94_b		847
-#define OBJ_id_GostR3410_94_b		OBJ_id_GostR3410_94,3L
-
-#define SN_id_GostR3410_94_bBis		"id-GostR3410-94-bBis"
-#define NID_id_GostR3410_94_bBis		848
-#define OBJ_id_GostR3410_94_bBis		OBJ_id_GostR3410_94,4L
-
-#define SN_id_Gost28147_89_cc		"id-Gost28147-89-cc"
-#define LN_id_Gost28147_89_cc		"GOST 28147-89 Cryptocom ParamSet"
-#define NID_id_Gost28147_89_cc		849
-#define OBJ_id_Gost28147_89_cc		OBJ_cryptocom,1L,6L,1L
-
-#define SN_id_GostR3410_94_cc		"gost94cc"
-#define LN_id_GostR3410_94_cc		"GOST 34.10-94 Cryptocom"
-#define NID_id_GostR3410_94_cc		850
-#define OBJ_id_GostR3410_94_cc		OBJ_cryptocom,1L,5L,3L
-
-#define SN_id_GostR3410_2001_cc		"gost2001cc"
-#define LN_id_GostR3410_2001_cc		"GOST 34.10-2001 Cryptocom"
-#define NID_id_GostR3410_2001_cc		851
-#define OBJ_id_GostR3410_2001_cc		OBJ_cryptocom,1L,5L,4L
-
-#define SN_id_GostR3411_94_with_GostR3410_94_cc		"id-GostR3411-94-with-GostR3410-94-cc"
-#define LN_id_GostR3411_94_with_GostR3410_94_cc		"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
-#define NID_id_GostR3411_94_with_GostR3410_94_cc		852
-#define OBJ_id_GostR3411_94_with_GostR3410_94_cc		OBJ_cryptocom,1L,3L,3L
-
-#define SN_id_GostR3411_94_with_GostR3410_2001_cc		"id-GostR3411-94-with-GostR3410-2001-cc"
-#define LN_id_GostR3411_94_with_GostR3410_2001_cc		"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
-#define NID_id_GostR3411_94_with_GostR3410_2001_cc		853
-#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc		OBJ_cryptocom,1L,3L,4L
-
-#define SN_id_GostR3410_2001_ParamSet_cc		"id-GostR3410-2001-ParamSet-cc"
-#define LN_id_GostR3410_2001_ParamSet_cc		"GOST R 3410-2001 Parameter Set Cryptocom"
-#define NID_id_GostR3410_2001_ParamSet_cc		854
-#define OBJ_id_GostR3410_2001_ParamSet_cc		OBJ_cryptocom,1L,8L,1L
-
-#define SN_camellia_128_cbc		"CAMELLIA-128-CBC"
-#define LN_camellia_128_cbc		"camellia-128-cbc"
-#define NID_camellia_128_cbc		751
-#define OBJ_camellia_128_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,2L
-
-#define SN_camellia_192_cbc		"CAMELLIA-192-CBC"
-#define LN_camellia_192_cbc		"camellia-192-cbc"
-#define NID_camellia_192_cbc		752
-#define OBJ_camellia_192_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,3L
-
-#define SN_camellia_256_cbc		"CAMELLIA-256-CBC"
-#define LN_camellia_256_cbc		"camellia-256-cbc"
-#define NID_camellia_256_cbc		753
-#define OBJ_camellia_256_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,4L
-
-#define SN_id_camellia128_wrap		"id-camellia128-wrap"
-#define NID_id_camellia128_wrap		907
-#define OBJ_id_camellia128_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,2L
-
-#define SN_id_camellia192_wrap		"id-camellia192-wrap"
-#define NID_id_camellia192_wrap		908
-#define OBJ_id_camellia192_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,3L
-
-#define SN_id_camellia256_wrap		"id-camellia256-wrap"
-#define NID_id_camellia256_wrap		909
-#define OBJ_id_camellia256_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,4L
-
-#define OBJ_ntt_ds		0L,3L,4401L,5L
-
-#define OBJ_camellia		OBJ_ntt_ds,3L,1L,9L
-
-#define SN_camellia_128_ecb		"CAMELLIA-128-ECB"
-#define LN_camellia_128_ecb		"camellia-128-ecb"
-#define NID_camellia_128_ecb		754
-#define OBJ_camellia_128_ecb		OBJ_camellia,1L
-
-#define SN_camellia_128_ofb128		"CAMELLIA-128-OFB"
-#define LN_camellia_128_ofb128		"camellia-128-ofb"
-#define NID_camellia_128_ofb128		766
-#define OBJ_camellia_128_ofb128		OBJ_camellia,3L
-
-#define SN_camellia_128_cfb128		"CAMELLIA-128-CFB"
-#define LN_camellia_128_cfb128		"camellia-128-cfb"
-#define NID_camellia_128_cfb128		757
-#define OBJ_camellia_128_cfb128		OBJ_camellia,4L
-
-#define SN_camellia_192_ecb		"CAMELLIA-192-ECB"
-#define LN_camellia_192_ecb		"camellia-192-ecb"
-#define NID_camellia_192_ecb		755
-#define OBJ_camellia_192_ecb		OBJ_camellia,21L
-
-#define SN_camellia_192_ofb128		"CAMELLIA-192-OFB"
-#define LN_camellia_192_ofb128		"camellia-192-ofb"
-#define NID_camellia_192_ofb128		767
-#define OBJ_camellia_192_ofb128		OBJ_camellia,23L
-
-#define SN_camellia_192_cfb128		"CAMELLIA-192-CFB"
-#define LN_camellia_192_cfb128		"camellia-192-cfb"
-#define NID_camellia_192_cfb128		758
-#define OBJ_camellia_192_cfb128		OBJ_camellia,24L
-
-#define SN_camellia_256_ecb		"CAMELLIA-256-ECB"
-#define LN_camellia_256_ecb		"camellia-256-ecb"
-#define NID_camellia_256_ecb		756
-#define OBJ_camellia_256_ecb		OBJ_camellia,41L
-
-#define SN_camellia_256_ofb128		"CAMELLIA-256-OFB"
-#define LN_camellia_256_ofb128		"camellia-256-ofb"
-#define NID_camellia_256_ofb128		768
-#define OBJ_camellia_256_ofb128		OBJ_camellia,43L
-
-#define SN_camellia_256_cfb128		"CAMELLIA-256-CFB"
-#define LN_camellia_256_cfb128		"camellia-256-cfb"
-#define NID_camellia_256_cfb128		759
-#define OBJ_camellia_256_cfb128		OBJ_camellia,44L
-
-#define SN_camellia_128_cfb1		"CAMELLIA-128-CFB1"
-#define LN_camellia_128_cfb1		"camellia-128-cfb1"
-#define NID_camellia_128_cfb1		760
-
-#define SN_camellia_192_cfb1		"CAMELLIA-192-CFB1"
-#define LN_camellia_192_cfb1		"camellia-192-cfb1"
-#define NID_camellia_192_cfb1		761
-
-#define SN_camellia_256_cfb1		"CAMELLIA-256-CFB1"
-#define LN_camellia_256_cfb1		"camellia-256-cfb1"
-#define NID_camellia_256_cfb1		762
-
-#define SN_camellia_128_cfb8		"CAMELLIA-128-CFB8"
-#define LN_camellia_128_cfb8		"camellia-128-cfb8"
-#define NID_camellia_128_cfb8		763
-
-#define SN_camellia_192_cfb8		"CAMELLIA-192-CFB8"
-#define LN_camellia_192_cfb8		"camellia-192-cfb8"
-#define NID_camellia_192_cfb8		764
-
-#define SN_camellia_256_cfb8		"CAMELLIA-256-CFB8"
-#define LN_camellia_256_cfb8		"camellia-256-cfb8"
-#define NID_camellia_256_cfb8		765
-
-#define SN_kisa		"KISA"
-#define LN_kisa		"kisa"
-#define NID_kisa		773
-#define OBJ_kisa		OBJ_member_body,410L,200004L
-
-#define SN_seed_ecb		"SEED-ECB"
-#define LN_seed_ecb		"seed-ecb"
-#define NID_seed_ecb		776
-#define OBJ_seed_ecb		OBJ_kisa,1L,3L
-
-#define SN_seed_cbc		"SEED-CBC"
-#define LN_seed_cbc		"seed-cbc"
-#define NID_seed_cbc		777
-#define OBJ_seed_cbc		OBJ_kisa,1L,4L
-
-#define SN_seed_cfb128		"SEED-CFB"
-#define LN_seed_cfb128		"seed-cfb"
-#define NID_seed_cfb128		779
-#define OBJ_seed_cfb128		OBJ_kisa,1L,5L
-
-#define SN_seed_ofb128		"SEED-OFB"
-#define LN_seed_ofb128		"seed-ofb"
-#define NID_seed_ofb128		778
-#define OBJ_seed_ofb128		OBJ_kisa,1L,6L
-
-#define SN_hmac		"HMAC"
-#define LN_hmac		"hmac"
-#define NID_hmac		855
-
-#define SN_cmac		"CMAC"
-#define LN_cmac		"cmac"
-#define NID_cmac		894
-
-#define SN_rc4_hmac_md5		"RC4-HMAC-MD5"
-#define LN_rc4_hmac_md5		"rc4-hmac-md5"
-#define NID_rc4_hmac_md5		915
-
-#define SN_aes_128_cbc_hmac_sha1		"AES-128-CBC-HMAC-SHA1"
-#define LN_aes_128_cbc_hmac_sha1		"aes-128-cbc-hmac-sha1"
-#define NID_aes_128_cbc_hmac_sha1		916
-
-#define SN_aes_192_cbc_hmac_sha1		"AES-192-CBC-HMAC-SHA1"
-#define LN_aes_192_cbc_hmac_sha1		"aes-192-cbc-hmac-sha1"
-#define NID_aes_192_cbc_hmac_sha1		917
-
-#define SN_aes_256_cbc_hmac_sha1		"AES-256-CBC-HMAC-SHA1"
-#define LN_aes_256_cbc_hmac_sha1		"aes-256-cbc-hmac-sha1"
-#define NID_aes_256_cbc_hmac_sha1		918
-
-#define SN_dhpublicnumber		"dhpublicnumber"
-#define LN_dhpublicnumber		"X9.42 DH"
-#define NID_dhpublicnumber		920
-#define OBJ_dhpublicnumber		OBJ_ISO_US,10046L,2L,1L
-
-#define SN_brainpoolP160r1		"brainpoolP160r1"
-#define NID_brainpoolP160r1		921
-#define OBJ_brainpoolP160r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
-
-#define SN_brainpoolP160t1		"brainpoolP160t1"
-#define NID_brainpoolP160t1		922
-#define OBJ_brainpoolP160t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
-
-#define SN_brainpoolP192r1		"brainpoolP192r1"
-#define NID_brainpoolP192r1		923
-#define OBJ_brainpoolP192r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
-
-#define SN_brainpoolP192t1		"brainpoolP192t1"
-#define NID_brainpoolP192t1		924
-#define OBJ_brainpoolP192t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
-
-#define SN_brainpoolP224r1		"brainpoolP224r1"
-#define NID_brainpoolP224r1		925
-#define OBJ_brainpoolP224r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
-
-#define SN_brainpoolP224t1		"brainpoolP224t1"
-#define NID_brainpoolP224t1		926
-#define OBJ_brainpoolP224t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
-
-#define SN_brainpoolP256r1		"brainpoolP256r1"
-#define NID_brainpoolP256r1		927
-#define OBJ_brainpoolP256r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
-
-#define SN_brainpoolP256t1		"brainpoolP256t1"
-#define NID_brainpoolP256t1		928
-#define OBJ_brainpoolP256t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
-
-#define SN_brainpoolP320r1		"brainpoolP320r1"
-#define NID_brainpoolP320r1		929
-#define OBJ_brainpoolP320r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
-
-#define SN_brainpoolP320t1		"brainpoolP320t1"
-#define NID_brainpoolP320t1		930
-#define OBJ_brainpoolP320t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
-
-#define SN_brainpoolP384r1		"brainpoolP384r1"
-#define NID_brainpoolP384r1		931
-#define OBJ_brainpoolP384r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
-
-#define SN_brainpoolP384t1		"brainpoolP384t1"
-#define NID_brainpoolP384t1		932
-#define OBJ_brainpoolP384t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
-
-#define SN_brainpoolP512r1		"brainpoolP512r1"
-#define NID_brainpoolP512r1		933
-#define OBJ_brainpoolP512r1		1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
-
-#define SN_brainpoolP512t1		"brainpoolP512t1"
-#define NID_brainpoolP512t1		934
-#define OBJ_brainpoolP512t1		1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
-
-#define OBJ_x9_63_scheme		1L,3L,133L,16L,840L,63L,0L
-
-#define OBJ_secg_scheme		OBJ_certicom_arc,1L
-
-#define SN_dhSinglePass_stdDH_sha1kdf_scheme		"dhSinglePass-stdDH-sha1kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha1kdf_scheme		936
-#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme		OBJ_x9_63_scheme,2L
-
-#define SN_dhSinglePass_stdDH_sha224kdf_scheme		"dhSinglePass-stdDH-sha224kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha224kdf_scheme		937
-#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme		OBJ_secg_scheme,11L,0L
-
-#define SN_dhSinglePass_stdDH_sha256kdf_scheme		"dhSinglePass-stdDH-sha256kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha256kdf_scheme		938
-#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme		OBJ_secg_scheme,11L,1L
-
-#define SN_dhSinglePass_stdDH_sha384kdf_scheme		"dhSinglePass-stdDH-sha384kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha384kdf_scheme		939
-#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme		OBJ_secg_scheme,11L,2L
-
-#define SN_dhSinglePass_stdDH_sha512kdf_scheme		"dhSinglePass-stdDH-sha512kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha512kdf_scheme		940
-#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme		OBJ_secg_scheme,11L,3L
-
-#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme		"dhSinglePass-cofactorDH-sha1kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme		941
-#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme		OBJ_x9_63_scheme,3L
-
-#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme		"dhSinglePass-cofactorDH-sha224kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme		942
-#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme		OBJ_secg_scheme,14L,0L
-
-#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme		"dhSinglePass-cofactorDH-sha256kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme		943
-#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme		OBJ_secg_scheme,14L,1L
-
-#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme		"dhSinglePass-cofactorDH-sha384kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme		944
-#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme		OBJ_secg_scheme,14L,2L
-
-#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme		"dhSinglePass-cofactorDH-sha512kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme		945
-#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme		OBJ_secg_scheme,14L,3L
-
-#define SN_dh_std_kdf		"dh-std-kdf"
-#define NID_dh_std_kdf		946
-
-#define SN_dh_cofactor_kdf		"dh-cofactor-kdf"
-#define NID_dh_cofactor_kdf		947
-
-#define SN_x25519		"X25519"
-#define LN_x25519		"x25519"
-#define NID_x25519		948
-
+#include "nid.h"
diff --git a/src/include/openssl/opensslfeatures.h b/src/include/openssl/opensslconf.h
similarity index 92%
rename from src/include/openssl/opensslfeatures.h
rename to src/include/openssl/opensslconf.h
index c3f97d5..bf65fc3 100644
--- a/src/include/openssl/opensslfeatures.h
+++ b/src/include/openssl/opensslconf.h
@@ -15,8 +15,8 @@
 /* This header is provided in order to make compiling against code that expects
    OpenSSL easier. */
 
-#ifndef OPENSSL_HEADER_OPENSSLFEATURES_H
-#define OPENSSL_HEADER_OPENSSLFEATURES_H
+#ifndef OPENSSL_HEADER_OPENSSLCONF_H
+#define OPENSSL_HEADER_OPENSSLCONF_H
 
 
 #define OPENSSL_NO_BF
@@ -57,4 +57,4 @@
 #define OPENSSL_NO_WHIRLPOOL
 
 
-#endif  /* OPENSSL_HEADER_OPENSSLFEATURES_H */
+#endif  /* OPENSSL_HEADER_OPENSSLCONF_H */
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index a6687a6..b899d9f 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -120,6 +120,7 @@
 #define PEM_STRING_RSA_PUBLIC	"RSA PUBLIC KEY"
 #define PEM_STRING_DSA		"DSA PRIVATE KEY"
 #define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
+#define PEM_STRING_EC "EC PRIVATE KEY"
 #define PEM_STRING_PKCS7	"PKCS7"
 #define PEM_STRING_PKCS7_SIGNED	"PKCS #7 SIGNED DATA"
 #define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
@@ -129,7 +130,6 @@
 #define PEM_STRING_DSAPARAMS	"DSA PARAMETERS"
 #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
 #define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
-#define PEM_STRING_PARAMETERS	"PARAMETERS"
 #define PEM_STRING_CMS		"CMS"
 
   /* Note that this structure is initialised by PEM_SealInit and cleaned up
@@ -477,10 +477,6 @@
 
 OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u);
 
-OPENSSL_EXPORT EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
-OPENSSL_EXPORT int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
-
-
 OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
 OPENSSL_EXPORT EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
 OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index 6b51f85..28cf6ac 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -139,12 +139,16 @@
 OPENSSL_EXPORT void PKCS12_PBE_add(void);
 
 /* d2i_PKCS12 is a dummy function that copies |*ber_bytes| into a
- * |PKCS12| structure. The |out_p12| argument must be NULL. On exit,
+ * |PKCS12| structure. The |out_p12| argument should be NULL(✝). On exit,
  * |*ber_bytes| will be advanced by |ber_len|. It returns a fresh |PKCS12|
  * structure or NULL on error.
  *
  * Note: unlike other d2i functions, |d2i_PKCS12| will always consume |ber_len|
- * bytes.*/
+ * bytes.
+ *
+ * (✝) If |out_p12| is not NULL and the function is successful, |*out_p12| will
+ * be freed if not NULL itself and the result will be written to |*out_p12|.
+ * New code should not depend on this. */
 OPENSSL_EXPORT PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes,
                                   size_t ber_len);
 
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 3a8e357..322249c 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -62,6 +62,12 @@
 OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd);
 #endif
 
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+/* RAND_reset_for_fuzzing resets the fuzzer-only deterministic RNG. This
+ * function is only defined in the fuzzer-only build configuration. */
+OPENSSL_EXPORT void RAND_reset_for_fuzzing(void);
+#endif
+
 
 /* Deprecated functions */
 
@@ -75,6 +81,9 @@
 /* RAND_load_file returns a nonnegative number. */
 OPENSSL_EXPORT int RAND_load_file(const char *path, long num);
 
+/* RAND_file_name returns NULL. */
+OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num);
+
 /* RAND_add does nothing. */
 OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
 
diff --git a/src/include/openssl/rc4.h b/src/include/openssl/rc4.h
index 0619cac..68af878 100644
--- a/src/include/openssl/rc4.h
+++ b/src/include/openssl/rc4.h
@@ -83,6 +83,12 @@
                         uint8_t *out);
 
 
+/* Deprecated functions. */
+
+/* RC4_options returns the string "rc4(ptr,int)". */
+OPENSSL_EXPORT const char *RC4_options(void);
+
+
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
diff --git a/src/crypto/dsa/internal.h b/src/include/openssl/ripemd.h
similarity index 67%
copy from src/crypto/dsa/internal.h
copy to src/include/openssl/ripemd.h
index ef99158..cf1e49e 100644
--- a/src/crypto/dsa/internal.h
+++ b/src/include/openssl/ripemd.h
@@ -52,27 +52,56 @@
  * 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.]
- *
- * The DSS routines are based on patches supplied by
- * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
+ * [including the GNU Public Licence.] */
 
-#ifndef OPENSSL_HEADER_DSA_INTERNAL_H
-#define OPENSSL_HEADER_DSA_INTERNAL_H
+#ifndef OPENSSL_HEADER_RIPEMD_H
+#define OPENSSL_HEADER_RIPEMD_H
 
 #include <openssl/base.h>
 
-#include <openssl/bn.h>
-#include <openssl/ex_data.h>
-
-#if defined(__cplusplus)
+#ifdef  __cplusplus
 extern "C" {
 #endif
 
 
+# define RIPEMD160_CBLOCK        64
+# define RIPEMD160_LBLOCK        (RIPEMD160_CBLOCK/4)
+# define RIPEMD160_DIGEST_LENGTH 20
+
+struct RIPEMD160state_st {
+  uint32_t h[5];
+  uint32_t Nl, Nh;
+  uint8_t data[RIPEMD160_CBLOCK];
+  unsigned num;
+};
+
+/* RIPEMD160_Init initialises |ctx| and returns one. */
+OPENSSL_EXPORT int RIPEMD160_Init(RIPEMD160_CTX *ctx);
+
+/* RIPEMD160_Update adds |len| bytes from |data| to |ctx| and returns one. */
+OPENSSL_EXPORT int RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data,
+                                   size_t len);
+
+/* RIPEMD160_Final adds the final padding to |ctx| and writes the resulting
+ * digest to |md|, which must have at least |RIPEMD160_DIGEST_LENGTH| bytes of
+ * space. It returns one. */
+OPENSSL_EXPORT int RIPEMD160_Final(uint8_t *md, RIPEMD160_CTX *ctx);
+
+/* RIPEMD160 writes the digest of |len| bytes from |data| to |out| and returns
+ * |out|. There must be at least |RIPEMD160_DIGEST_LENGTH| bytes of space in
+ * |out|. */
+OPENSSL_EXPORT uint8_t *RIPEMD160(const uint8_t *data, size_t len,
+                                  uint8_t *out);
+
+/* RIPEMD160_Transform is a low-level function that performs a single,
+ * RIPEMD160 block transformation using the state from |ctx| and 64 bytes from
+ * |block|. */
+OPENSSL_EXPORT void RIPEMD160_Transform(RIPEMD160_CTX *ctx,
+                                        const uint8_t *block);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
 #endif
 
-#endif  /* OPENSSL_HEADER_DSA_INTERNAL_H */
+#endif  /* OPENSSL_HEADER_RIPEMD_H */
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 304c555..83fdf16 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -59,7 +59,6 @@
 
 #include <openssl/base.h>
 
-#include <openssl/asn1.h>
 #include <openssl/engine.h>
 #include <openssl/ex_data.h>
 #include <openssl/thread.h>
@@ -322,6 +321,17 @@
                                                   const EVP_MD *mgf1Hash,
                                                   int sLen);
 
+/* RSA_padding_add_PKCS1_OAEP_mgf1 writes an OAEP padding of |from| to |to|
+ * with the given parameters and hash functions. If |md| is NULL then SHA-1 is
+ * used. If |mgf1md| is NULL then the value of |md| is used (which means SHA-1
+ * if that, in turn, is NULL).
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP_mgf1(
+    uint8_t *to, unsigned to_len, const uint8_t *from, unsigned from_len,
+    const uint8_t *param, unsigned param_len, const EVP_MD *md,
+    const EVP_MD *mgf1md);
+
 /* RSA_add_pkcs1_prefix builds a version of |msg| prefixed with the DigestInfo
  * header for the given hash function and sets |out_msg| to point to it. On
  * successful return, |*out_msg| may be allocated memory and, if so,
@@ -400,20 +410,20 @@
  * API, like a platform key store. */
 #define RSA_FLAG_OPAQUE 1
 
-/* RSA_FLAG_CACHE_PUBLIC causes a precomputed Montgomery context to be created,
- * on demand, for the public key operations. */
+/* Deprecated and ignored. */
 #define RSA_FLAG_CACHE_PUBLIC 2
 
-/* RSA_FLAG_CACHE_PRIVATE causes a precomputed Montgomery context to be
- * created, on demand, for the private key operations. */
+/* Deprecated and ignored. */
 #define RSA_FLAG_CACHE_PRIVATE 4
 
-/* RSA_FLAG_NO_BLINDING disables blinding of private operations. */
+/* RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a
+ * dangerous thing to do. It is deprecated and may be ignored in the future.
+ *
+ * This flag must be used if a key without the public exponent |e| is used for
+ * private key operations; avoid using such keys whenever possible. */
 #define RSA_FLAG_NO_BLINDING 8
 
-/* RSA_FLAG_EXT_PKEY means that private key operations will be handled by
- * |mod_exp| and that they do not depend on the private key components being
- * present: for example a key stored in external hardware. */
+/* RSA_FLAG_EXT_PKEY is deprecated and ignored. */
 #define RSA_FLAG_EXT_PKEY 0x20
 
 /* RSA_FLAG_SIGN_VER causes the |sign| and |verify| functions of |rsa_meth_st|
@@ -441,10 +451,10 @@
 
 /* d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len|
  * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |RSA| is allocated and the previous
+ * one is freed. On successful exit, |*inp| is advanced past the DER structure.
+ * It returns the result or NULL on error. */
 OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
 
 /* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
@@ -455,10 +465,10 @@
 
 /* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
  * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |RSA| is allocated and the previous
+ * one is freed. On successful exit, |*inp| is advanced past the DER structure.
+ * It returns the result or NULL on error. */
 OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
 
 /* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
@@ -467,14 +477,26 @@
  * not, or a negative value on error. */
 OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
 
-typedef struct rsa_pss_params_st {
-  X509_ALGOR *hashAlgorithm;
-  X509_ALGOR *maskGenAlgorithm;
-  ASN1_INTEGER *saltLength;
-  ASN1_INTEGER *trailerField;
-} RSA_PSS_PARAMS;
+/* RSA_padding_add_PKCS1_PSS acts like |RSA_padding_add_PKCS1_PSS_mgf1| but the
+ * |mgf1Hash| parameter of the latter is implicitly set to |Hash|. */
+OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM,
+                                             const uint8_t *mHash,
+                                             const EVP_MD *Hash, int sLen);
 
-DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+/* RSA_verify_PKCS1_PSS acts like |RSA_verify_PKCS1_PSS_mgf1| but the
+ * |mgf1Hash| parameter of the latter is implicitly set to |Hash|. */
+OPENSSL_EXPORT int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash,
+                                        const EVP_MD *Hash, const uint8_t *EM,
+                                        int sLen);
+
+/* RSA_padding_add_PKCS1_OAEP acts like |RSA_padding_add_PKCS1_OAEP_mgf1| but
+ * the |md| and |mgf1md| paramaters of the latter are implicitly set to NULL,
+ * which means SHA-1. */
+OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, unsigned to_len,
+                                              const uint8_t *from,
+                                              unsigned from_len,
+                                              const uint8_t *param,
+                                              unsigned param_len);
 
 
 struct rsa_meth_st {
@@ -491,6 +513,7 @@
   int (*sign)(int type, const uint8_t *m, unsigned int m_length,
               uint8_t *sigret, unsigned int *siglen, const RSA *rsa);
 
+  /* Ignored. Set this to NULL. */
   int (*verify)(int dtype, const uint8_t *m, unsigned int m_length,
                 const uint8_t *sigbuf, unsigned int siglen, const RSA *rsa);
 
@@ -503,6 +526,7 @@
 
   int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                  const uint8_t *in, size_t in_len, int padding);
+  /* Ignored. Set this to NULL. */
   int (*verify_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                     const uint8_t *in, size_t in_len, int padding);
 
@@ -521,8 +545,10 @@
   int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in,
                            size_t len);
 
-  int (*mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
-                 BN_CTX *ctx); /* Can be null */
+  /* mod_exp is deprecated and ignored. Set it to NULL. */
+  int (*mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+
+  /* bn_mod_exp is deprecated and ignored. Set it to NULL. */
   int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                     const BIGNUM *m, BN_CTX *ctx,
                     const BN_MONT_CTX *mont);
@@ -587,51 +613,51 @@
 }  /* extern C */
 #endif
 
-#define RSA_R_BAD_E_VALUE 100
-#define RSA_R_BAD_FIXED_HEADER_DECRYPT 101
-#define RSA_R_BAD_PAD_BYTE_COUNT 102
-#define RSA_R_BAD_RSA_PARAMETERS 103
-#define RSA_R_BAD_SIGNATURE 104
-#define RSA_R_BLOCK_TYPE_IS_NOT_01 105
-#define RSA_R_BN_NOT_INITIALIZED 106
-#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 107
-#define RSA_R_CRT_VALUES_INCORRECT 108
-#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 109
-#define RSA_R_DATA_TOO_LARGE 110
-#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 111
-#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 112
-#define RSA_R_DATA_TOO_SMALL 113
-#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 114
-#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 115
-#define RSA_R_D_E_NOT_CONGRUENT_TO_1 116
-#define RSA_R_EMPTY_PUBLIC_KEY 117
-#define RSA_R_FIRST_OCTET_INVALID 118
-#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 119
-#define RSA_R_INTERNAL_ERROR 120
-#define RSA_R_INVALID_MESSAGE_LENGTH 121
-#define RSA_R_KEY_SIZE_TOO_SMALL 122
-#define RSA_R_LAST_OCTET_INVALID 123
-#define RSA_R_MODULUS_TOO_LARGE 124
-#define RSA_R_NO_PUBLIC_EXPONENT 125
-#define RSA_R_NULL_BEFORE_BLOCK_MISSING 126
-#define RSA_R_N_NOT_EQUAL_P_Q 127
-#define RSA_R_OAEP_DECODING_ERROR 128
-#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 129
-#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 130
-#define RSA_R_PADDING_CHECK_FAILED 131
-#define RSA_R_PKCS_DECODING_ERROR 132
-#define RSA_R_SLEN_CHECK_FAILED 133
-#define RSA_R_SLEN_RECOVERY_FAILED 134
-#define RSA_R_TOO_LONG 135
-#define RSA_R_TOO_MANY_ITERATIONS 136
-#define RSA_R_UNKNOWN_ALGORITHM_TYPE 137
-#define RSA_R_UNKNOWN_PADDING_TYPE 138
-#define RSA_R_VALUE_MISSING 139
-#define RSA_R_WRONG_SIGNATURE_LENGTH 140
-#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 141
-#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 142
-#define RSA_R_BAD_ENCODING 143
-#define RSA_R_ENCODE_ERROR 144
-#define RSA_R_BAD_VERSION 145
+#define RSA_R_BAD_ENCODING 100
+#define RSA_R_BAD_E_VALUE 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102
+#define RSA_R_BAD_PAD_BYTE_COUNT 103
+#define RSA_R_BAD_RSA_PARAMETERS 104
+#define RSA_R_BAD_SIGNATURE 105
+#define RSA_R_BAD_VERSION 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_01 107
+#define RSA_R_BN_NOT_INITIALIZED 108
+#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 109
+#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 110
+#define RSA_R_CRT_VALUES_INCORRECT 111
+#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 112
+#define RSA_R_DATA_TOO_LARGE 113
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 114
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 115
+#define RSA_R_DATA_TOO_SMALL 116
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 117
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 118
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1 119
+#define RSA_R_EMPTY_PUBLIC_KEY 120
+#define RSA_R_ENCODE_ERROR 121
+#define RSA_R_FIRST_OCTET_INVALID 122
+#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 123
+#define RSA_R_INTERNAL_ERROR 124
+#define RSA_R_INVALID_MESSAGE_LENGTH 125
+#define RSA_R_KEY_SIZE_TOO_SMALL 126
+#define RSA_R_LAST_OCTET_INVALID 127
+#define RSA_R_MODULUS_TOO_LARGE 128
+#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 129
+#define RSA_R_NO_PUBLIC_EXPONENT 130
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING 131
+#define RSA_R_N_NOT_EQUAL_P_Q 132
+#define RSA_R_OAEP_DECODING_ERROR 133
+#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 134
+#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 135
+#define RSA_R_PADDING_CHECK_FAILED 136
+#define RSA_R_PKCS_DECODING_ERROR 137
+#define RSA_R_SLEN_CHECK_FAILED 138
+#define RSA_R_SLEN_RECOVERY_FAILED 139
+#define RSA_R_TOO_LONG 140
+#define RSA_R_TOO_MANY_ITERATIONS 141
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE 142
+#define RSA_R_UNKNOWN_PADDING_TYPE 143
+#define RSA_R_VALUE_MISSING 144
+#define RSA_R_WRONG_SIGNATURE_LENGTH 145
 
 #endif  /* OPENSSL_HEADER_RSA_H */
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index dcfee91..1d0b486 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -251,25 +251,39 @@
 
 /* SSL_get_rfd returns the file descriptor that |ssl| is configured to read
  * from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file
- * descriptor then it returns -1. */
+ * descriptor then it returns -1.
+ *
+ * Note: On Windows, this may return either a file descriptor or a socket (cast
+ * to int), depending on whether |ssl| was configured with a file descriptor or
+ * socket |BIO|. */
 OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl);
 
 /* SSL_get_wfd returns the file descriptor that |ssl| is configured to write
  * to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file
- * descriptor then it returns -1. */
+ * descriptor then it returns -1.
+ *
+ * Note: On Windows, this may return either a file descriptor or a socket (cast
+ * to int), depending on whether |ssl| was configured with a file descriptor or
+ * socket |BIO|. */
 OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl);
 
 /* SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one
  * on success and zero on allocation error. The caller retains ownership of
- * |fd|. */
+ * |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
 OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd);
 
 /* SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and
- * zero on allocation error. The caller retains ownership of |fd|. */
+ * zero on allocation error. The caller retains ownership of |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
 OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd);
 
 /* SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and
- * zero on allocation error. The caller retains ownership of |fd|. */
+ * zero on allocation error. The caller retains ownership of |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
 OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd);
 
 /* SSL_do_handshake continues the current handshake. If there is none or the
@@ -465,7 +479,8 @@
  * a private key operation was unfinished. The caller may retry the operation
  * when the private key operation is complete.
  *
- * See also |SSL_set_private_key_method|. */
+ * See also |SSL_set_private_key_method| and
+ * |SSL_CTX_set_private_key_method|. */
 #define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13
 
 /* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
@@ -1003,6 +1018,11 @@
 OPENSSL_EXPORT void SSL_set_private_key_method(
     SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
 
+/* SSL_CTX_set_private_key_method configures a custom private key on |ctx|.
+ * |key_method| must remain valid for the lifetime of |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_private_key_method(
+    SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method);
+
 
 /* Cipher suites.
  *
@@ -1029,6 +1049,9 @@
 /* SSL_CIPHER_has_SHA1_HMAC returns one if |cipher| uses HMAC-SHA1. */
 OPENSSL_EXPORT int SSL_CIPHER_has_SHA1_HMAC(const SSL_CIPHER *cipher);
 
+/* SSL_CIPHER_has_SHA256_HMAC returns one if |cipher| uses HMAC-SHA256. */
+OPENSSL_EXPORT int SSL_CIPHER_has_SHA256_HMAC(const SSL_CIPHER *cipher);
+
 /* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
 OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
 
@@ -1473,6 +1496,16 @@
  * TODO(davidben): This should return a const X509 *. */
 OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session);
 
+/* TODO(davidben): Remove this when wpa_supplicant in Android has synced with
+ * upstream. */
+#if !defined(BORINGSSL_SUPPRESS_ACCESSORS)
+/* SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s master
+ * secret to |out| and returns the number of bytes written. If |max_out| is
+ * zero, it returns the size of the master secret. */
+OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
+                                                 uint8_t *out, size_t max_out);
+#endif
+
 /* SSL_SESSION_set_time sets |session|'s creation time to |time| and returns
  * |time|. This function may be useful in writing tests but otherwise should not
  * be used. */
@@ -2062,6 +2095,28 @@
  * handshake. */
 OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
 
+/* SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. Ownership of
+ * |store| is transferred to the |SSL_CTX|. */
+OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx,
+                                                  X509_STORE *store);
+
+/* SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. An additional
+ * reference to |store| will be taken. */
+OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx,
+                                                  X509_STORE *store);
+
+/* SSL_set0_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. Ownership of
+ * |store| is transferred to the |SSL|. */
+OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store);
+
+/* SSL_set1_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. An additional
+ * reference to |store| will be taken. */
+OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store);
+
 
 /* Client certificate CA list.
  *
@@ -2118,12 +2173,6 @@
 OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
                                                        const char *file);
 
-/* SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls
- * |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success
- * or zero on error. */
-OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
-                                                      const char *dir);
-
 
 /* Server name indication.
  *
@@ -2359,8 +2408,8 @@
  *
  * See RFC 5764. */
 
-/* An SRTP_PROTECTION_PROFILE is an SRTP profile for use with the use_srtp
- * extension. */
+/* srtp_protection_profile_st (aka |SRTP_PROTECTION_PROFILE|) is an SRTP
+ * profile for use with the use_srtp extension. */
 struct srtp_protection_profile_st {
   const char *name;
   unsigned long id;
@@ -2574,7 +2623,7 @@
                                             CRYPTO_EX_free *free_func);
 
 
-/* Obscure functions. */
+/* Low-level record-layer state. */
 
 /* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
  * the read and write directions. It returns one on success or zero if |ssl|
@@ -2592,6 +2641,28 @@
                                const uint8_t **out_write_iv,
                                size_t *out_iv_len);
 
+/* SSL_get_key_block_len returns the length of |ssl|'s key block. */
+OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl);
+
+/* SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s
+ * current connection state. */
+OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out,
+                                          size_t out_len);
+
+/* SSL_get_read_sequence returns, in TLS, the expected sequence number of the
+ * next incoming record in the current epoch. In DTLS, it returns the maximum
+ * sequence number received in the current epoch and includes the epoch number
+ * in the two most significant bytes. */
+OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl);
+
+/* SSL_get_write_sequence returns the sequence number of the next outgoing
+ * record in the current epoch. In DTLS, it includes the epoch number in the
+ * two most significant bytes. */
+OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl);
+
+
+/* Obscure functions. */
+
 /* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
  * SSL_SESSION structures so that a test can ensure that outside code agrees on
  * these values. */
@@ -2696,15 +2767,17 @@
 
 /* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
  * sent by |ctx|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
-                                                  size_t max_send_fragment);
+ * will be split into multiple records. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
+                                                 size_t max_send_fragment);
 
-/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ssl|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
-                                              size_t max_send_fragment);
+/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records sent
+ * by |ssl|. Beyond this length, handshake messages and application data will
+ * be split into multiple records. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl,
+                                             size_t max_send_fragment);
 
 /* ssl_early_callback_ctx is passed to certain callbacks that are called very
  * early on during the server handshake. At this point, much of the SSL* hasn't
@@ -2860,6 +2933,34 @@
  * |TLSEXT_hash_none|. */
 OPENSSL_EXPORT uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl);
 
+/* TODO(davidben): Remove this when wpa_supplicant in Android has synced with
+ * upstream. */
+#if !defined(BORINGSSL_SUPPRESS_ACCESSORS)
+/* SSL_get_client_random writes up to |max_out| bytes of the most recent
+ * handshake's client_random to |out| and returns the number of bytes written.
+ * If |max_out| is zero, it returns the size of the client_random. */
+OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out,
+                                            size_t max_out);
+
+/* SSL_get_server_random writes up to |max_out| bytes of the most recent
+ * handshake's server_random to |out| and returns the number of bytes written.
+ * If |max_out| is zero, it returns the size of the server_random. */
+OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out,
+                                            size_t max_out);
+#endif
+
+/* SSL_get_pending_cipher returns the cipher suite for the current handshake or
+ * NULL if one has not been negotiated yet or there is no pending handshake. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl);
+
+/* SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether
+ * only the SHA-256 hash of peer's certificate should be saved in memory and in
+ * the session. This can save memory, ticket size and session cache space. If
+ * enabled, |SSL_get_peer_certificate| will return NULL after the handshake
+ * completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. */
+OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx,
+                                                                   int enable);
+
 
 /* Deprecated functions. */
 
@@ -3013,6 +3114,10 @@
 /* SSL_set_state does nothing. */
 OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
 
+/* SSL_get_shared_ciphers writes an empty string to |buf| and returns a
+ * pointer to |buf|, or NULL if |len| is less than or equal to zero. */
+OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len);
+
 /* SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. */
 #define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
 
@@ -3071,6 +3176,9 @@
 /* SSL_get_current_expansion returns NULL. */
 OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *s);
 
+/* SSL_get_server_tmp_key returns zero. */
+OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
+
 #define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
 #define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
 #define SSL_SESSION_set_app_data(s, a) \
@@ -3303,6 +3411,13 @@
  * |ec_key|'s curve. */
 OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
 
+/* SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls
+ * |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success
+ * or zero on error. This function is only available from the libdecrepit
+ * library. */
+OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+                                                      const char *dir);
+
 
 /* Private structures.
  *
@@ -3463,6 +3578,8 @@
   uint8_t *in_group_flags;
 };
 
+/* ssl_ctx_st (aka |SSL_CTX|) contains configuration common to several SSL
+ * connections. */
 struct ssl_ctx_st {
   const SSL_PROTOCOL_METHOD *method;
 
@@ -3627,7 +3744,7 @@
 
 
   /* retain_only_sha256_of_client_certs is true if we should compute the SHA256
-   * hash of the peer's certifiate and then discard it to save memory and
+   * hash of the peer's certificate and then discard it to save memory and
    * session space. Only effective on the server side. */
   char retain_only_sha256_of_client_certs;
 
@@ -3706,6 +3823,11 @@
    * means that we'll accept Channel IDs from clients. For a client, means that
    * we'll advertise support. */
   unsigned tlsext_channel_id_enabled:1;
+
+  /* extra_certs is a dummy value included for compatibility.
+   * TODO(agl): remove once node.js no longer references this. */
+  STACK_OF(X509)* extra_certs;
+  int freelist_max_len;
 };
 
 struct ssl_st {
@@ -3724,10 +3846,6 @@
    * TLS). */
   const SSL_PROTOCOL_METHOD *method;
 
-  /* enc_method is the method table corresponding to the current protocol
-   * version. */
-  const SSL3_ENC_METHOD *enc_method;
-
   /* There are 2 BIO's even though they are normally both the same. This is so
    * data can be read and written to different handlers */
 
@@ -3775,9 +3893,6 @@
   struct ssl_cipher_preference_list_st *cipher_list;
   STACK_OF(SSL_CIPHER) *cipher_list_by_id;
 
-  SSL_AEAD_CTX *aead_read_ctx;
-  SSL_AEAD_CTX *aead_write_ctx;
-
   /* session info */
 
   /* client cert? */
@@ -3836,15 +3951,6 @@
 
   SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */
 
-  /* Next protocol negotiation. For the client, this is the protocol that we
-   * sent in NextProtocol and is set when handling ServerHello extensions.
-   *
-   * For a server, this is the client's selected_protocol from NextProtocol and
-   * is set when handling the NextProtocol message, before the Finished
-   * message. */
-  uint8_t *next_proto_negotiated;
-  size_t next_proto_negotiated_len;
-
   /* srtp_profiles is the list of configured SRTP protection profiles for
    * DTLS-SRTP. */
   STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
@@ -3870,10 +3976,6 @@
   EVP_CIPHER_CTX *enc_read_ctx;
   EVP_MD_CTX *read_hash;
 
-  /* in_handshake is non-zero when we are actually in SSL_accept() or
-   * SSL_connect() */
-  int in_handshake;
-
   /* verify_mode is a bitmask of |SSL_VERIFY_*| values. */
   uint8_t verify_mode;
 
@@ -3900,6 +4002,9 @@
    * means that we'll accept Channel IDs from clients. For a client, means that
    * we'll advertise support. */
   unsigned tlsext_channel_id_enabled:1;
+
+  /* TODO(agl): remove once node.js not longer references this. */
+  int tlsext_status_type;
 };
 
 typedef struct ssl3_record_st {
@@ -3964,8 +4069,10 @@
    * the handshake hash for TLS 1.1 and below. */
   EVP_MD_CTX handshake_md5;
 
-  int warn_alert;
-  int fatal_alert;
+  /* clean_shutdown is one if the connection was cleanly shutdown with a
+   * close_notify and zero otherwise. */
+  char clean_shutdown;
+
   /* we allow one fatal and one warning alert to be outstanding, send close
    * alert via the warning alert */
   int alert_dispatch;
@@ -3980,6 +4087,16 @@
    * received. */
   uint8_t warning_alert_count;
 
+  /* aead_read_ctx is the current read cipher state. */
+  SSL_AEAD_CTX *aead_read_ctx;
+
+  /* aead_write_ctx is the current write cipher state. */
+  SSL_AEAD_CTX *aead_write_ctx;
+
+  /* enc_method is the method table corresponding to the current protocol
+   * version. */
+  const SSL3_ENC_METHOD *enc_method;
+
   /* State pertaining to the pending handshake.
    *
    * TODO(davidben): State is current spread all over the place. Move
@@ -4045,13 +4162,12 @@
     uint8_t *certificate_types;
     size_t num_certificate_types;
 
-    int key_block_length;
     uint8_t *key_block;
+    uint8_t key_block_length;
 
-    const EVP_AEAD *new_aead;
     uint8_t new_mac_secret_len;
+    uint8_t new_key_len;
     uint8_t new_fixed_iv_len;
-    uint8_t new_variable_iv_len;
 
     /* Server-only: cert_request is true if a client certificate was
      * requested. */
@@ -4114,6 +4230,15 @@
   /* Set if we saw the Next Protocol Negotiation extension from our peer. */
   int next_proto_neg_seen;
 
+  /* Next protocol negotiation. For the client, this is the protocol that we
+   * sent in NextProtocol and is set when handling ServerHello extensions.
+   *
+   * For a server, this is the client's selected_protocol from NextProtocol and
+   * is set when handling the NextProtocol message, before the Finished
+   * message. */
+  uint8_t *next_proto_negotiated;
+  size_t next_proto_negotiated_len;
+
   /* ALPN information
    * (we are in the process of transitioning from NPN to ALPN.) */
 
@@ -4142,8 +4267,6 @@
  * wpa_supplicant will take a little time to sync with upstream. Outside of
  * Android they'll have no definition. */
 
-#define SSL_F_SSL_SET_SESSION_TICKET_EXT doesnt_exist
-
 OPENSSL_EXPORT int SSL_set_session_ticket_ext(SSL *s, void *ext_data,
                                               int ext_len);
 OPENSSL_EXPORT int SSL_set_session_secret_cb(SSL *s, void *cb, void *arg);
@@ -4151,6 +4274,14 @@
 OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
 
 
+/* Nodejs compatibility section (hidden).
+ *
+ * These defines exist for node.js, with the hope that we can eliminate the
+ * need for them over time. */
+#define SSLerr(function, reason) \
+  ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__)
+
+
 /* Preprocessor compatibility section (hidden).
  *
  * Historically, a number of APIs were implemented in OpenSSL as macros and
@@ -4438,6 +4569,7 @@
 #define SSL_R_WRONG_VERSION_NUMBER 247
 #define SSL_R_X509_LIB 248
 #define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249
+#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250
 #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/thread.h b/src/include/openssl/thread.h
index 568a858..ac4ced0 100644
--- a/src/include/openssl/thread.h
+++ b/src/include/openssl/thread.h
@@ -67,7 +67,9 @@
 
 
 #if defined(OPENSSL_NO_THREADS)
-typedef struct crypto_mutex_st {} CRYPTO_MUTEX;
+typedef struct crypto_mutex_st {
+  char padding;  /* Empty structs have different sizes in C and C++. */
+} CRYPTO_MUTEX;
 #elif defined(OPENSSL_WINDOWS)
 /* CRYPTO_MUTEX can appear in public header files so we really don't want to
  * pull in windows.h. It's statically asserted that this structure is large
diff --git a/src/include/openssl/time_support.h b/src/include/openssl/time_support.h
index cec430d..274b17d 100644
--- a/src/include/openssl/time_support.h
+++ b/src/include/openssl/time_support.h
@@ -60,6 +60,7 @@
 
 #include <openssl/base.h>
 
+#include <time.h>
 
 #if defined(__cplusplus)
 extern "C" {
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index 92d2752..e0f1399 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -218,7 +218,7 @@
 /* ExtensionType value from RFC7685 */
 #define TLSEXT_TYPE_padding 21
 
-/* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */
+/* ExtensionType value from RFC7627 */
 #define TLSEXT_TYPE_extended_master_secret 23
 
 /* ExtensionType value from RFC4507 */
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index a5aaf31..4b977b9 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -76,6 +76,7 @@
 #include <openssl/ecdsa.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
+#include <openssl/obj.h>
 #include <openssl/rsa.h>
 #include <openssl/sha.h>
 #include <openssl/stack.h>
@@ -1153,6 +1154,17 @@
 OPENSSL_EXPORT char *X509_TRUST_get0_name(X509_TRUST *xp);
 OPENSSL_EXPORT int X509_TRUST_get_trust(X509_TRUST *xp);
 
+
+typedef struct rsa_pss_params_st {
+  X509_ALGOR *hashAlgorithm;
+  X509_ALGOR *maskGenAlgorithm;
+  ASN1_INTEGER *saltLength;
+  ASN1_INTEGER *trailerField;
+} RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
+
 /* PKCS7_get_certificates parses a PKCS#7, SignedData structure from |cbs| and
  * appends the included certificates to |out_certs|. It returns one on success
  * and zero on error. */
@@ -1227,30 +1239,28 @@
 #define X509_R_INVALID_BIT_STRING_BITS_LEFT 109
 #define X509_R_INVALID_DIRECTORY 110
 #define X509_R_INVALID_FIELD_NAME 111
-#define X509_R_INVALID_TRUST 112
-#define X509_R_ISSUER_MISMATCH 113
-#define X509_R_KEY_TYPE_MISMATCH 114
-#define X509_R_KEY_VALUES_MISMATCH 115
-#define X509_R_LOADING_CERT_DIR 116
-#define X509_R_LOADING_DEFAULTS 117
-#define X509_R_METHOD_NOT_SUPPORTED 118
+#define X509_R_INVALID_PSS_PARAMETERS 112
+#define X509_R_INVALID_TRUST 113
+#define X509_R_ISSUER_MISMATCH 114
+#define X509_R_KEY_TYPE_MISMATCH 115
+#define X509_R_KEY_VALUES_MISMATCH 116
+#define X509_R_LOADING_CERT_DIR 117
+#define X509_R_LOADING_DEFAULTS 118
 #define X509_R_NEWER_CRL_NOT_NEWER 119
 #define X509_R_NOT_PKCS7_SIGNED_DATA 120
 #define X509_R_NO_CERTIFICATES_INCLUDED 121
 #define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 122
-#define X509_R_NO_CRL_NUMBER 123
-#define X509_R_PUBLIC_KEY_DECODE_ERROR 124
-#define X509_R_PUBLIC_KEY_ENCODE_ERROR 125
-#define X509_R_SHOULD_RETRY 126
-#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 127
-#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 128
-#define X509_R_UNKNOWN_KEY_TYPE 129
-#define X509_R_UNKNOWN_NID 130
-#define X509_R_UNKNOWN_PURPOSE_ID 131
-#define X509_R_UNKNOWN_TRUST_ID 132
-#define X509_R_UNSUPPORTED_ALGORITHM 133
-#define X509_R_WRONG_LOOKUP_TYPE 134
-#define X509_R_WRONG_TYPE 135
-#define X509_R_NO_CRLS_INCLUDED 136
+#define X509_R_NO_CRLS_INCLUDED 123
+#define X509_R_NO_CRL_NUMBER 124
+#define X509_R_PUBLIC_KEY_DECODE_ERROR 125
+#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
+#define X509_R_SHOULD_RETRY 127
+#define X509_R_UNKNOWN_KEY_TYPE 128
+#define X509_R_UNKNOWN_NID 129
+#define X509_R_UNKNOWN_PURPOSE_ID 130
+#define X509_R_UNKNOWN_TRUST_ID 131
+#define X509_R_UNSUPPORTED_ALGORITHM 132
+#define X509_R_WRONG_LOOKUP_TYPE 133
+#define X509_R_WRONG_TYPE 134
 
 #endif
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index b39ef49..a9d0519 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -412,6 +412,11 @@
 /* Allow partial chains if at least one certificate is in trusted store */
 #define X509_V_FLAG_PARTIAL_CHAIN		0x80000
 
+/* If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
+ * will force the behaviour to match that of previous versions. */
+#define X509_V_FLAG_NO_ALT_CHAINS		0x100000
+
 #define X509_VP_FLAG_DEFAULT			0x1
 #define X509_VP_FLAG_OVERWRITE			0x2
 #define X509_VP_FLAG_RESET_FLAGS		0x4
@@ -431,6 +436,7 @@
 OPENSSL_EXPORT void X509_OBJECT_up_ref_count(X509_OBJECT *a);
 OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a);
 OPENSSL_EXPORT X509_STORE *X509_STORE_new(void );
+OPENSSL_EXPORT void X509_STORE_up_ref(X509_STORE *store);
 OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v);
 
 OPENSSL_EXPORT STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
diff --git a/src/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index b7b8ba7..fa78f33 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -600,6 +600,7 @@
 				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
 OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val);
 
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, char *value);
 OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
 OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
 OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
@@ -646,6 +647,7 @@
 OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
 OPENSSL_EXPORT void *X509V3_EXT_d2i(X509_EXTENSION *ext);
 OPENSSL_EXPORT void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data);
 
 
 OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index ee4cbc9..cc95a70 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -115,14 +115,12 @@
 
 #include <assert.h>
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
@@ -292,12 +290,11 @@
   /* During the handshake, wbio is buffered to pack messages together. Flush the
    * buffer if the ChangeCipherSpec would not fit in a packet. */
   if (dtls1_max_record_size(ssl) == 0) {
-    ssl->rwstate = SSL_WRITING;
     int ret = BIO_flush(SSL_get_wbio(ssl));
     if (ret <= 0) {
+      ssl->rwstate = SSL_WRITING;
       return ret;
     }
-    ssl->rwstate = SSL_NOTHING;
   }
 
   static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
@@ -342,13 +339,12 @@
     /* During the handshake, wbio is buffered to pack messages together. Flush
      * the buffer if there isn't enough room to make progress. */
     if (dtls1_max_record_size(ssl) < DTLS1_HM_HEADER_LENGTH + 1) {
-      ssl->rwstate = SSL_WRITING;
       int flush_ret = BIO_flush(SSL_get_wbio(ssl));
       if (flush_ret <= 0) {
+        ssl->rwstate = SSL_WRITING;
         ret = flush_ret;
         goto err;
       }
-      ssl->rwstate = SSL_NOTHING;
       assert(BIO_wpending(SSL_get_wbio(ssl)) == 0);
     }
 
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index ad5eb50..2fc9094 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -115,7 +115,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -125,7 +124,6 @@
 #include <openssl/err.h>
 #include <openssl/md5.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rand.h>
 
 #include "internal.h"
@@ -143,7 +141,6 @@
   assert(!ssl->server);
   assert(SSL_IS_DTLS(ssl));
 
-  ERR_clear_error();
   ERR_clear_system_error();
 
   if (ssl->info_callback != NULL) {
@@ -152,8 +149,6 @@
     cb = ssl->ctx->info_callback;
   }
 
-  ssl->in_handshake++;
-
   for (;;) {
     state = ssl->state;
 
@@ -368,10 +363,7 @@
         ssl->state = SSL3_ST_CW_FINISHED_A;
         ssl->init_num = 0;
 
-        ssl->session->cipher = ssl->s3->tmp.new_cipher;
-        if (!ssl->enc_method->setup_key_block(ssl) ||
-            !ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -383,10 +375,8 @@
           dtls1_start_timer(ssl);
         }
 
-        ret =
-            ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
-                               ssl->enc_method->client_finished_label,
-                               ssl->enc_method->client_finished_label_len);
+        ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
+                                 SSL3_ST_CW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
@@ -431,7 +421,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
           ret = -1;
           goto end;
         }
@@ -457,12 +447,11 @@
         break;
 
       case SSL3_ST_CW_FLUSH:
-        ssl->rwstate = SSL_WRITING;
         if (BIO_flush(ssl->wbio) <= 0) {
+          ssl->rwstate = SSL_WRITING;
           ret = -1;
           goto end;
         }
-        ssl->rwstate = SSL_NOTHING;
         ssl->state = ssl->s3->tmp.next_state;
         break;
 
@@ -508,8 +497,6 @@
   }
 
 end:
-  ssl->in_handshake--;
-
   BUF_MEM_free(buf);
   if (cb != NULL) {
     cb(ssl, SSL_CB_CONNECT_EXIT, ret);
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c
index 7f08b06..e48fbf1 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -57,12 +57,11 @@
 #include <openssl/ssl.h>
 
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
@@ -110,11 +109,11 @@
 
   ssl->d1 = d1;
 
-  /* Set the version to the highest version for DTLS. This controls the initial
-   * state of |ssl->enc_method| and what the API reports as the version prior to
-   * negotiation.
+  /* Set the version to the highest supported version.
    *
-   * TODO(davidben): This is fragile and confusing. */
+   * TODO(davidben): Move this field into |s3|, have it store the normalized
+   * protocol version, and implement this pre-negotiation quirk in |SSL_version|
+   * at the API boundary rather than in internal state. */
   ssl->version = DTLS1_2_VERSION;
   return 1;
 }
@@ -272,6 +271,10 @@
 }
 
 int DTLSv1_handle_timeout(SSL *ssl) {
+  ssl->rwstate = SSL_NOTHING;
+  /* Functions which use SSL_get_error must clear the error queue on entry. */
+  ERR_clear_error();
+
   if (!SSL_IS_DTLS(ssl)) {
     return -1;
   }
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index f2ade3a..4690486 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -112,7 +112,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
@@ -186,6 +185,7 @@
 }
 
 int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+  assert(!SSL_in_init(ssl));
   return dtls1_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
 }
 
@@ -233,7 +233,7 @@
  * This function must handle any surprises the peer may have for us, such as
  * Alert records (e.g. close_notify) and out of records. */
 int dtls1_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek) {
-  int al, i, ret;
+  int al, ret;
   unsigned int n;
   SSL3_RECORD *rr;
   void (*cb)(const SSL *ssl, int type, int value) = NULL;
@@ -245,21 +245,7 @@
     return -1;
   }
 
-  if (!ssl->in_handshake && SSL_in_init(ssl)) {
-    /* type == SSL3_RT_APPLICATION_DATA */
-    i = ssl->handshake_func(ssl);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
-
 start:
-  ssl->rwstate = SSL_NOTHING;
-
   /* ssl->s3->rrec.type     - is the type of record
    * ssl->s3->rrec.data     - data
    * ssl->s3->rrec.off      - offset into 'data' for next read
@@ -291,7 +277,6 @@
    * 'peek' mode) */
   if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
     rr->length = 0;
-    ssl->rwstate = SSL_NOTHING;
     return 0;
   }
 
@@ -300,7 +285,7 @@
     /* Make sure that we are not getting application data when we
      * are doing a handshake for the first time. */
     if (SSL_in_init(ssl) && (type == SSL3_RT_APPLICATION_DATA) &&
-        (ssl->aead_read_ctx == NULL)) {
+        (ssl->s3->aead_read_ctx == NULL)) {
       /* TODO(davidben): Is this check redundant with the handshake_func
        * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -338,11 +323,10 @@
 
   /* If we get here, then type != rr->type. */
 
-  /* If an alert record, process one alert out of the record. Note that we allow
-   * a single record to contain multiple alerts. */
+  /* If an alert record, process the alert. */
   if (rr->type == SSL3_RT_ALERT) {
-    /* Alerts may not be fragmented. */
-    if (rr->length < 2) {
+    /* Alerts records may not contain fragmented or multiple alerts. */
+    if (rr->length != 2) {
       al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
       goto f_err;
@@ -369,16 +353,14 @@
     }
 
     if (alert_level == SSL3_AL_WARNING) {
-      ssl->s3->warn_alert = alert_descr;
       if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+        ssl->s3->clean_shutdown = 1;
         ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
         return 0;
       }
     } else if (alert_level == SSL3_AL_FATAL) {
       char tmp[16];
 
-      ssl->rwstate = SSL_NOTHING;
-      ssl->s3->fatal_alert = alert_descr;
       OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
       BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
       ERR_add_error_data(2, "SSL alert number ", tmp);
@@ -403,8 +385,10 @@
    * Application data must come in the encrypted epoch, and ChangeCipherSpec in
    * the unencrypted epoch (we never renegotiate). Other cases fall through and
    * fail with a fatal error. */
-  if ((rr->type == SSL3_RT_APPLICATION_DATA && ssl->aead_read_ctx != NULL) ||
-      (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && ssl->aead_read_ctx == NULL)) {
+  if ((rr->type == SSL3_RT_APPLICATION_DATA &&
+       ssl->s3->aead_read_ctx != NULL) ||
+      (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC &&
+       ssl->s3->aead_read_ctx == NULL)) {
     rr->length = 0;
     goto start;
   }
@@ -458,39 +442,23 @@
 }
 
 int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) {
-  int i;
-
-  if (SSL_in_init(ssl) && !ssl->in_handshake) {
-    i = ssl->handshake_func(ssl);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
+  assert(!SSL_in_init(ssl));
 
   if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
     return -1;
   }
 
-  i = dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
-                        dtls1_use_current_epoch);
-  return i;
+  return dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
+                           dtls1_use_current_epoch);
 }
 
 /* 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 *ssl, int type, const void *buf, int len,
                       enum dtls1_use_epoch_t use_epoch) {
-  int i;
-
   assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
-  ssl->rwstate = SSL_NOTHING;
-  i = do_dtls1_write(ssl, type, buf, len, use_epoch);
-  return i;
+  return do_dtls1_write(ssl, type, buf, len, use_epoch);
 }
 
 static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
@@ -537,42 +505,35 @@
 }
 
 int dtls1_dispatch_alert(SSL *ssl) {
-  int i, j;
-  void (*cb)(const SSL *ssl, int type, int value) = NULL;
-  uint8_t buf[DTLS1_AL_HEADER_LENGTH];
-  uint8_t *ptr = &buf[0];
-
   ssl->s3->alert_dispatch = 0;
-
-  memset(buf, 0x00, sizeof(buf));
-  *ptr++ = ssl->s3->send_alert[0];
-  *ptr++ = ssl->s3->send_alert[1];
-
-  i = do_dtls1_write(ssl, SSL3_RT_ALERT, &buf[0], sizeof(buf),
-                     dtls1_use_current_epoch);
-  if (i <= 0) {
+  int ret = do_dtls1_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2,
+                           dtls1_use_current_epoch);
+  if (ret <= 0) {
     ssl->s3->alert_dispatch = 1;
-  } else {
-    if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
-      (void)BIO_flush(ssl->wbio);
-    }
-
-    if (ssl->msg_callback) {
-      ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
-                        ssl, ssl->msg_callback_arg);
-    }
-
-    if (ssl->info_callback != NULL) {
-      cb = ssl->info_callback;
-    } else if (ssl->ctx->info_callback != NULL) {
-      cb = ssl->ctx->info_callback;
-    }
-
-    if (cb != NULL) {
-      j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
-      cb(ssl, SSL_CB_WRITE_ALERT, j);
-    }
+    return ret;
   }
 
-  return i;
+  /* If the alert is fatal, flush the BIO now. */
+  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+    BIO_flush(ssl->wbio);
+  }
+
+  if (ssl->msg_callback != NULL) {
+    ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_ALERT,
+                      ssl->s3->send_alert, 2, ssl, ssl->msg_callback_arg);
+  }
+
+  void (*cb)(const SSL *ssl, int type, int value) = NULL;
+  if (ssl->info_callback != NULL) {
+    cb = ssl->info_callback;
+  } else if (ssl->ctx->info_callback != NULL) {
+    cb = ssl->ctx->info_callback;
+  }
+
+  if (cb != NULL) {
+    int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+    cb(ssl, SSL_CB_WRITE_ALERT, alert);
+  }
+
+  return 1;
 }
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c
index 5dba8ef..e7b1607 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -116,12 +116,10 @@
 
 #include <openssl/ssl.h>
 
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/bytestring.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
 
 #include "internal.h"
 
@@ -212,7 +210,7 @@
     return ssl->srtp_profiles;
   }
 
-  if (ssl->ctx != NULL && ssl->ctx->srtp_profiles != NULL) {
+  if (ssl->ctx->srtp_profiles != NULL) {
     return ssl->ctx->srtp_profiles;
   }
 
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index 3ba9411..d353281 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -115,7 +115,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 
 #include <openssl/bn.h>
 #include <openssl/buf.h>
@@ -123,7 +122,6 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
-#include <openssl/obj.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 
@@ -141,7 +139,6 @@
   assert(ssl->server);
   assert(SSL_IS_DTLS(ssl));
 
-  ERR_clear_error();
   ERR_clear_system_error();
 
   if (ssl->info_callback != NULL) {
@@ -150,8 +147,6 @@
     cb = ssl->ctx->info_callback;
   }
 
-  ssl->in_handshake++;
-
   for (;;) {
     state = ssl->state;
 
@@ -307,12 +302,11 @@
         break;
 
       case SSL3_ST_SW_FLUSH:
-        ssl->rwstate = SSL_WRITING;
         if (BIO_flush(ssl->wbio) <= 0) {
+          ssl->rwstate = SSL_WRITING;
           ret = -1;
           goto end;
         }
-        ssl->rwstate = SSL_NOTHING;
         ssl->state = ssl->s3->tmp.next_state;
         break;
 
@@ -355,7 +349,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
           ret = -1;
           goto end;
         }
@@ -393,12 +387,6 @@
 
       case SSL3_ST_SW_CHANGE_A:
       case SSL3_ST_SW_CHANGE_B:
-        ssl->session->cipher = ssl->s3->tmp.new_cipher;
-        if (!ssl->enc_method->setup_key_block(ssl)) {
-          ret = -1;
-          goto end;
-        }
-
         ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
                                             SSL3_ST_SW_CHANGE_B);
 
@@ -409,8 +397,7 @@
         ssl->state = SSL3_ST_SW_FINISHED_A;
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -419,9 +406,7 @@
       case SSL3_ST_SW_FINISHED_A:
       case SSL3_ST_SW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
-                                 SSL3_ST_SW_FINISHED_B,
-                                 ssl->enc_method->server_finished_label,
-                                 ssl->enc_method->server_finished_label_len);
+                                 SSL3_ST_SW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
@@ -476,7 +461,6 @@
   }
 
 end:
-  ssl->in_handshake--;
   BUF_MEM_free(buf);
   if (cb != NULL) {
     cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
diff --git a/src/ssl/dtls_record.c b/src/ssl/dtls_record.c
index 940494a..eaf6df7 100644
--- a/src/ssl/dtls_record.c
+++ b/src/ssl/dtls_record.c
@@ -213,7 +213,7 @@
 
   /* Decrypt the body. */
   size_t plaintext_len;
-  if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+  if (!SSL_AEAD_CTX_open(ssl->s3->aead_read_ctx, out, &plaintext_len, max_out,
                          type, version, sequence, CBS_data(&body),
                          CBS_len(&body))) {
     /* Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
@@ -250,7 +250,7 @@
                      enum dtls1_use_epoch_t use_epoch) {
   /* Determine the parameters for the current epoch. */
   uint16_t epoch = ssl->d1->w_epoch;
-  SSL_AEAD_CTX *aead = ssl->aead_write_ctx;
+  SSL_AEAD_CTX *aead = ssl->s3->aead_write_ctx;
   uint8_t *seq = ssl->s3->write_sequence;
   if (use_epoch == dtls1_use_previous_epoch) {
     /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
@@ -286,7 +286,7 @@
   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)) {
+      !ssl_record_sequence_update(&seq[2], 6)) {
     return 0;
   }
 
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 5acb598..982f304 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -346,6 +346,10 @@
 
 /* Record layer. */
 
+/* ssl_record_sequence_update increments the sequence number in |seq|. It
+ * returns one on success and zero on wraparound. */
+int ssl_record_sequence_update(uint8_t *seq, size_t seq_len);
+
 /* ssl_record_prefix_len returns the length of the prefix before the ciphertext
  * of a record for |ssl|.
  *
@@ -432,6 +436,14 @@
                      uint8_t type, const uint8_t *in, size_t in_len,
                      enum dtls1_use_epoch_t use_epoch);
 
+/* ssl_set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It takes
+ * ownership of |aead_ctx|. */
+void ssl_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx);
+
+/* ssl_set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It takes
+ * ownership of |aead_ctx|. */
+void ssl_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx);
+
 
 /* Private key operations. */
 
@@ -519,7 +531,7 @@
 #define SSL_CURVE_SECP256R1 23
 #define SSL_CURVE_SECP384R1 24
 #define SSL_CURVE_SECP521R1 25
-#define SSL_CURVE_ECDH_X25519 29
+#define SSL_CURVE_X25519 29
 
 /* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for
  * TLS. */
@@ -735,12 +747,6 @@
 
 /* Check if an SSL structure is using DTLS */
 #define SSL_IS_DTLS(ssl) (ssl->method->is_dtls)
-/* See if we need explicit IV */
-#define SSL_USE_EXPLICIT_IV(ssl) \
-  (ssl->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
-/* See if we use signature algorithms extension and signature algorithm before
- * signatures. */
-#define SSL_USE_SIGALGS(ssl) (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS)
 
 /* From RFC4492, used in encoding the curve type in ECParameters */
 #define NAMED_CURVE_TYPE 3
@@ -797,6 +803,10 @@
    * supported signature algorithms or curves. */
   int (*cert_cb)(SSL *ssl, void *arg);
   void *cert_cb_arg;
+
+  /* Optional X509_STORE for certificate validation. If NULL the parent SSL_CTX
+   * store is used instead. */
+  X509_STORE *verify_store;
 } CERT;
 
 /* SSL_METHOD is a compatibility structure to support the legacy version-locked
@@ -840,22 +850,16 @@
 /* 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 (*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 *);
-  int (*generate_master_secret)(SSL *, uint8_t *, const uint8_t *, size_t);
-  int (*change_cipher_state)(SSL *, int);
-  int (*final_finish_mac)(SSL *, const char *, int, uint8_t *);
+  /* prf computes the PRF function for |ssl|. It writes |out_len| bytes to
+   * |out|, using |secret| as the secret and |label| as the label. |seed1| and
+   * |seed2| are concatenated to form the seed parameter. It returns one on
+   * success and zero on failure. */
+  int (*prf)(const SSL *ssl, uint8_t *out, size_t out_len,
+             const uint8_t *secret, size_t secret_len, const char *label,
+             size_t label_len, const uint8_t *seed1, size_t seed1_len,
+             const uint8_t *seed2, size_t seed2_len);
+  int (*final_finish_mac)(SSL *ssl, int from_server, uint8_t *out);
   int (*cert_verify_mac)(SSL *, int, uint8_t *);
-  const char *client_finished_label;
-  int client_finished_label_len;
-  const char *server_finished_label;
-  int server_finished_label_len;
-  int (*alert_value)(int);
-  int (*export_keying_material)(SSL *, uint8_t *, size_t, const char *, size_t,
-                                const uint8_t *, size_t, int use_context);
-  /* Various flags indicating protocol version requirements */
-  unsigned int enc_flags;
 };
 
 #define SSL_HM_HEADER_LENGTH(ssl) ssl->method->hhlen
@@ -865,15 +869,6 @@
   ssl->method->set_handshake_header(ssl, htype, len)
 #define ssl_do_write(ssl) ssl->method->do_write(ssl)
 
-/* Values for enc_flags */
-
-/* Uses explicit IV for CBC mode */
-#define SSL_ENC_FLAG_EXPLICIT_IV 0x1
-/* Uses signature algorithms extension */
-#define SSL_ENC_FLAG_SIGALGS 0x2
-/* Uses SHA256 default PRF */
-#define SSL_ENC_FLAG_SHA256_PRF 0x4
-
 /* lengths of messages */
 #define DTLS1_COOKIE_LENGTH 256
 
@@ -966,12 +961,9 @@
 } DTLS1_STATE;
 
 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;
 extern const SSL3_ENC_METHOD SSLv3_enc_data;
 extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[];
 
-void ssl_clear_cipher_ctx(SSL *ssl);
 int ssl_clear_bad_session(SSL *ssl);
 CERT *ssl_cert_new(void);
 CERT *ssl_cert_dup(CERT *cert);
@@ -1030,10 +1022,6 @@
 int ssl3_send_certificate_status(SSL *ssl);
 int ssl3_get_finished(SSL *ssl, int state_a, int state_b);
 int ssl3_send_change_cipher_spec(SSL *ssl, int state_a, int state_b);
-int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
-             size_t secret_len, const char *label, size_t label_len,
-             const uint8_t *seed1, size_t seed1_len,
-             const uint8_t *seed2, size_t seed2_len);
 void ssl3_cleanup_key_block(SSL *ssl);
 int ssl3_do_write(SSL *ssl, int type);
 int ssl3_send_alert(SSL *ssl, int level, int desc);
@@ -1054,7 +1042,7 @@
 int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
                           const EVP_MD **out_md, int pkey_type);
 
-int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen);
+int ssl3_send_finished(SSL *ssl, int a, int b);
 int ssl3_supports_cipher(const SSL_CIPHER *cipher);
 int ssl3_dispatch_alert(SSL *ssl);
 int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
@@ -1063,8 +1051,6 @@
 int ssl3_read_bytes(SSL *ssl, 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 *ssl, int type, const void *buf, int len);
-int ssl3_final_finish_mac(SSL *ssl, const char *sender, int slen, uint8_t *p);
-int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
 int ssl3_output_cert_chain(SSL *ssl);
 const SSL_CIPHER *ssl3_choose_cipher(
     SSL *ssl, STACK_OF(SSL_CIPHER) *clnt,
@@ -1075,12 +1061,6 @@
 int ssl3_accept(SSL *ssl);
 int ssl3_connect(SSL *ssl);
 
-/* ssl3_record_sequence_update increments the sequence number in |seq|. It
- * returns one on success and zero on wraparound. */
-int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len);
-
-int ssl3_do_change_cipher_spec(SSL *ssl);
-
 int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len);
 int ssl3_handshake_write(SSL *ssl);
 
@@ -1159,29 +1139,11 @@
 int ssl_init_wbio_buffer(SSL *ssl, int push);
 void ssl_free_wbio_buffer(SSL *ssl);
 
-/* tls1_prf computes the TLS PRF function for |ssl| as described in RFC 5246,
- * section 5 and RFC 2246 section 5. It writes |out_len| bytes to |out|, using
- * |secret| as the secret and |label| as the label. |seed1| and |seed2| are
- * concatenated to form the seed parameter. It returns one on success and zero
- * on failure. */
-int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
-             size_t secret_len, const char *label, size_t label_len,
-             const uint8_t *seed1, size_t seed1_len,
-             const uint8_t *seed2, size_t seed2_len);
-
 int tls1_change_cipher_state(SSL *ssl, int which);
 int tls1_setup_key_block(SSL *ssl);
 int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len);
-int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *p);
-int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
 int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster,
                                 size_t premaster_len);
-int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
-                                const char *label, size_t label_len,
-                                const uint8_t *context, size_t context_len,
-                                int use_context);
-int tls1_alert_code(int code);
-int ssl3_alert_code(int code);
 
 char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx);
 
@@ -1219,13 +1181,13 @@
 
 #define tlsext_tick_md EVP_sha256
 
-/* tls_process_ticket processes the session ticket extension. On success, it
- * sets |*out_session| to the decrypted session or NULL if the ticket was
- * rejected. It sets |*out_send_ticket| to whether a new ticket should be sent
- * at the end of the handshake. It returns one on success and zero on fatal
+/* tls_process_ticket processes a session ticket from the client. On success,
+ * it sets |*out_session| to the decrypted session or NULL if the ticket was
+ * rejected. If the ticket was valid, it sets |*out_renew_ticket| to whether
+ * the ticket should be renewed. It returns one on success and zero on fatal
  * error. */
 int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
-                       int *out_send_ticket, const uint8_t *ticket,
+                       int *out_renew_ticket, const uint8_t *ticket,
                        size_t ticket_len, const uint8_t *session_id,
                        size_t session_id_len);
 
@@ -1294,9 +1256,13 @@
  *
  * TODO(davidben): To normalize some DTLS-specific code, move away from using
  * the wire version except at API boundaries. */
-uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version);
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version);
 
-uint32_t ssl_get_algorithm_prf(SSL *ssl);
+/* ssl3_protocol_version returns |ssl|'s protocol version. It is an error to
+ * call this function before the version is determined. */
+uint16_t ssl3_protocol_version(const SSL *ssl);
+
+uint32_t ssl_get_algorithm_prf(const SSL *ssl);
 int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs);
 
 /* tls1_choose_signing_digest returns a digest for use with |ssl|'s private key
diff --git a/src/ssl/pqueue/pqueue.c b/src/ssl/pqueue/pqueue.c
index 14bd9b6..e689761 100644
--- a/src/ssl/pqueue/pqueue.c
+++ b/src/ssl/pqueue/pqueue.c
@@ -69,7 +69,7 @@
 
 
 pitem *pitem_new(uint8_t prio64be[8], void *data) {
-  pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem));
+  pitem *item = OPENSSL_malloc(sizeof(pitem));
   if (item == NULL) {
     return NULL;
   }
@@ -91,7 +91,7 @@
 }
 
 pqueue pqueue_new(void) {
-  pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s));
+  pqueue_s *pq = OPENSSL_malloc(sizeof(pqueue_s));
   if (pq == NULL) {
     return NULL;
   }
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 01a7e8c..5d364ab 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -114,7 +114,6 @@
 
 #include <assert.h>
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
@@ -122,7 +121,7 @@
 #include <openssl/evp.h>
 #include <openssl/mem.h>
 #include <openssl/md5.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 #include <openssl/x509.h>
@@ -156,15 +155,15 @@
   return 0;
 }
 
-int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) {
+int ssl3_send_finished(SSL *ssl, int a, int b) {
   uint8_t *p;
   int n;
 
   if (ssl->state == a) {
     p = ssl_handshake_start(ssl);
 
-    n = ssl->enc_method->final_finish_mac(ssl, sender, slen,
-                                          ssl->s3->tmp.finish_md);
+    n = ssl->s3->enc_method->final_finish_mac(ssl, ssl->server,
+                                              ssl->s3->tmp.finish_md);
     if (n == 0) {
       return 0;
     }
@@ -202,25 +201,14 @@
 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
  * so far. */
 static void ssl3_take_mac(SSL *ssl) {
-  const char *sender;
-  int slen;
-
   /* If no new cipher setup then return immediately: other functions will set
    * the appropriate error. */
   if (ssl->s3->tmp.new_cipher == NULL) {
     return;
   }
 
-  if (ssl->state & SSL_ST_CONNECT) {
-    sender = ssl->enc_method->server_finished_label;
-    slen = ssl->enc_method->server_finished_label_len;
-  } else {
-    sender = ssl->enc_method->client_finished_label;
-    slen = ssl->enc_method->client_finished_label_len;
-  }
-
-  ssl->s3->tmp.peer_finish_md_len = ssl->enc_method->final_finish_mac(
-      ssl, sender, slen, ssl->s3->tmp.peer_finish_md);
+  ssl->s3->tmp.peer_finish_md_len = ssl->s3->enc_method->final_finish_mac(
+      ssl, !ssl->server, ssl->s3->tmp.peer_finish_md);
 }
 
 int ssl3_get_finished(SSL *ssl, int a, int b) {
@@ -250,7 +238,12 @@
     goto f_err;
   }
 
-  if (CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len) != 0) {
+  int finished_ret =
+      CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  finished_ret = 0;
+#endif
+  if (finished_ret != 0) {
     al = SSL_AD_DECRYPT_ERROR;
     OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
     goto f_err;
@@ -277,13 +270,6 @@
   return 0;
 }
 
-/* for these 2 messages, we need to
- * ssl->enc_read_ctx      re-init
- * ssl->s3->read_sequence   zero
- * ssl->s3->read_mac_secret   re-init
- * ssl->session->read_sym_enc   assign
- * ssl->session->read_compression assign
- * ssl->session->read_hash    assign */
 int ssl3_send_change_cipher_spec(SSL *ssl, int a, int b) {
   if (ssl->state == a) {
     *((uint8_t *)ssl->init_buf->data) = SSL3_MT_CCS;
@@ -407,7 +393,6 @@
     int bytes_read =
         ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], n, 0);
     if (bytes_read <= 0) {
-      ssl->rwstate = SSL_READING;
       *ok = 0;
       return bytes_read;
     }
@@ -452,7 +437,7 @@
   /* For TLS v1.2 send signature algorithm and signature using
    * agreed digest and cached handshake records. Otherwise, use
    * SHA1 or MD5 + SHA1 depending on key type.  */
-  if (SSL_USE_SIGALGS(ssl)) {
+  if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
     EVP_MD_CTX mctx;
     unsigned len;
 
@@ -467,15 +452,15 @@
     }
     *out_len = len;
   } else if (pkey_type == EVP_PKEY_RSA) {
-    if (ssl->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 ||
-        ssl->enc_method->cert_verify_mac(ssl, NID_sha1,
-                                         out + MD5_DIGEST_LENGTH) == 0) {
+    if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 ||
+        ssl->s3->enc_method->cert_verify_mac(ssl, NID_sha1,
+                                             out + MD5_DIGEST_LENGTH) == 0) {
       return 0;
     }
     *out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
     *out_md = EVP_md5_sha1();
   } else if (pkey_type == EVP_PKEY_EC) {
-    if (ssl->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
+    if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
       return 0;
     }
     *out_len = SHA_DIGEST_LENGTH;
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index 5f68037..6f381cf 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -150,7 +150,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -163,7 +162,6 @@
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
@@ -182,7 +180,6 @@
   assert(!ssl->server);
   assert(!SSL_IS_DTLS(ssl));
 
-  ERR_clear_error();
   ERR_clear_system_error();
 
   if (ssl->info_callback != NULL) {
@@ -191,8 +188,6 @@
     cb = ssl->ctx->info_callback;
   }
 
-  ssl->in_handshake++;
-
   for (;;) {
     state = ssl->state;
 
@@ -388,10 +383,7 @@
         }
         ssl->init_num = 0;
 
-        ssl->session->cipher = ssl->s3->tmp.new_cipher;
-        if (!ssl->enc_method->setup_key_block(ssl) ||
-            !ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -424,9 +416,7 @@
       case SSL3_ST_CW_FINISHED_A:
       case SSL3_ST_CW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
-                                 SSL3_ST_CW_FINISHED_B,
-                                 ssl->enc_method->client_finished_label,
-                                 ssl->enc_method->client_finished_label_len);
+                                 SSL3_ST_CW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
@@ -487,7 +477,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
           ret = -1;
           goto end;
         }
@@ -511,12 +501,11 @@
         break;
 
       case SSL3_ST_CW_FLUSH:
-        ssl->rwstate = SSL_WRITING;
         if (BIO_flush(ssl->wbio) <= 0) {
+          ssl->rwstate = SSL_WRITING;
           ret = -1;
           goto end;
         }
-        ssl->rwstate = SSL_NOTHING;
         ssl->state = ssl->s3->tmp.next_state;
         break;
 
@@ -581,7 +570,6 @@
   }
 
 end:
-  ssl->in_handshake--;
   BUF_MEM_free(buf);
   if (cb != NULL) {
     cb(ssl, SSL_CB_CONNECT_EXIT, ret);
@@ -676,13 +664,12 @@
     ssl->client_version = max_version;
   }
 
-  /* If the configured session has expired or was created at a version higher
-   * than our maximum version, drop it. */
+  /* If the configured session has expired or was created at a disabled
+   * version, drop it. */
   if (ssl->session != NULL &&
       (ssl->session->session_id_length == 0 || ssl->session->not_resumable ||
        ssl->session->timeout < (long)(time(NULL) - ssl->session->time) ||
-       (!SSL_IS_DTLS(ssl) && ssl->session->ssl_version > ssl->version) ||
-       (SSL_IS_DTLS(ssl) && ssl->session->ssl_version < ssl->version))) {
+       !ssl3_is_version_enabled(ssl, ssl->session->ssl_version))) {
     SSL_set_session(ssl, NULL);
   }
 
@@ -791,8 +778,8 @@
       goto f_err;
     }
     ssl->version = server_version;
-    ssl->enc_method = ssl3_get_enc_method(server_version);
-    assert(ssl->enc_method != NULL);
+    ssl->s3->enc_method = ssl3_get_enc_method(server_version);
+    assert(ssl->s3->enc_method != NULL);
     /* At this point, the connection's version is known and ssl->version is
      * fixed. Begin enforcing the record-layer version. */
     ssl->s3->have_version = 1;
@@ -841,8 +828,7 @@
   /* If the cipher is disabled then we didn't sent it in the ClientHello, so if
    * the server selected it, it's an error. */
   if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
-      SSL_CIPHER_get_min_version(c) >
-          ssl3_version_from_wire(ssl, ssl->version)) {
+      SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
     al = SSL_AD_ILLEGAL_PARAMETER;
     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
     goto f_err;
@@ -867,6 +853,8 @@
       OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
       goto f_err;
     }
+  } else {
+    ssl->session->cipher = c;
   }
   ssl->s3->tmp.new_cipher = c;
 
@@ -878,7 +866,7 @@
   /* 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, the handshake buffer may be released. */
-  if (!SSL_USE_SIGALGS(ssl) || ssl->hit) {
+  if (ssl->hit || ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
     ssl3_free_handshake_buffer(ssl);
   }
 
@@ -1060,19 +1048,16 @@
 int ssl3_get_server_key_exchange(SSL *ssl) {
   EVP_MD_CTX md_ctx;
   int al, ok;
-  long n, alg_k, alg_a;
   EVP_PKEY *pkey = NULL;
-  const EVP_MD *md = NULL;
   DH *dh = NULL;
   EC_KEY *ecdh = NULL;
   EC_POINT *srvr_ecpoint = NULL;
-  CBS server_key_exchange, server_key_exchange_orig, parameter;
 
   /* use same message size as in ssl3_get_certificate_request() as
    * ServerKeyExchange message may be skipped */
-  n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_KEY_EXCH_A,
-                                 SSL3_ST_CR_KEY_EXCH_B, -1, ssl->max_cert_list,
-                                 ssl_hash_message, &ok);
+  long n = ssl->method->ssl_get_message(
+      ssl, SSL3_ST_CR_KEY_EXCH_A, SSL3_ST_CR_KEY_EXCH_B, -1, ssl->max_cert_list,
+      ssl_hash_message, &ok);
   if (!ok) {
     return n;
   }
@@ -1097,11 +1082,12 @@
   }
 
   /* Retain a copy of the original CBS to compute the signature over. */
+  CBS server_key_exchange;
   CBS_init(&server_key_exchange, ssl->init_msg, n);
-  server_key_exchange_orig = server_key_exchange;
+  CBS server_key_exchange_orig = server_key_exchange;
 
-  alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
-  alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
+  uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+  uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
   EVP_MD_CTX_init(&md_ctx);
 
   if (alg_a & SSL_aPSK) {
@@ -1224,6 +1210,7 @@
   /* At this point, |server_key_exchange| contains the signature, if any, while
    * |server_key_exchange_orig| contains the entire message. From that, derive
    * a CBS containing just the parameter. */
+  CBS parameter;
   CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
            CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
 
@@ -1234,7 +1221,8 @@
       goto err;
     }
 
-    if (SSL_USE_SIGALGS(ssl)) {
+    const EVP_MD *md = NULL;
+    if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
       uint8_t hash, signature;
       if (!CBS_get_u8(&server_key_exchange, &hash) ||
           !CBS_get_u8(&server_key_exchange, &signature)) {
@@ -1261,15 +1249,20 @@
       goto f_err;
     }
 
-    if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) ||
-        !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random,
-                                SSL3_RANDOM_SIZE) ||
-        !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random,
-                                SSL3_RANDOM_SIZE) ||
-        !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
-                                CBS_len(&parameter)) ||
-        !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
-                               CBS_len(&signature))) {
+    int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
+                 EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random,
+                                        SSL3_RANDOM_SIZE) &&
+                 EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random,
+                                        SSL3_RANDOM_SIZE) &&
+                 EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
+                                        CBS_len(&parameter)) &&
+                 EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
+                                       CBS_len(&signature));
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+    sig_ok = 1;
+    ERR_clear_error();
+#endif
+    if (!sig_ok) {
       /* bad signature */
       al = SSL_AD_DECRYPT_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
@@ -1306,17 +1299,12 @@
 
 int ssl3_get_certificate_request(SSL *ssl) {
   int ok, ret = 0;
-  unsigned long n;
   X509_NAME *xn = NULL;
   STACK_OF(X509_NAME) *ca_sk = NULL;
-  CBS cbs;
-  CBS certificate_types;
-  CBS certificate_authorities;
-  const uint8_t *data;
 
-  n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_CERT_REQ_A,
-                                 SSL3_ST_CR_CERT_REQ_B, -1, ssl->max_cert_list,
-                                 ssl_hash_message, &ok);
+  long n = ssl->method->ssl_get_message(
+      ssl, SSL3_ST_CR_CERT_REQ_A, SSL3_ST_CR_CERT_REQ_B, -1, ssl->max_cert_list,
+      ssl_hash_message, &ok);
 
   if (!ok) {
     return n;
@@ -1334,10 +1322,11 @@
 
   if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
-    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
     goto err;
   }
 
+  CBS cbs;
   CBS_init(&cbs, ssl->init_msg, n);
 
   ca_sk = sk_X509_NAME_new(ca_dn_cmp);
@@ -1347,6 +1336,7 @@
   }
 
   /* get the certificate types */
+  CBS certificate_types;
   if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
@@ -1359,7 +1349,7 @@
     goto err;
   }
 
-  if (SSL_USE_SIGALGS(ssl)) {
+  if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
     CBS supported_signature_algorithms;
     if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
         !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
@@ -1370,6 +1360,7 @@
   }
 
   /* get the CA RDNs */
+  CBS certificate_authorities;
   if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
     OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
@@ -1385,25 +1376,13 @@
       goto err;
     }
 
-    data = CBS_data(&distinguished_name);
-
+    const uint8_t *data = CBS_data(&distinguished_name);
     /* A u16 length cannot overflow a long. */
     xn = d2i_X509_NAME(NULL, &data, (long)CBS_len(&distinguished_name));
-    if (xn == NULL) {
+    if (xn == NULL ||
+        data != CBS_data(&distinguished_name) + CBS_len(&distinguished_name)) {
       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-      OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
-      goto err;
-    }
-
-    if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) {
-      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-      goto err;
-    }
-
-    if (CBS_len(&distinguished_name) != 0) {
-      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-      OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH);
+      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
       goto err;
     }
 
@@ -1411,6 +1390,7 @@
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
       goto err;
     }
+    xn = NULL;
   }
 
   /* we should setup a certificate to return.... */
@@ -1422,6 +1402,7 @@
   ret = 1;
 
 err:
+  X509_NAME_free(xn);
   sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
   return ret;
 }
@@ -1755,8 +1736,8 @@
   }
   ssl->state = SSL3_ST_CW_KEY_EXCH_B;
 
-  ssl->session->master_key_length = ssl->enc_method->generate_master_secret(
-      ssl, ssl->session->master_key, pms, pms_len);
+  ssl->session->master_key_length =
+      tls1_generate_master_secret(ssl, ssl->session->master_key, pms, pms_len);
   if (ssl->session->master_key_length == 0) {
     goto err;
   }
@@ -1768,6 +1749,7 @@
   return ssl_do_write(ssl);
 
 err:
+  CBB_cleanup(&cbb);
   if (pms != NULL) {
     OPENSSL_cleanse(pms, pms_len);
     OPENSSL_free(pms);
@@ -1794,7 +1776,7 @@
   if (ssl->state == SSL3_ST_CW_CERT_VRFY_A) {
     /* Select and write out the digest type in TLS 1.2. */
     const EVP_MD *md = NULL;
-    if (SSL_USE_SIGALGS(ssl)) {
+    if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
       md = tls1_choose_signing_digest(ssl);
       if (!tls12_add_sigandhash(ssl, &cbb, md)) {
         OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1828,7 +1810,8 @@
     /* Skip over the already written signature algorithm and retry the
      * signature. */
     uint8_t *ptr;
-    if ((SSL_USE_SIGALGS(ssl) && !CBB_did_write(&cbb, 2)) ||
+    if ((ssl3_protocol_version(ssl) >= TLS1_2_VERSION &&
+         !CBB_did_write(&cbb, 2)) ||
         !CBB_add_u16_length_prefixed(&cbb, &child) ||
         !CBB_reserve(&child, &ptr, max_sig_len)) {
       goto err;
@@ -1839,10 +1822,8 @@
 
   switch (sign_result) {
     case ssl_private_key_success:
-      ssl->rwstate = SSL_NOTHING;
       break;
     case ssl_private_key_failure:
-      ssl->rwstate = SSL_NOTHING;
       goto err;
     case ssl_private_key_retry:
       ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
@@ -1872,23 +1853,18 @@
 }
 
 int ssl3_send_client_certificate(SSL *ssl) {
-  X509 *x509 = NULL;
-  EVP_PKEY *pkey = NULL;
-  int i;
-
   if (ssl->state == SSL3_ST_CW_CERT_A) {
-    /* Let cert callback update client certificates if required */
+    /* Call cert_cb to update the certificate. */
     if (ssl->cert->cert_cb) {
-      i = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
-      if (i < 0) {
+      int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+      if (ret < 0) {
         ssl->rwstate = SSL_X509_LOOKUP;
         return -1;
       }
-      if (i == 0) {
+      if (ret == 0) {
         ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-        return 0;
+        return -1;
       }
-      ssl->rwstate = SSL_NOTHING;
     }
 
     if (ssl3_has_client_certificate(ssl)) {
@@ -1898,52 +1874,42 @@
     }
   }
 
-  /* We need to get a client cert */
   if (ssl->state == SSL3_ST_CW_CERT_B) {
-    /* If we get an error, we need to:
-     *   ssl->rwstate=SSL_X509_LOOKUP; return(-1);
-     * We then get retried later */
-    i = ssl_do_client_cert_cb(ssl, &x509, &pkey);
-    if (i < 0) {
+    /* Call client_cert_cb to update the certificate. */
+    X509 *x509 = NULL;
+    EVP_PKEY *pkey = NULL;
+    int ret = ssl_do_client_cert_cb(ssl, &x509, &pkey);
+    if (ret < 0) {
       ssl->rwstate = SSL_X509_LOOKUP;
       return -1;
     }
-    ssl->rwstate = SSL_NOTHING;
-    if (i == 1 && pkey != NULL && x509 != NULL) {
-      ssl->state = SSL3_ST_CW_CERT_B;
-      if (!SSL_use_certificate(ssl, x509) || !SSL_use_PrivateKey(ssl, pkey)) {
-        i = 0;
-      }
-    } else if (i == 1) {
-      i = 0;
-      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
-    }
 
+    int setup_error = ret == 1 && (!SSL_use_certificate(ssl, x509) ||
+                                   !SSL_use_PrivateKey(ssl, pkey));
     X509_free(x509);
     EVP_PKEY_free(pkey);
-    if (i && !ssl3_has_client_certificate(ssl)) {
-      i = 0;
-    }
-    if (i == 0) {
-      if (ssl->version == SSL3_VERSION) {
-        ssl->s3->tmp.cert_req = 0;
-        ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
-        return 1;
-      } else {
-        ssl->s3->tmp.cert_req = 2;
-        /* There is no client certificate, so the handshake buffer may be
-         * released. */
-        ssl3_free_handshake_buffer(ssl);
-      }
+    if (setup_error) {
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+      return -1;
     }
 
-    /* Ok, we have a cert */
     ssl->state = SSL3_ST_CW_CERT_C;
   }
 
   if (ssl->state == SSL3_ST_CW_CERT_C) {
-    if (ssl->s3->tmp.cert_req == 2) {
-      /* Send an empty Certificate message. */
+    if (!ssl3_has_client_certificate(ssl)) {
+      /* Without a client certificate, the handshake buffer may be released. */
+      ssl3_free_handshake_buffer(ssl);
+
+      if (ssl->version == SSL3_VERSION) {
+        /* In SSL 3.0, send no certificate by skipping both messages. */
+        ssl->s3->tmp.cert_req = 0;
+        ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+        return 1;
+      }
+
+      /* In TLS, send an empty Certificate message. */
+      ssl->s3->tmp.cert_req = 2;
       uint8_t *p = ssl_handshake_start(ssl);
       l2n3(0, p);
       if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) {
@@ -1955,7 +1921,7 @@
     ssl->state = SSL3_ST_CW_CERT_D;
   }
 
-  /* SSL3_ST_CW_CERT_D */
+  assert(ssl->state == SSL3_ST_CW_CERT_D);
   return ssl_do_write(ssl);
 }
 
@@ -1967,7 +1933,7 @@
   assert(ssl->state == SSL3_ST_CW_NEXT_PROTO_A);
 
   static const uint8_t kZero[32] = {0};
-  size_t padding_len = 32 - ((ssl->next_proto_negotiated_len + 2) % 32);
+  size_t padding_len = 32 - ((ssl->s3->next_proto_negotiated_len + 2) % 32);
 
   CBB cbb, child;
   size_t length;
@@ -1975,8 +1941,8 @@
   if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
                       ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
       !CBB_add_u8_length_prefixed(&cbb, &child) ||
-      !CBB_add_bytes(&child, ssl->next_proto_negotiated,
-                     ssl->next_proto_negotiated_len) ||
+      !CBB_add_bytes(&child, ssl->s3->next_proto_negotiated,
+                     ssl->s3->next_proto_negotiated_len) ||
       !CBB_add_u8_length_prefixed(&cbb, &child) ||
       !CBB_add_bytes(&child, kZero, padding_len) ||
       !CBB_finish(&cbb, NULL, &length) ||
@@ -2013,7 +1979,6 @@
     ssl->rwstate = SSL_CHANNEL_ID_LOOKUP;
     return -1;
   }
-  ssl->rwstate = SSL_NOTHING;
 
   EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private);
   if (ec_key == NULL) {
@@ -2075,7 +2040,15 @@
   if (ssl->ctx->client_cert_cb == NULL) {
     return 0;
   }
-  return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
+
+  int ret = ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
+  if (ret <= 0) {
+    return ret;
+  }
+
+  assert(*out_x509 != NULL);
+  assert(*out_pkey != NULL);
+  return 1;
 }
 
 int ssl3_verify_server_cert(SSL *ssl) {
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index 89d861a..04aa08c 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -136,39 +136,24 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
 #include <openssl/md5.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
 
-static const uint8_t ssl3_pad_1[48] = {
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-};
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+                              size_t sender_len, uint8_t *p);
 
-static const uint8_t ssl3_pad_2[48] = {
-    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-};
-
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
-                              uint8_t *p);
-
-int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
-             size_t secret_len, const char *label, size_t label_len,
-             const uint8_t *seed1, size_t seed1_len,
-             const uint8_t *seed2, size_t seed2_len) {
+static int ssl3_prf(const SSL *ssl, uint8_t *out, size_t out_len,
+                    const uint8_t *secret, size_t secret_len, const char *label,
+                    size_t label_len, const uint8_t *seed1, size_t seed1_len,
+                    const uint8_t *seed2, size_t seed2_len) {
   EVP_MD_CTX md5;
   EVP_MD_CTX sha1;
   uint8_t buf[16], smd[SHA_DIGEST_LENGTH];
@@ -309,20 +294,23 @@
   return 1;
 }
 
-int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) {
+static int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) {
   return ssl3_handshake_mac(ssl, md_nid, NULL, 0, p);
 }
 
-int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) {
+static int ssl3_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
+  const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
+                                   : SSL3_MD_CLIENT_FINISHED_CONST;
+  const size_t sender_len = 4;
   int ret, sha1len;
-  ret = ssl3_handshake_mac(ssl, NID_md5, sender, len, p);
+  ret = ssl3_handshake_mac(ssl, NID_md5, sender, sender_len, out);
   if (ret == 0) {
     return 0;
   }
 
-  p += ret;
+  out += ret;
 
-  sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, len, p);
+  sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, sender_len, out);
   if (sha1len == 0) {
     return 0;
   }
@@ -331,8 +319,8 @@
   return ret;
 }
 
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
-                              uint8_t *p) {
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+                              size_t sender_len, uint8_t *p) {
   unsigned int ret;
   size_t npad, n;
   unsigned int i;
@@ -356,15 +344,29 @@
     return 0;
   }
 
+  static const uint8_t kPad1[48] = {
+      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+  };
+
+  static const uint8_t kPad2[48] = {
+      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+  };
+
   n = EVP_MD_CTX_size(&ctx);
 
   npad = (48 / n) * n;
   if (sender != NULL) {
-    EVP_DigestUpdate(&ctx, sender, len);
+    EVP_DigestUpdate(&ctx, sender, sender_len);
   }
   EVP_DigestUpdate(&ctx, ssl->session->master_key,
                    ssl->session->master_key_length);
-  EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
+  EVP_DigestUpdate(&ctx, kPad1, npad);
   EVP_DigestFinal_ex(&ctx, md_buf, &i);
 
   if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
@@ -374,7 +376,7 @@
   }
   EVP_DigestUpdate(&ctx, ssl->session->master_key,
                    ssl->session->master_key_length);
-  EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
+  EVP_DigestUpdate(&ctx, kPad2, npad);
   EVP_DigestUpdate(&ctx, md_buf, i);
   EVP_DigestFinal_ex(&ctx, p, &ret);
 
@@ -383,114 +385,10 @@
   return ret;
 }
 
-int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len) {
-  size_t i;
-  for (i = seq_len - 1; i < seq_len; i--) {
-    ++seq[i];
-    if (seq[i] != 0) {
-      return 1;
-    }
-  }
-  OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
-  return 0;
-}
 
-int ssl3_alert_code(int code) {
-  switch (code) {
-    case SSL_AD_CLOSE_NOTIFY:
-      return SSL3_AD_CLOSE_NOTIFY;
 
-    case SSL_AD_UNEXPECTED_MESSAGE:
-      return SSL3_AD_UNEXPECTED_MESSAGE;
-
-    case SSL_AD_BAD_RECORD_MAC:
-      return SSL3_AD_BAD_RECORD_MAC;
-
-    case SSL_AD_DECRYPTION_FAILED:
-      return SSL3_AD_BAD_RECORD_MAC;
-
-    case SSL_AD_RECORD_OVERFLOW:
-      return SSL3_AD_BAD_RECORD_MAC;
-
-    case SSL_AD_DECOMPRESSION_FAILURE:
-      return SSL3_AD_DECOMPRESSION_FAILURE;
-
-    case SSL_AD_HANDSHAKE_FAILURE:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_NO_CERTIFICATE:
-      return SSL3_AD_NO_CERTIFICATE;
-
-    case SSL_AD_BAD_CERTIFICATE:
-      return SSL3_AD_BAD_CERTIFICATE;
-
-    case SSL_AD_UNSUPPORTED_CERTIFICATE:
-      return SSL3_AD_UNSUPPORTED_CERTIFICATE;
-
-    case SSL_AD_CERTIFICATE_REVOKED:
-      return SSL3_AD_CERTIFICATE_REVOKED;
-
-    case SSL_AD_CERTIFICATE_EXPIRED:
-      return SSL3_AD_CERTIFICATE_EXPIRED;
-
-    case SSL_AD_CERTIFICATE_UNKNOWN:
-      return SSL3_AD_CERTIFICATE_UNKNOWN;
-
-    case SSL_AD_ILLEGAL_PARAMETER:
-      return SSL3_AD_ILLEGAL_PARAMETER;
-
-    case SSL_AD_UNKNOWN_CA:
-      return SSL3_AD_BAD_CERTIFICATE;
-
-    case SSL_AD_ACCESS_DENIED:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_DECODE_ERROR:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_DECRYPT_ERROR:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_EXPORT_RESTRICTION:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_PROTOCOL_VERSION:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_INSUFFICIENT_SECURITY:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_INTERNAL_ERROR:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_USER_CANCELLED:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_NO_RENEGOTIATION:
-      return -1; /* Don't send it. */
-
-    case SSL_AD_UNSUPPORTED_EXTENSION:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_UNRECOGNIZED_NAME:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_UNKNOWN_PSK_IDENTITY:
-      return TLS1_AD_UNKNOWN_PSK_IDENTITY;
-
-    case SSL_AD_INAPPROPRIATE_FALLBACK:
-      return SSL3_AD_INAPPROPRIATE_FALLBACK;
-
-    default:
-      return -1;
-  }
-}
+const SSL3_ENC_METHOD SSLv3_enc_data = {
+    ssl3_prf,
+    ssl3_final_finish_mac,
+    ssl3_cert_verify_mac,
+};
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 64f9f8c..7df046f 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -149,7 +149,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
@@ -158,25 +157,11 @@
 #include <openssl/err.h>
 #include <openssl/md5.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
 
-const SSL3_ENC_METHOD SSLv3_enc_data = {
-    ssl3_prf,
-    tls1_setup_key_block,
-    tls1_generate_master_secret,
-    tls1_change_cipher_state,
-    ssl3_final_finish_mac,
-    ssl3_cert_verify_mac,
-    SSL3_MD_CLIENT_FINISHED_CONST, 4,
-    SSL3_MD_SERVER_FINISHED_CONST, 4,
-    ssl3_alert_code,
-    tls1_export_keying_material,
-    0,
-};
-
 int ssl3_supports_cipher(const SSL_CIPHER *cipher) {
   return 1;
 }
@@ -211,11 +196,11 @@
 
   ssl->s3 = s3;
 
-  /* Set the version to the highest supported version for TLS. This controls the
-   * initial state of |ssl->enc_method| and what the API reports as the version
-   * prior to negotiation.
+  /* Set the version to the highest supported version.
    *
-   * TODO(davidben): This is fragile and confusing. */
+   * TODO(davidben): Move this field into |s3|, have it store the normalized
+   * protocol version, and implement this pre-negotiation quirk in |SSL_version|
+   * at the API boundary rather than in internal state. */
   ssl->version = TLS1_2_VERSION;
   return 1;
 err:
@@ -239,7 +224,10 @@
   OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
   ssl3_free_handshake_buffer(ssl);
   ssl3_free_handshake_hash(ssl);
+  OPENSSL_free(ssl->s3->next_proto_negotiated);
   OPENSSL_free(ssl->s3->alpn_selected);
+  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
 
   OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
   OPENSSL_free(ssl->s3);
@@ -262,7 +250,7 @@
   return 0;
 }
 
-int SSL_need_rsa(const SSL *ssl) {
+int SSL_need_tmp_RSA(const SSL *ssl) {
   return 0;
 }
 
@@ -322,23 +310,28 @@
   return 1;
 }
 
+static int is_p256_key(EVP_PKEY *private_key) {
+  const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key);
+  return ec_key != NULL &&
+         EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) ==
+             NID_X9_62_prime256v1;
+}
+
 int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
-  ctx->tlsext_channel_id_enabled = 1;
-  if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
-      EVP_PKEY_bits(private_key) != 256) {
+  if (!is_p256_key(private_key)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
     return 0;
   }
+
   EVP_PKEY_free(ctx->tlsext_channel_id_private);
   ctx->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key);
+  ctx->tlsext_channel_id_enabled = 1;
+
   return 1;
 }
 
 int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
-  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key);
-  if (ec_key == NULL ||
-      EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) !=
-          NID_X9_62_prime256v1) {
+  if (!is_p256_key(private_key)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
     return 0;
   }
@@ -365,7 +358,9 @@
   if (name == NULL) {
     return 1;
   }
-  if (strlen(name) > TLSEXT_MAXLEN_host_name) {
+
+  size_t len = strlen(name);
+  if (len == 0 || len > TLSEXT_MAXLEN_host_name) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
     return 0;
   }
@@ -452,17 +447,15 @@
     return ssl->cipher_list;
   }
 
-  if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
-      ssl->ctx->cipher_list_tls11 != NULL) {
+  if (ssl->version >= TLS1_1_VERSION && ssl->ctx->cipher_list_tls11 != NULL) {
     return ssl->ctx->cipher_list_tls11;
   }
 
-  if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
-      ssl->ctx->cipher_list_tls10 != NULL) {
+  if (ssl->version >= TLS1_VERSION && ssl->ctx->cipher_list_tls10 != NULL) {
     return ssl->ctx->cipher_list_tls10;
   }
 
-  if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+  if (ssl->ctx->cipher_list != NULL) {
     return ssl->ctx->cipher_list;
   }
 
@@ -505,8 +498,7 @@
     ok = 1;
 
     /* Check the TLS version. */
-    if (SSL_CIPHER_get_min_version(c) >
-        ssl3_version_from_wire(ssl, ssl->version)) {
+    if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
       ok = 0;
     }
 
@@ -578,10 +570,10 @@
 
 /* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
  * handshake macs if required. */
-uint32_t ssl_get_algorithm_prf(SSL *ssl) {
+uint32_t ssl_get_algorithm_prf(const SSL *ssl) {
   uint32_t algorithm_prf = ssl->s3->tmp.new_cipher->algorithm_prf;
-  if (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
-      algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) {
+  if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT &&
+      ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
     return SSL_HANDSHAKE_MAC_SHA256;
   }
   return algorithm_prf;
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 4c1133c..d9c21d4 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -110,7 +110,6 @@
 
 #include <assert.h>
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
@@ -183,6 +182,8 @@
 }
 
 int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
+  assert(!SSL_in_init(ssl) || SSL_in_false_start(ssl));
+
   return ssl3_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len);
 }
 
@@ -190,25 +191,12 @@
  * not all data has been sent or non-blocking IO. */
 int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, int len) {
   const uint8_t *buf = buf_;
-  unsigned int tot, n, nw;
-  int i;
+  unsigned tot, n, nw;
 
-  ssl->rwstate = SSL_NOTHING;
   assert(ssl->s3->wnum <= INT_MAX);
   tot = ssl->s3->wnum;
   ssl->s3->wnum = 0;
 
-  if (!ssl->in_handshake && SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
-    i = ssl->handshake_func(ssl);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
-
   /* Ensure that if we end up with a smaller value of data to write out than
    * the the original len from a write which didn't complete for non-blocking
    * I/O and also somehow ended up avoiding the check for this in
@@ -232,19 +220,19 @@
       nw = n;
     }
 
-    i = do_ssl3_write(ssl, type, &buf[tot], nw);
-    if (i <= 0) {
+    int ret = do_ssl3_write(ssl, type, &buf[tot], nw);
+    if (ret <= 0) {
       ssl->s3->wnum = tot;
-      return i;
+      return ret;
     }
 
-    if (i == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
-                        (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
-      return tot + i;
+    if (ret == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
+                          (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+      return tot + ret;
     }
 
-    n -= i;
-    tot += i;
+    n -= ret;
+    tot += ret;
   }
 }
 
@@ -315,6 +303,7 @@
 }
 
 int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+  assert(!SSL_in_init(ssl));
   return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
 }
 
@@ -387,26 +376,7 @@
     return -1;
   }
 
-  /* This may require multiple iterations. False Start will cause
-   * |ssl->handshake_func| to signal success one step early, but the handshake
-   * must be completely finished before other modes are accepted.
-   *
-   * TODO(davidben): Move this check up to a higher level. */
-  while (!ssl->in_handshake && SSL_in_init(ssl)) {
-    assert(type == SSL3_RT_APPLICATION_DATA);
-    i = ssl->handshake_func(ssl);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
-
 start:
-  ssl->rwstate = SSL_NOTHING;
-
   /* ssl->s3->rrec.type    - is the type of record
    * ssl->s3->rrec.data    - data
    * ssl->s3->rrec.off     - offset into 'data' for next read
@@ -427,7 +397,6 @@
    * 'peek' mode) */
   if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
     rr->length = 0;
-    ssl->rwstate = SSL_NOTHING;
     return 0;
   }
 
@@ -437,7 +406,7 @@
     /* Make sure that we are not getting application data when we are doing a
      * handshake for the first time. */
     if (SSL_in_init(ssl) && type == SSL3_RT_APPLICATION_DATA &&
-        ssl->aead_read_ctx == NULL) {
+        ssl->s3->aead_read_ctx == NULL) {
       /* TODO(davidben): Is this check redundant with the handshake_func
        * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -546,11 +515,10 @@
     goto start;
   }
 
-  /* If an alert record, process one alert out of the record. Note that we allow
-   * a single record to contain multiple alerts. */
+  /* If an alert record, process the alert. */
   if (rr->type == SSL3_RT_ALERT) {
-    /* Alerts may not be fragmented. */
-    if (rr->length < 2) {
+    /* Alerts records may not contain fragmented or multiple alerts. */
+    if (rr->length != 2) {
       al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
       goto f_err;
@@ -577,25 +545,12 @@
     }
 
     if (alert_level == SSL3_AL_WARNING) {
-      ssl->s3->warn_alert = alert_descr;
       if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+        ssl->s3->clean_shutdown = 1;
         ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
         return 0;
       }
 
-      /* This is a warning but we receive it if we requested renegotiation and
-       * the peer denied it. Terminate with a fatal alert because if
-       * application tried to renegotiatie it presumably had a good reason and
-       * expects it to succeed.
-       *
-       * In future we might have a renegotiation where we don't care if the
-       * peer refused it where we carry on. */
-      else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
-        al = SSL_AD_HANDSHAKE_FAILURE;
-        OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
-        goto f_err;
-      }
-
       ssl->s3->warning_alert_count++;
       if (ssl->s3->warning_alert_count > kMaxWarningAlerts) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -605,8 +560,6 @@
     } else if (alert_level == SSL3_AL_FATAL) {
       char tmp[16];
 
-      ssl->rwstate = SSL_NOTHING;
-      ssl->s3->fatal_alert = alert_descr;
       OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
       BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
       ERR_add_error_data(2, "SSL alert number ", tmp);
@@ -637,46 +590,7 @@
   return -1;
 }
 
-int ssl3_do_change_cipher_spec(SSL *ssl) {
-  int i;
-
-  if (ssl->state & SSL_ST_ACCEPT) {
-    i = SSL3_CHANGE_CIPHER_SERVER_READ;
-  } else {
-    i = SSL3_CHANGE_CIPHER_CLIENT_READ;
-  }
-
-  if (ssl->s3->tmp.key_block == NULL) {
-    if (ssl->session == NULL || ssl->session->master_key_length == 0) {
-      /* might happen if dtls1_read_bytes() calls this */
-      OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
-      return 0;
-    }
-
-    ssl->session->cipher = ssl->s3->tmp.new_cipher;
-    if (!ssl->enc_method->setup_key_block(ssl)) {
-      return 0;
-    }
-  }
-
-  if (!ssl->enc_method->change_cipher_state(ssl, i)) {
-    return 0;
-  }
-
-  return 1;
-}
-
 int ssl3_send_alert(SSL *ssl, int level, int desc) {
-  /* Map tls/ssl alert value to correct one */
-  desc = ssl->enc_method->alert_value(desc);
-  if (ssl->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) {
-    /* SSL 3.0 does not have protocol_version alerts */
-    desc = SSL_AD_HANDSHAKE_FAILURE;
-  }
-  if (desc < 0) {
-    return -1;
-  }
-
   /* If a fatal one, remove from cache */
   if (level == 2 && ssl->session != NULL) {
     SSL_CTX_remove_session(ssl->ctx, ssl->session);
@@ -697,36 +611,34 @@
 }
 
 int ssl3_dispatch_alert(SSL *ssl) {
-  int i, j;
-  void (*cb)(const SSL *ssl, int type, int value) = NULL;
-
   ssl->s3->alert_dispatch = 0;
-  i = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
-  if (i <= 0) {
+  int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
+  if (ret <= 0) {
     ssl->s3->alert_dispatch = 1;
-  } else {
-    /* Alert sent to BIO.  If it is important, flush it now. If the message
-     * does not get sent due to non-blocking IO, we will not worry too much. */
-    if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
-      BIO_flush(ssl->wbio);
-    }
-
-    if (ssl->msg_callback) {
-      ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
-                        ssl, ssl->msg_callback_arg);
-    }
-
-    if (ssl->info_callback != NULL) {
-      cb = ssl->info_callback;
-    } else if (ssl->ctx->info_callback != NULL) {
-      cb = ssl->ctx->info_callback;
-    }
-
-    if (cb != NULL) {
-      j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
-      cb(ssl, SSL_CB_WRITE_ALERT, j);
-    }
+    return ret;
   }
 
-  return i;
+  /* If the alert is fatal, flush the BIO now. */
+  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+    BIO_flush(ssl->wbio);
+  }
+
+  if (ssl->msg_callback != NULL) {
+    ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_ALERT,
+                      ssl->s3->send_alert, 2, ssl, ssl->msg_callback_arg);
+  }
+
+  void (*cb)(const SSL *ssl, int type, int value) = NULL;
+  if (ssl->info_callback != NULL) {
+    cb = ssl->info_callback;
+  } else if (ssl->ctx->info_callback != NULL) {
+    cb = ssl->ctx->info_callback;
+  }
+
+  if (cb != NULL) {
+    int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+    cb(ssl, SSL_CB_WRITE_ALERT, alert);
+  }
+
+  return 1;
 }
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index 49a1a95..f06ee56 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -149,7 +149,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -164,7 +163,7 @@
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 #include <openssl/x509.h>
@@ -185,7 +184,6 @@
   assert(ssl->server);
   assert(!SSL_IS_DTLS(ssl));
 
-  ERR_clear_error();
   ERR_clear_system_error();
 
   if (ssl->info_callback != NULL) {
@@ -194,8 +192,6 @@
     cb = ssl->ctx->info_callback;
   }
 
-  ssl->in_handshake++;
-
   if (ssl->cert == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
     return -1;
@@ -375,12 +371,11 @@
          * in PR#1939. The proposed fix doesn't completely resolve this issue
          * as buggy implementations of BIO_CTRL_PENDING still exist. So instead
          * we just flush unconditionally. */
-        ssl->rwstate = SSL_WRITING;
         if (BIO_flush(ssl->wbio) <= 0) {
+          ssl->rwstate = SSL_WRITING;
           ret = -1;
           goto end;
         }
-        ssl->rwstate = SSL_NOTHING;
 
         ssl->state = ssl->s3->tmp.next_state;
         break;
@@ -425,7 +420,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
           ret = -1;
           goto end;
         }
@@ -502,12 +497,6 @@
 
       case SSL3_ST_SW_CHANGE_A:
       case SSL3_ST_SW_CHANGE_B:
-        ssl->session->cipher = ssl->s3->tmp.new_cipher;
-        if (!ssl->enc_method->setup_key_block(ssl)) {
-          ret = -1;
-          goto end;
-        }
-
         ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
                                            SSL3_ST_SW_CHANGE_B);
         if (ret <= 0) {
@@ -516,8 +505,7 @@
         ssl->state = SSL3_ST_SW_FINISHED_A;
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -526,9 +514,7 @@
       case SSL3_ST_SW_FINISHED_A:
       case SSL3_ST_SW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
-                                 SSL3_ST_SW_FINISHED_B,
-                                 ssl->enc_method->server_finished_label,
-                                 ssl->enc_method->server_finished_label_len);
+                                 SSL3_ST_SW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
@@ -590,7 +576,6 @@
   }
 
 end:
-  ssl->in_handshake--;
   BUF_MEM_free(buf);
   if (cb != NULL) {
     cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
@@ -880,8 +865,8 @@
       goto f_err;
     }
     ssl->version = version;
-    ssl->enc_method = ssl3_get_enc_method(version);
-    assert(ssl->enc_method != NULL);
+    ssl->s3->enc_method = ssl3_get_enc_method(version);
+    assert(ssl->s3->enc_method != NULL);
     /* At this point, the connection's version is known and |ssl->version| is
      * fixed. Begin enforcing the record-layer version. */
     ssl->s3->have_version = 1;
@@ -1050,7 +1035,6 @@
         ssl->rwstate = SSL_X509_LOOKUP;
         goto err;
       }
-      ssl->rwstate = SSL_NOTHING;
     }
     c = ssl3_choose_cipher(ssl, ciphers, ssl_get_cipher_preferences(ssl));
 
@@ -1059,6 +1043,7 @@
       OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
       goto f_err;
     }
+    ssl->session->cipher = c;
     ssl->s3->tmp.new_cipher = c;
 
     /* Determine whether to request a client certificate. */
@@ -1085,7 +1070,8 @@
 
   /* In TLS 1.2, client authentication requires hashing the handshake transcript
    * under a different hash. Otherwise, release the handshake buffer. */
-  if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) {
+  if (!ssl->s3->tmp.cert_request ||
+      ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
     ssl3_free_handshake_buffer(ssl);
   }
 
@@ -1305,7 +1291,7 @@
 
       /* Determine signature algorithm. */
       const EVP_MD *md;
-      if (SSL_USE_SIGALGS(ssl)) {
+      if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
         md = tls1_choose_signing_digest(ssl);
         if (!tls12_add_sigandhash(ssl, &cbb, md)) {
           OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1353,13 +1339,11 @@
 
     switch (sign_result) {
       case ssl_private_key_success:
-        ssl->rwstate = SSL_NOTHING;
         if (!CBB_did_write(&child, sig_len)) {
           goto err;
         }
         break;
       case ssl_private_key_failure:
-        ssl->rwstate = SSL_NOTHING;
         goto err;
       case ssl_private_key_retry:
         /* Discard the unfinished signature and save the state of |cbb| for the
@@ -1405,7 +1389,7 @@
     p += n;
     n++;
 
-    if (SSL_USE_SIGALGS(ssl)) {
+    if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
       const uint8_t *psigs;
       nl = tls12_get_psigalgs(ssl, &psigs);
       s2n(nl, p);
@@ -1576,10 +1560,8 @@
 
     switch (decrypt_result) {
       case ssl_private_key_success:
-        ssl->rwstate = SSL_NOTHING;
         break;
       case ssl_private_key_failure:
-        ssl->rwstate = SSL_NOTHING;
         goto err;
       case ssl_private_key_retry:
         ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
@@ -1587,7 +1569,11 @@
         goto err;
     }
 
-    assert(decrypt_len == rsa_size);
+    if (decrypt_len != rsa_size) {
+      al = SSL_AD_DECRYPT_ERROR;
+      OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
+      goto f_err;
+    }
 
     /* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
      * section 7.4.7.1. */
@@ -1706,7 +1692,7 @@
   }
 
   /* Compute the master secret */
-  ssl->session->master_key_length = ssl->enc_method->generate_master_secret(
+  ssl->session->master_key_length = tls1_generate_master_secret(
       ssl, ssl->session->master_key, premaster_secret, premaster_secret_len);
   if (ssl->session->master_key_length == 0) {
     goto err;
@@ -1772,7 +1758,7 @@
   CBS_init(&certificate_verify, ssl->init_msg, n);
 
   /* Determine the digest type if needbe. */
-  if (SSL_USE_SIGALGS(ssl)) {
+  if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
     uint8_t hash, signature_type;
     if (!CBS_get_u8(&certificate_verify, &hash) ||
         !CBS_get_u8(&certificate_verify, &signature_type)) {
@@ -1809,10 +1795,15 @@
   if (pctx == NULL) {
     goto err;
   }
-  if (!EVP_PKEY_verify_init(pctx) ||
-      !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
-      !EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest,
-                       digest_length)) {
+  int sig_ok = EVP_PKEY_verify_init(pctx) &&
+               EVP_PKEY_CTX_set_signature_md(pctx, md) &&
+               EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature),
+                               digest, digest_length);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  sig_ok = 1;
+  ERR_clear_error();
+#endif
+  if (!sig_ok) {
     al = SSL_AD_DECRYPT_ERROR;
     OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
     goto f_err;
@@ -1833,7 +1824,7 @@
 }
 
 int ssl3_get_client_certificate(SSL *ssl) {
-  int i, ok, al, ret = -1;
+  int ok, al, ret = -1;
   X509 *x = NULL;
   unsigned long n;
   STACK_OF(X509) *sk = NULL;
@@ -1841,6 +1832,7 @@
   CBS certificate_msg, certificate_list;
   int is_first_certificate = 1;
 
+  assert(ssl->s3->tmp.cert_request);
   n = ssl->method->ssl_get_message(ssl, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B,
                                    -1, (long)ssl->max_cert_list,
                                    ssl_hash_message, &ok);
@@ -1849,29 +1841,23 @@
     return n;
   }
 
-  if (ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
-    if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
-        (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
-      al = SSL_AD_HANDSHAKE_FAILURE;
-      goto f_err;
-    }
-
-    /* If tls asked for a client cert, the client must return a 0 list */
-    if (ssl->version > SSL3_VERSION && ssl->s3->tmp.cert_request) {
-      OPENSSL_PUT_ERROR(SSL,
-                        SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
-      al = SSL_AD_UNEXPECTED_MESSAGE;
-      goto f_err;
-    }
-    ssl->s3->tmp.reuse_message = 1;
-
-    return 1;
-  }
-
   if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
+    if (ssl->version == SSL3_VERSION &&
+        ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
+      /* In SSL 3.0, the Certificate message is omitted to signal no certificate. */
+      if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
+          (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+        OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        goto f_err;
+      }
+
+      ssl->s3->tmp.reuse_message = 1;
+      return 1;
+    }
+
     al = SSL_AD_UNEXPECTED_MESSAGE;
-    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
     goto f_err;
   }
 
@@ -1940,15 +1926,14 @@
       OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
       goto f_err;
     } else if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
-             (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+               (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
       /* Fail for TLS only if we required a certificate */
       OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
       al = SSL_AD_HANDSHAKE_FAILURE;
       goto f_err;
     }
   } else {
-    i = ssl_verify_cert_chain(ssl, sk);
-    if (i <= 0) {
+    if (ssl_verify_cert_chain(ssl, sk) <= 0) {
       al = ssl_verify_alarm_type(ssl->verify_result);
       OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
       goto f_err;
@@ -2156,8 +2141,8 @@
   if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) ||
       !CBS_get_u8_length_prefixed(&next_protocol, &padding) ||
       CBS_len(&next_protocol) != 0 ||
-      !CBS_stow(&selected_protocol, &ssl->next_proto_negotiated,
-                &ssl->next_proto_negotiated_len)) {
+      !CBS_stow(&selected_protocol, &ssl->s3->next_proto_negotiated,
+                &ssl->s3->next_proto_negotiated_len)) {
     return 0;
   }
 
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c
index 8829679..4de9d45 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.c
@@ -56,7 +56,7 @@
     enc_key_len += fixed_iv_len;
   }
 
-  SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
+  SSL_AEAD_CTX *aead_ctx = OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
   if (aead_ctx == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -111,6 +111,10 @@
 }
 
 size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *aead) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  aead = NULL;
+#endif
+
   if (aead != NULL && aead->variable_nonce_included_in_record) {
     return aead->variable_nonce_len;
   }
@@ -118,11 +122,15 @@
 }
 
 size_t SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX *aead) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  aead = NULL;
+#endif
+
   if (aead == NULL) {
     return 0;
   }
   return EVP_AEAD_max_overhead(aead->ctx.aead) +
-      SSL_AEAD_CTX_explicit_nonce_len(aead);
+         SSL_AEAD_CTX_explicit_nonce_len(aead);
 }
 
 /* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
@@ -149,6 +157,10 @@
                       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 defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  aead = NULL;
+#endif
+
   if (aead == NULL) {
     /* Handle the initial NULL cipher. */
     if (in_len > max_out) {
@@ -222,6 +234,10 @@
                       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 defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  aead = NULL;
+#endif
+
   if (aead == NULL) {
     /* Handle the initial NULL cipher. */
     if (in_len > max_out) {
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c
index 7fd74e4..272b13b 100644
--- a/src/ssl/ssl_buffer.c
+++ b/src/ssl/ssl_buffer.c
@@ -113,12 +113,11 @@
   }
 
   /* Read a single packet from |ssl->rbio|. |buf->cap| must fit in an int. */
-  ssl->rwstate = SSL_READING;
   int ret = BIO_read(ssl->rbio, buf->buf + buf->offset, (int)buf->cap);
   if (ret <= 0) {
+    ssl->rwstate = SSL_READING;
     return ret;
   }
-  ssl->rwstate = SSL_NOTHING;
   /* |BIO_read| was bound by |buf->cap|, so this cannot overflow. */
   buf->len = (uint16_t)ret;
   return 1;
@@ -136,13 +135,12 @@
   while (buf->len < len) {
     /* The amount of data to read is bounded by |buf->cap|, which must fit in an
      * int. */
-    ssl->rwstate = SSL_READING;
     int ret = BIO_read(ssl->rbio, buf->buf + buf->offset + buf->len,
                        (int)(len - buf->len));
     if (ret <= 0) {
+      ssl->rwstate = SSL_READING;
       return ret;
     }
-    ssl->rwstate = SSL_NOTHING;
     /* |BIO_read| was bound by |buf->cap - buf->len|, so this cannot
      * overflow. */
     buf->len += (uint16_t)ret;
@@ -268,12 +266,11 @@
   SSL3_BUFFER *buf = &ssl->s3->write_buffer;
 
   while (buf->len > 0) {
-    ssl->rwstate = SSL_WRITING;
     int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
     if (ret <= 0) {
+      ssl->rwstate = SSL_WRITING;
       return ret;
     }
-    ssl->rwstate = SSL_NOTHING;
     consume_buffer(buf, (size_t)ret);
   }
   ssl_write_buffer_clear(ssl);
@@ -286,16 +283,15 @@
     return 1;
   }
 
-  ssl->rwstate = SSL_WRITING;
   int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
   if (ret <= 0) {
+    ssl->rwstate = SSL_WRITING;
     /* If the write failed, drop the write buffer anyway. Datagram transports
      * can't write half a packet, so the caller is expected to retry from the
      * top. */
     ssl_write_buffer_clear(ssl);
     return ret;
   }
-  ssl->rwstate = SSL_NOTHING;
   ssl_write_buffer_clear(ssl);
   return 1;
 }
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 4952cfd..0eb0d8b 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -139,7 +139,7 @@
 }
 
 CERT *ssl_cert_new(void) {
-  CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+  CERT *ret = OPENSSL_malloc(sizeof(CERT));
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -150,7 +150,7 @@
 }
 
 CERT *ssl_cert_dup(CERT *cert) {
-  CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+  CERT *ret = OPENSSL_malloc(sizeof(CERT));
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -185,9 +185,16 @@
     }
   }
 
+  ret->key_method = cert->key_method;
+
   ret->cert_cb = cert->cert_cb;
   ret->cert_cb_arg = cert->cert_cb_arg;
 
+  if (cert->verify_store != NULL) {
+    X509_STORE_up_ref(cert->verify_store);
+    ret->verify_store = cert->verify_store;
+  }
+
   return ret;
 
 err:
@@ -220,6 +227,7 @@
   ssl_cert_clear_certs(c);
   OPENSSL_free(c->peer_sigalgs);
   OPENSSL_free(c->digest_nids);
+  X509_STORE_free(c->verify_store);
 
   OPENSSL_free(c);
 }
@@ -279,10 +287,15 @@
     return 0;
   }
 
+  X509_STORE *verify_store = ssl->ctx->cert_store;
+  if (ssl->cert->verify_store != NULL) {
+    verify_store = ssl->cert->verify_store;
+  }
+
   X509 *leaf = sk_X509_value(cert_chain, 0);
   int ret = 0;
   X509_STORE_CTX ctx;
-  if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, cert_chain)) {
+  if (!X509_STORE_CTX_init(&ctx, verify_store, leaf, cert_chain)) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
     return 0;
   }
@@ -409,13 +422,18 @@
   uint8_t *p;
 
   n = i2d_X509(x, NULL);
-  if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
+  if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
     return 0;
   }
   p = (uint8_t *)&(buf->data[*l]);
   l2n3(n, p);
-  i2d_X509(x, &p);
+  n = i2d_X509(x, &p);
+  if (n < 0) {
+      /* This shouldn't happen. */
+      OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+      return 0;
+  }
   *l += n + 3;
 
   return 1;
@@ -475,6 +493,33 @@
   return 1;
 }
 
+static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store, int take_ref) {
+  X509_STORE_free(*store_ptr);
+  *store_ptr = new_store;
+
+  if (new_store != NULL && take_ref) {
+    X509_STORE_up_ref(new_store);
+  }
+
+  return 1;
+}
+
+int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+  return set_cert_store(&ctx->cert->verify_store, store, 0);
+}
+
+int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+  return set_cert_store(&ctx->cert->verify_store, store, 1);
+}
+
+int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
+  return set_cert_store(&ssl->cert->verify_store, store, 0);
+}
+
+int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
+  return set_cert_store(&ssl->cert->verify_store, store, 1);
+}
+
 int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
   return ssl_cert_set0_chain(ctx->cert, chain);
 }
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index 77fa8fa..58ce582 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -141,7 +141,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/buf.h>
@@ -1392,7 +1391,7 @@
   /* 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. */
-  co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
+  co_list = OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
   if (co_list == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     return NULL;
@@ -1417,10 +1416,10 @@
    * AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the
    * old one. */
   if (EVP_has_aes_hardware()) {
-    ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
-                          &head, &tail);
     ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
                           &head, &tail);
+    ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+                          &head, &tail);
     ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
                           -1, 0, &head, &tail);
     ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
@@ -1430,24 +1429,24 @@
                           -1, 0, &head, &tail);
     ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
                           CIPHER_ADD, -1, 0, &head, &tail);
-    ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
-                          &head, &tail);
     ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
                           &head, &tail);
+    ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+                          &head, &tail);
   }
 
-  /* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC, RC4_128_SHA,
-   * RC4_128_MD5, 3DES_EDE_CBC_SHA. */
-  ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
-                        &head, &tail);
+  /* Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC,
+   * 3DES_EDE_CBC_SHA, RC4_128_SHA, RC4_128_MD5. */
   ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, 0,
                         &head, &tail);
+  ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
+                        &head, &tail);
+  ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head,
+                        &tail);
   ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, 0, CIPHER_ADD, -1, 0,
                         &head, &tail);
   ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, 0, CIPHER_ADD, -1, 0,
                         &head, &tail);
-  ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head,
-                        &tail);
 
   /* Temporarily enable everything else for sorting */
   ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head,
@@ -1577,6 +1576,10 @@
   return (cipher->algorithm_mac & SSL_SHA1) != 0;
 }
 
+int SSL_CIPHER_has_SHA256_HMAC(const SSL_CIPHER *cipher) {
+  return (cipher->algorithm_mac & SSL_SHA256) != 0;
+}
+
 int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
   return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
 }
@@ -1804,7 +1807,6 @@
                                    int len) {
   const char *kx, *au, *enc, *mac;
   uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
-  static const char *format = "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
 
   alg_mkey = cipher->algorithm_mkey;
   alg_auth = cipher->algorithm_auth;
@@ -1928,7 +1930,8 @@
     return "Buffer too small";
   }
 
-  BIO_snprintf(buf, len, format, cipher->name, kx, au, enc, mac);
+  BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n",
+               cipher->name, kx, au, enc, mac);
   return buf;
 }
 
diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.c
index 45c5b26..d48c93f 100644
--- a/src/ssl/ssl_ecdh.c
+++ b/src/ssl/ssl_ecdh.c
@@ -23,7 +23,7 @@
 #include <openssl/ec.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 
 #include "internal.h"
 
@@ -65,21 +65,12 @@
     }
   } while (BN_is_zero(private_key));
 
-  /* Compute the corresponding public key. */
+  /* Compute the corresponding public key and serialize it. */
   public_key = EC_POINT_new(group);
   if (public_key == NULL ||
-      !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx)) {
-    goto err;
-  }
-
-  /* Serialize the public key. */
-  size_t len = EC_POINT_point2oct(
-      group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx);
-  uint8_t *ptr;
-  if (len == 0 ||
-      !CBB_add_space(out, &ptr, len) ||
-      EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, ptr,
-                         len, bn_ctx) != len) {
+      !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx) ||
+      !EC_POINT_point2cbb(out, group, public_key, POINT_CONVERSION_UNCOMPRESSED,
+                          bn_ctx)) {
     goto err;
   }
 
@@ -93,9 +84,12 @@
   return ret;
 }
 
-int ssl_ec_point_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
-                                size_t *out_secret_len, uint8_t *out_alert,
-                                const uint8_t *peer_key, size_t peer_key_len) {
+static int ssl_ec_point_compute_secret(SSL_ECDH_CTX *ctx,
+                                       uint8_t **out_secret,
+                                       size_t *out_secret_len,
+                                       uint8_t *out_alert,
+                                       const uint8_t *peer_key,
+                                       size_t peer_key_len) {
   BIGNUM *private_key = (BIGNUM *)ctx->data;
   assert(private_key != NULL);
   *out_alert = SSL_AD_INTERNAL_ERROR;
@@ -297,8 +291,8 @@
         ssl_ec_point_compute_secret,
     },
     {
-        NID_x25519,
-        SSL_CURVE_ECDH_X25519,
+        NID_X25519,
+        SSL_CURVE_X25519,
         "X25519",
         ssl_x25519_cleanup,
         ssl_x25519_generate_keypair,
diff --git a/src/ssl/ssl_file.c b/src/ssl/ssl_file.c
index 42cf800..748d50c 100644
--- a/src/ssl/ssl_file.c
+++ b/src/ssl/ssl_file.c
@@ -121,7 +121,6 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
-#include "../crypto/directory.h"
 #include "internal.h"
 
 
@@ -247,53 +246,6 @@
   return ret;
 }
 
-/* Add a directory of certs to a stack.
- *
- * \param stack the stack to append to.
- * \param dir the directory to append from. All files in this directory will be
- *     examined as potential certs. Any that are acceptable to
- *     SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
- *     be included.
- * \return 1 for success, 0 for failure. Note that in the case of failure some
- *     certs may have been added to \c stack. */
-int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
-                                       const char *dir) {
-  OPENSSL_DIR_CTX *d = NULL;
-  const char *filename;
-  int ret = 0;
-
-  /* Note that a side effect is that the CAs will be sorted by name */
-  while ((filename = OPENSSL_DIR_read(&d, dir))) {
-    char buf[1024];
-    int r;
-
-    if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
-      goto err;
-    }
-
-    r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
-    if (r <= 0 || r >= (int)sizeof(buf) ||
-        !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
-      goto err;
-    }
-  }
-
-  if (errno) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
-    ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
-    goto err;
-  }
-
-  ret = 1;
-
-err:
-  if (d) {
-    OPENSSL_DIR_end(&d);
-  }
-  return ret;
-}
-
 int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
   int reason_code;
   BIO *in;
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 08578a6..d62cdae 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -141,7 +141,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/bytestring.h>
@@ -150,7 +149,6 @@
 #include <openssl/err.h>
 #include <openssl/lhash.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
 
@@ -181,12 +179,21 @@
   return 1;
 }
 
-static uint32_t ssl_session_hash(const SSL_SESSION *a) {
+static uint32_t ssl_session_hash(const SSL_SESSION *sess) {
+  const uint8_t *session_id = sess->session_id;
+
+  uint8_t tmp_storage[sizeof(uint32_t)];
+  if (sess->session_id_length < sizeof(tmp_storage)) {
+    memset(tmp_storage, 0, sizeof(tmp_storage));
+    memcpy(tmp_storage, sess->session_id, sess->session_id_length);
+    session_id = tmp_storage;
+  }
+
   uint32_t hash =
-      ((uint32_t)a->session_id[0]) |
-      ((uint32_t)a->session_id[1] << 8) |
-      ((uint32_t)a->session_id[2] << 16) |
-      ((uint32_t)a->session_id[3] << 24);
+      ((uint32_t)session_id[0]) |
+      ((uint32_t)session_id[1] << 8) |
+      ((uint32_t)session_id[2] << 16) |
+      ((uint32_t)session_id[3] << 24);
 
   return hash;
 }
@@ -221,7 +228,7 @@
     goto err;
   }
 
-  ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+  ret = OPENSSL_malloc(sizeof(SSL_CTX));
   if (ret == NULL) {
     goto err;
   }
@@ -353,7 +360,7 @@
     return NULL;
   }
 
-  SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
+  SSL *ssl = OPENSSL_malloc(sizeof(SSL));
   if (ssl == NULL) {
     goto err;
   }
@@ -417,8 +424,6 @@
   if (!ssl->method->ssl_new(ssl)) {
     goto err;
   }
-  ssl->enc_method = ssl3_get_enc_method(ssl->version);
-  assert(ssl->enc_method != NULL);
 
   ssl->rwstate = SSL_NOTHING;
 
@@ -486,8 +491,6 @@
   ssl_clear_bad_session(ssl);
   SSL_SESSION_free(ssl->session);
 
-  ssl_clear_cipher_ctx(ssl);
-
   ssl_cert_free(ssl->cert);
 
   OPENSSL_free(ssl->tlsext_hostname);
@@ -497,7 +500,6 @@
   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 (ssl->method != NULL) {
@@ -513,8 +515,6 @@
   ssl->shutdown = 0;
   ssl->state = SSL_ST_CONNECT;
   ssl->handshake_func = ssl->method->ssl_connect;
-  /* clear the current cipher */
-  ssl_clear_cipher_ctx(ssl);
 }
 
 void SSL_set_accept_state(SSL *ssl) {
@@ -522,8 +522,6 @@
   ssl->shutdown = 0;
   ssl->state = SSL_ST_ACCEPT;
   ssl->handshake_func = ssl->method->ssl_accept;
-  /* clear the current cipher */
-  ssl_clear_cipher_ctx(ssl);
 }
 
 void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
@@ -550,6 +548,10 @@
 BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
 
 int SSL_do_handshake(SSL *ssl) {
+  ssl->rwstate = SSL_NOTHING;
+  /* Functions which use SSL_get_error must clear the error queue on entry. */
+  ERR_clear_error();
+
   if (ssl->handshake_func == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
     return -1;
@@ -563,91 +565,117 @@
 }
 
 int SSL_connect(SSL *ssl) {
-  if (ssl->handshake_func == 0) {
+  if (ssl->handshake_func == NULL) {
     /* Not properly initialized yet */
     SSL_set_connect_state(ssl);
   }
 
-  if (ssl->handshake_func != ssl->method->ssl_connect) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-    return -1;
-  }
+  assert(ssl->handshake_func == ssl->method->ssl_connect);
 
-  return ssl->handshake_func(ssl);
+  return SSL_do_handshake(ssl);
 }
 
 int SSL_accept(SSL *ssl) {
-  if (ssl->handshake_func == 0) {
+  if (ssl->handshake_func == NULL) {
     /* Not properly initialized yet */
     SSL_set_accept_state(ssl);
   }
 
-  if (ssl->handshake_func != ssl->method->ssl_accept) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+  assert(ssl->handshake_func == ssl->method->ssl_accept);
+
+  return SSL_do_handshake(ssl);
+}
+
+static int ssl_read_impl(SSL *ssl, void *buf, int num, int peek) {
+  ssl->rwstate = SSL_NOTHING;
+  /* Functions which use SSL_get_error must clear the error queue on entry. */
+  ERR_clear_error();
+  ERR_clear_system_error();
+
+  if (ssl->handshake_func == NULL) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
     return -1;
   }
 
-  return ssl->handshake_func(ssl);
+  if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
+    return 0;
+  }
+
+  /* This may require multiple iterations. False Start will cause
+   * |ssl->handshake_func| to signal success one step early, but the handshake
+   * must be completely finished before other modes are accepted. */
+  while (SSL_in_init(ssl)) {
+    int ret = SSL_do_handshake(ssl);
+    if (ret < 0) {
+      return ret;
+    }
+    if (ret == 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+      return -1;
+    }
+  }
+
+  return ssl->method->ssl_read_app_data(ssl, buf, num, peek);
 }
 
 int SSL_read(SSL *ssl, void *buf, int num) {
-  if (ssl->handshake_func == 0) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
-    return -1;
-  }
-
-  if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
-    ssl->rwstate = SSL_NOTHING;
-    return 0;
-  }
-
-  ERR_clear_system_error();
-  return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
+  return ssl_read_impl(ssl, buf, num, 0 /* consume bytes */);
 }
 
 int SSL_peek(SSL *ssl, void *buf, int num) {
-  if (ssl->handshake_func == 0) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
-    return -1;
-  }
-
-  if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
-    return 0;
-  }
-
-  ERR_clear_system_error();
-  return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
+  return ssl_read_impl(ssl, buf, num, 1 /* peek */);
 }
 
 int SSL_write(SSL *ssl, const void *buf, int num) {
-  if (ssl->handshake_func == 0) {
+  ssl->rwstate = SSL_NOTHING;
+  /* Functions which use SSL_get_error must clear the error queue on entry. */
+  ERR_clear_error();
+  ERR_clear_system_error();
+
+  if (ssl->handshake_func == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
     return -1;
   }
 
   if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
-    ssl->rwstate = SSL_NOTHING;
     OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
     return -1;
   }
 
-  ERR_clear_system_error();
+  /* If necessary, complete the handshake implicitly. */
+  if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+    int ret = SSL_do_handshake(ssl);
+    if (ret < 0) {
+      return ret;
+    }
+    if (ret == 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+      return -1;
+    }
+  }
+
   return ssl->method->ssl_write_app_data(ssl, buf, num);
 }
 
 int SSL_shutdown(SSL *ssl) {
+  ssl->rwstate = SSL_NOTHING;
+  /* Functions which use SSL_get_error must clear the error queue on entry. */
+  ERR_clear_error();
+
   /* Note that this function behaves differently from what one might expect.
    * Return values are 0 for no success (yet), 1 for success; but calling it
    * once is usually not enough, even if blocking I/O is used (see
    * ssl3_shutdown). */
 
-  if (ssl->handshake_func == 0) {
+  if (ssl->handshake_func == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
     return -1;
   }
 
+  /* We can't shutdown properly if we are in the middle of a handshake. */
   if (SSL_in_init(ssl)) {
-    return 1;
+    OPENSSL_PUT_ERROR(SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
+    return -1;
   }
 
   /* Do nothing if configured not to send a close_notify. */
@@ -710,8 +738,7 @@
   }
 
   if (ret_code == 0) {
-    if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
-        (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
+    if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) && ssl->s3->clean_shutdown) {
       /* The socket was cleanly shut down with a close_notify. */
       return SSL_ERROR_ZERO_RETURN;
     }
@@ -997,7 +1024,7 @@
 }
 
 int SSL_set_fd(SSL *ssl, int fd) {
-  BIO *bio = BIO_new(BIO_s_fd());
+  BIO *bio = BIO_new(BIO_s_socket());
   if (bio == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
     return 0;
@@ -1009,9 +1036,9 @@
 
 int SSL_set_wfd(SSL *ssl, int fd) {
   if (ssl->rbio == NULL ||
-      BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
+      BIO_method_type(ssl->rbio) != BIO_TYPE_SOCKET ||
       BIO_get_fd(ssl->rbio, NULL) != fd) {
-    BIO *bio = BIO_new(BIO_s_fd());
+    BIO *bio = BIO_new(BIO_s_socket());
     if (bio == NULL) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
       return 0;
@@ -1026,9 +1053,9 @@
 }
 
 int SSL_set_rfd(SSL *ssl, int fd) {
-  if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
+  if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_SOCKET ||
       BIO_get_fd(ssl->wbio, NULL) != fd) {
-    BIO *bio = BIO_new(BIO_s_fd());
+    BIO *bio = BIO_new(BIO_s_socket());
     if (bio == NULL) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
       return 0;
@@ -1187,7 +1214,7 @@
   ssl->max_cert_list = (uint32_t)max_cert_list;
 }
 
-void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
+int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
   if (max_send_fragment < 512) {
     max_send_fragment = 512;
   }
@@ -1195,9 +1222,11 @@
     max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
   }
   ctx->max_send_fragment = (uint16_t)max_send_fragment;
+
+  return 1;
 }
 
-void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
+int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
   if (max_send_fragment < 512) {
     max_send_fragment = 512;
   }
@@ -1205,6 +1234,8 @@
     max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
   }
   ssl->max_send_fragment = (uint16_t)max_send_fragment;
+
+  return 1;
 }
 
 int SSL_set_mtu(SSL *ssl, unsigned mtu) {
@@ -1254,17 +1285,15 @@
     return ssl->cipher_list->ciphers;
   }
 
-  if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
-      ssl->ctx->cipher_list_tls11 != NULL) {
+  if (ssl->version >= TLS1_1_VERSION && ssl->ctx->cipher_list_tls11 != NULL) {
     return ssl->ctx->cipher_list_tls11->ciphers;
   }
 
-  if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
-      ssl->ctx->cipher_list_tls10 != NULL) {
+  if (ssl->version >= TLS1_VERSION && ssl->ctx->cipher_list_tls10 != NULL) {
     return ssl->ctx->cipher_list_tls10->ciphers;
   }
 
-  if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+  if (ssl->ctx->cipher_list != NULL) {
     return ssl->ctx->cipher_list->ciphers;
   }
 
@@ -1282,7 +1311,7 @@
     return ssl->cipher_list_by_id;
   }
 
-  if (ssl->ctx != NULL && ssl->ctx->cipher_list_by_id != NULL) {
+  if (ssl->ctx->cipher_list_by_id != NULL) {
     return ssl->ctx->cipher_list_by_id;
   }
 
@@ -1574,11 +1603,11 @@
 
 void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
                                     unsigned *out_len) {
-  *out_data = ssl->next_proto_negotiated;
+  *out_data = ssl->s3->next_proto_negotiated;
   if (*out_data == NULL) {
     *out_len = 0;
   } else {
-    *out_len = ssl->next_proto_negotiated_len;
+    *out_len = ssl->s3->next_proto_negotiated_len;
   }
 }
 
@@ -1643,18 +1672,6 @@
   }
 }
 
-int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
-                               const char *label, size_t label_len,
-                               const uint8_t *context, size_t context_len,
-                               int use_context) {
-  if (ssl->version < TLS1_VERSION) {
-    return 0;
-  }
-
-  return ssl->enc_method->export_keying_material(
-      ssl, out, out_len, label, label_len, context, context_len, use_context);
-}
-
 void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
                                       int (*cb)(X509_STORE_CTX *store_ctx,
                                                 void *arg),
@@ -1822,13 +1839,6 @@
   return ssl_get_version(session->ssl_version);
 }
 
-void ssl_clear_cipher_ctx(SSL *ssl) {
-  SSL_AEAD_CTX_free(ssl->aead_read_ctx);
-  ssl->aead_read_ctx = NULL;
-  SSL_AEAD_CTX_free(ssl->aead_write_ctx);
-  ssl->aead_write_ctx = NULL;
-}
-
 X509 *SSL_get_certificate(const SSL *ssl) {
   if (ssl->cert != NULL) {
     return ssl->cert->x509;
@@ -1862,16 +1872,18 @@
 }
 
 const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
-  if (ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_write_ctx == NULL) {
     return NULL;
   }
-  return ssl->aead_write_ctx->cipher;
+  return ssl->s3->aead_write_ctx->cipher;
 }
 
 const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
 
 const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; }
 
+int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; }
+
 int ssl_init_wbio_buffer(SSL *ssl, int push) {
   BIO *bbio;
 
@@ -1995,6 +2007,14 @@
 
 void SSL_set_state(SSL *ssl, int state) { }
 
+char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len) {
+  if (len <= 0) {
+    return NULL;
+  }
+  buf[0] = '\0';
+  return buf;
+}
+
 void SSL_set_verify_result(SSL *ssl, long result) {
   ssl->verify_result = result;
 }
@@ -2305,15 +2325,11 @@
       return &SSLv3_enc_data;
 
     case TLS1_VERSION:
-      return &TLSv1_enc_data;
-
-    case DTLS1_VERSION:
     case TLS1_1_VERSION:
-      return &TLSv1_1_enc_data;
-
-    case DTLS1_2_VERSION:
     case TLS1_2_VERSION:
-      return &TLSv1_2_enc_data;
+    case DTLS1_VERSION:
+    case DTLS1_2_VERSION:
+      return &TLSv1_enc_data;
 
     default:
       return NULL;
@@ -2495,7 +2511,7 @@
   }
 }
 
-uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version) {
   if (!SSL_IS_DTLS(ssl)) {
     return wire_version;
   }
@@ -2516,6 +2532,11 @@
   return version;
 }
 
+uint16_t ssl3_protocol_version(const SSL *ssl) {
+  assert(ssl->s3->have_version);
+  return ssl3_version_from_wire(ssl, ssl->version);
+}
+
 int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
 
 int SSL_is_server(SSL *ssl) { return ssl->server; }
@@ -2541,23 +2562,24 @@
 
 int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
                       const RC4_KEY **write_key) {
-  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_read_ctx == NULL || ssl->s3->aead_write_ctx == NULL) {
     return 0;
   }
 
-  return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
-         EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
+  return EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_read_ctx->ctx, read_key) &&
+         EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_write_ctx->ctx, write_key);
 }
 
 int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
                 const uint8_t **out_write_iv, size_t *out_iv_len) {
-  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_read_ctx == NULL || ssl->s3->aead_write_ctx == NULL) {
     return 0;
   }
 
   size_t write_iv_len;
-  if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
-      !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
+  if (!EVP_AEAD_CTX_get_iv(&ssl->s3->aead_read_ctx->ctx, out_read_iv,
+                           out_iv_len) ||
+      !EVP_AEAD_CTX_get_iv(&ssl->s3->aead_write_ctx->ctx, out_write_iv,
                            &write_iv_len) ||
       *out_iv_len != write_iv_len) {
     return 0;
@@ -2566,10 +2588,69 @@
   return 1;
 }
 
+static uint64_t be_to_u64(const uint8_t in[8]) {
+  return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) |
+         (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) |
+         (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) |
+         (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]);
+}
+
+uint64_t SSL_get_read_sequence(const SSL *ssl) {
+  /* TODO(davidben): Internally represent sequence numbers as uint64_t. */
+  if (SSL_IS_DTLS(ssl)) {
+    /* max_seq_num already includes the epoch. */
+    assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48));
+    return ssl->d1->bitmap.max_seq_num;
+  }
+  return be_to_u64(ssl->s3->read_sequence);
+}
+
+uint64_t SSL_get_write_sequence(const SSL *ssl) {
+  uint64_t ret = be_to_u64(ssl->s3->write_sequence);
+  if (SSL_IS_DTLS(ssl)) {
+    assert((ret >> 48) == 0);
+    ret |= ((uint64_t)ssl->d1->w_epoch) << 48;
+  }
+  return ret;
+}
+
 uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
   return ssl->s3->tmp.server_key_exchange_hash;
 }
 
+size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) {
+  if (max_out == 0) {
+    return sizeof(ssl->s3->client_random);
+  }
+  if (max_out > sizeof(ssl->s3->client_random)) {
+    max_out = sizeof(ssl->s3->client_random);
+  }
+  memcpy(out, ssl->s3->client_random, max_out);
+  return max_out;
+}
+
+size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) {
+  if (max_out == 0) {
+    return sizeof(ssl->s3->server_random);
+  }
+  if (max_out > sizeof(ssl->s3->server_random)) {
+    max_out = sizeof(ssl->s3->server_random);
+  }
+  memcpy(out, ssl->s3->server_random, max_out);
+  return max_out;
+}
+
+const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) {
+  if (!SSL_in_init(ssl)) {
+    return NULL;
+  }
+  return ssl->s3->tmp.new_cipher;
+}
+
+void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) {
+  ctx->retain_only_sha256_of_client_certs = !!enabled;
+}
+
 int SSL_clear(SSL *ssl) {
   if (ssl->method == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
@@ -2608,12 +2689,6 @@
   BUF_MEM_free(ssl->init_buf);
   ssl->init_buf = NULL;
 
-  ssl_clear_cipher_ctx(ssl);
-
-  OPENSSL_free(ssl->next_proto_negotiated);
-  ssl->next_proto_negotiated = NULL;
-  ssl->next_proto_negotiated_len = 0;
-
   /* The ssl->d1->mtu is simultaneously configuration (preserved across
    * clear) and connection-specific state (gets reset).
    *
@@ -2627,8 +2702,6 @@
   if (!ssl->method->ssl_new(ssl)) {
     return 0;
   }
-  ssl->enc_method = ssl3_get_enc_method(ssl->version);
-  assert(ssl->enc_method != NULL);
 
   if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
     ssl->d1->mtu = mtu;
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 990979b..c17d2da 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -326,6 +326,11 @@
   ssl->cert->key_method = key_method;
 }
 
+void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
+                                    const SSL_PRIVATE_KEY_METHOD *key_method) {
+  ctx->cert->key_method = key_method;
+}
+
 int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
                                      size_t num_digests) {
   OPENSSL_free(ssl->cert->digest_nids);
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index 3d59bc3..12d065e 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -136,7 +136,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/err.h>
@@ -161,7 +160,7 @@
 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
 
 SSL_SESSION *SSL_SESSION_new(void) {
-  SSL_SESSION *session = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
+  SSL_SESSION *session = OPENSSL_malloc(sizeof(SSL_SESSION));
   if (session == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     return 0;
@@ -232,6 +231,19 @@
   return session->peer;
 }
 
+size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out,
+                                  size_t max_out) {
+  /* TODO(davidben): Fix master_key_length's type and remove these casts. */
+  if (max_out == 0) {
+    return (size_t)session->master_key_length;
+  }
+  if (max_out > (size_t)session->master_key_length) {
+    max_out = (size_t)session->master_key_length;
+  }
+  memcpy(out, session->master_key, max_out);
+  return max_out;
+}
+
 long SSL_SESSION_set_time(SSL_SESSION *session, long time) {
   if (session == NULL) {
     return 0;
@@ -430,7 +442,7 @@
   /* This is used only by servers. */
   assert(ssl->server);
   SSL_SESSION *session = NULL;
-  int send_ticket = 0;
+  int renew_ticket = 0;
 
   /* If tickets are disabled, always behave as if no tickets are present. */
   const uint8_t *ticket = NULL;
@@ -440,24 +452,27 @@
       ssl->version > SSL3_VERSION &&
       SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
                                            &ticket, &ticket_len);
-  if (tickets_supported) {
-    if (!tls_process_ticket(ssl, &session, &send_ticket, ticket, ticket_len,
+  int from_cache = 0;
+  if (tickets_supported && ticket_len > 0) {
+    if (!tls_process_ticket(ssl, &session, &renew_ticket, ticket, ticket_len,
                             ctx->session_id, ctx->session_id_len)) {
       return ssl_session_error;
     }
   } else {
-    /* The client does not support session tickets, so the session ID should be
-     * used instead. */
+    /* The client didn't send a ticket, so the session ID is a real ID. */
     enum ssl_session_result_t lookup_ret = ssl_lookup_session(
         ssl, &session, ctx->session_id, ctx->session_id_len);
     if (lookup_ret != ssl_session_success) {
       return lookup_ret;
     }
+    from_cache = 1;
   }
 
   if (session == NULL ||
       session->sid_ctx_length != ssl->sid_ctx_length ||
       memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
+    /* The client did not offer a suitable ticket or session ID. If supported,
+     * the new session should use a ticket. */
     goto no_session;
   }
 
@@ -471,11 +486,12 @@
      * effectively disable the session cache by accident without anyone
      * noticing). */
     OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
-    goto fatal_error;
+    SSL_SESSION_free(session);
+    return ssl_session_error;
   }
 
   if (session->timeout < (long)(time(NULL) - session->time)) {
-    if (!tickets_supported) {
+    if (from_cache) {
       /* The session was from the cache, so remove it. */
       SSL_CTX_remove_session(ssl->initial_ctx, session);
     }
@@ -483,13 +499,9 @@
   }
 
   *out_session = session;
-  *out_send_ticket = send_ticket;
+  *out_send_ticket = renew_ticket;
   return ssl_session_success;
 
-fatal_error:
-  SSL_SESSION_free(session);
-  return ssl_session_error;
-
 no_session:
   *out_session = NULL;
   *out_send_ticket = tickets_supported;
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 9558f1c..590a2c1 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -18,13 +18,16 @@
 
 #include <algorithm>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <openssl/base64.h>
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
+#include <openssl/pem.h>
 #include <openssl/ssl.h>
+#include <openssl/x509.h>
 
 #include "test/scoped_types.h"
 #include "../crypto/test/test_util.h"
@@ -38,215 +41,178 @@
 struct CipherTest {
   // The rule string to apply.
   const char *rule;
-  // The list of expected ciphers, in order, terminated with -1.
-  const ExpectedCipher *expected;
+  // The list of expected ciphers, in order.
+  std::vector<ExpectedCipher> expected;
 };
 
-// Selecting individual ciphers should work.
-static const char kRule1[] =
-    "ECDHE-ECDSA-CHACHA20-POLY1305:"
-    "ECDHE-RSA-CHACHA20-POLY1305:"
-    "ECDHE-ECDSA-AES128-GCM-SHA256:"
-    "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected1[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// + reorders selected ciphers to the end, keeping their relative
-// order.
-static const char kRule2[] =
-    "ECDHE-ECDSA-CHACHA20-POLY1305:"
-    "ECDHE-RSA-CHACHA20-POLY1305:"
-    "ECDHE-ECDSA-AES128-GCM-SHA256:"
-    "ECDHE-RSA-AES128-GCM-SHA256:"
-    "+aRSA";
-
-static const ExpectedCipher kExpected2[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// ! banishes ciphers from future selections.
-static const char kRule3[] =
-    "!aRSA:"
-    "ECDHE-ECDSA-CHACHA20-POLY1305:"
-    "ECDHE-RSA-CHACHA20-POLY1305:"
-    "ECDHE-ECDSA-AES128-GCM-SHA256:"
-    "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected3[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// Multiple masks can be ANDed in a single rule.
-static const char kRule4[] = "kRSA+AESGCM+AES128";
-
-static const ExpectedCipher kExpected4[] = {
-  { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// - removes selected ciphers, but preserves their order for future
-// selections. Select AES_128_GCM, but order the key exchanges RSA,
-// DHE_RSA, ECDHE_RSA.
-static const char kRule5[] =
-    "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
-    "AESGCM+AES128+aRSA";
-
-static const ExpectedCipher kExpected5[] = {
-  { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// Unknown selectors are no-ops.
-static const char kRule6[] =
-    "ECDHE-ECDSA-CHACHA20-POLY1305:"
-    "ECDHE-RSA-CHACHA20-POLY1305:"
-    "ECDHE-ECDSA-AES128-GCM-SHA256:"
-    "ECDHE-RSA-AES128-GCM-SHA256:"
-    "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
-
-static const ExpectedCipher kExpected6[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// Square brackets specify equi-preference groups.
-static const char kRule7[] =
-    "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
-    "[ECDHE-RSA-CHACHA20-POLY1305]:"
-    "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected7[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 },
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// @STRENGTH performs a stable strength-sort of the selected
-// ciphers and only the selected ciphers.
-static const char kRule8[] =
-    // To simplify things, banish all but {ECDHE_RSA,RSA} x
-    // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
-    "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
-    // Order some ciphers backwards by strength.
-    "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
-    // Select ECDHE ones and sort them by strength. Ties should resolve
-    // based on the order above.
-    "kECDHE:@STRENGTH:-ALL:"
-    // Now bring back everything uses RSA. ECDHE_RSA should be first,
-    // sorted by strength. Then RSA, backwards by strength.
-    "aRSA";
-
-static const ExpectedCipher kExpected8[] = {
-  { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
-  { SSL3_CK_RSA_RC4_128_SHA, 0 },
-  { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
-  { TLS1_CK_RSA_WITH_AES_256_SHA, 0 },
-  { 0, 0 },
-};
-
-// Exact ciphers may not be used in multi-part rules; they are treated
-// as unknown aliases.
-static const char kRule9[] =
-    "ECDHE-ECDSA-AES128-GCM-SHA256:"
-    "ECDHE-RSA-AES128-GCM-SHA256:"
-    "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
-    "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected9[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
-  { 0, 0 },
-};
-
-// SSLv3 matches everything that existed before TLS 1.2.
-static const char kRule10[] = "AES128-SHA:AES128-SHA256:!SSLv3";
-
-static const ExpectedCipher kExpected10[] = {
-  { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 },
-  { 0, 0 },
-};
-
-// TLSv1.2 matches everything added in TLS 1.2.
-static const char kRule11[] = "AES128-SHA:AES128-SHA256:!TLSv1.2";
-
-static const ExpectedCipher kExpected11[] = {
-  { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
-  { 0, 0 },
-};
-
-// The two directives have no intersection.
-static const char kRule12[] = "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3";
-
-static const ExpectedCipher kExpected12[] = {
-  { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
-  { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 },
-  { 0, 0 },
-};
-
-// The shared name of the CHACHA20_POLY1305 variants behaves like a cipher name
-// and not an alias. It may not be used in a multipart rule. (That the shared
-// name works is covered by the standard tests.)
-static const char kRule13[] =
-    "ECDHE-ECDSA-CHACHA20-POLY1305:"
-    "ECDHE-RSA-CHACHA20-POLY1305:"
-    "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
-    "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305";
-
-static const ExpectedCipher kExpected13[] = {
-  { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
-  { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
-  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
-  { 0, 0 },
-};
-
-static CipherTest kCipherTests[] = {
-  { kRule1, kExpected1 },
-  { kRule2, kExpected2 },
-  { kRule3, kExpected3 },
-  { kRule4, kExpected4 },
-  { kRule5, kExpected5 },
-  { kRule6, kExpected6 },
-  { kRule7, kExpected7 },
-  { kRule8, kExpected8 },
-  { kRule9, kExpected9 },
-  { kRule10, kExpected10 },
-  { kRule11, kExpected11 },
-  { kRule12, kExpected12 },
-  { kRule13, kExpected13 },
-  { NULL, NULL },
+static const CipherTest kCipherTests[] = {
+    // Selecting individual ciphers should work.
+    {
+        "ECDHE-ECDSA-CHACHA20-POLY1305:"
+        "ECDHE-RSA-CHACHA20-POLY1305:"
+        "ECDHE-ECDSA-AES128-GCM-SHA256:"
+        "ECDHE-RSA-AES128-GCM-SHA256",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // + reorders selected ciphers to the end, keeping their relative order.
+    {
+        "ECDHE-ECDSA-CHACHA20-POLY1305:"
+        "ECDHE-RSA-CHACHA20-POLY1305:"
+        "ECDHE-ECDSA-AES128-GCM-SHA256:"
+        "ECDHE-RSA-AES128-GCM-SHA256:"
+        "+aRSA",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // ! banishes ciphers from future selections.
+    {
+        "!aRSA:"
+        "ECDHE-ECDSA-CHACHA20-POLY1305:"
+        "ECDHE-RSA-CHACHA20-POLY1305:"
+        "ECDHE-ECDSA-AES128-GCM-SHA256:"
+        "ECDHE-RSA-AES128-GCM-SHA256",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // Multiple masks can be ANDed in a single rule.
+    {
+        "kRSA+AESGCM+AES128",
+        {
+            {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // - removes selected ciphers, but preserves their order for future
+    // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
+    // ECDHE_RSA.
+    {
+        "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
+        "AESGCM+AES128+aRSA",
+        {
+            {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // Unknown selectors are no-ops.
+    {
+        "ECDHE-ECDSA-CHACHA20-POLY1305:"
+        "ECDHE-RSA-CHACHA20-POLY1305:"
+        "ECDHE-ECDSA-AES128-GCM-SHA256:"
+        "ECDHE-RSA-AES128-GCM-SHA256:"
+        "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // Square brackets specify equi-preference groups.
+    {
+        "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
+        "[ECDHE-RSA-CHACHA20-POLY1305]:"
+        "ECDHE-RSA-AES128-GCM-SHA256",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // @STRENGTH performs a stable strength-sort of the selected ciphers and
+    // only the selected ciphers.
+    {
+        // To simplify things, banish all but {ECDHE_RSA,RSA} x
+        // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
+        "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
+        // Order some ciphers backwards by strength.
+        "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
+        // Select ECDHE ones and sort them by strength. Ties should resolve
+        // based on the order above.
+        "kECDHE:@STRENGTH:-ALL:"
+        // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
+        // by strength. Then RSA, backwards by strength.
+        "aRSA",
+        {
+            {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
+            {SSL3_CK_RSA_RC4_128_SHA, 0},
+            {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+            {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
+        },
+    },
+    // Exact ciphers may not be used in multi-part rules; they are treated
+    // as unknown aliases.
+    {
+        "ECDHE-ECDSA-AES128-GCM-SHA256:"
+        "ECDHE-RSA-AES128-GCM-SHA256:"
+        "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
+        "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+        },
+    },
+    // SSLv3 matches everything that existed before TLS 1.2.
+    {
+        "AES128-SHA:AES128-SHA256:!SSLv3",
+        {
+            {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
+        },
+    },
+    // TLSv1.2 matches everything added in TLS 1.2.
+    {
+        "AES128-SHA:AES128-SHA256:!TLSv1.2",
+        {
+            {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+        },
+    },
+    // The two directives have no intersection.
+    {
+        "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
+        {
+            {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+            {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
+        },
+    },
+    // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
+    // name and not an alias. It may not be used in a multipart rule. (That the
+    // shared name works is covered by the standard tests.)
+    {
+        "ECDHE-ECDSA-CHACHA20-POLY1305:"
+        "ECDHE-RSA-CHACHA20-POLY1305:"
+        "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
+        "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
+        {
+            {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+            {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+            {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+        },
+    },
 };
 
 static const char *kBadRules[] = {
@@ -270,7 +236,6 @@
   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
-  NULL,
 };
 
 static const char *kMustNotIncludeNull[] = {
@@ -287,7 +252,6 @@
   "SSLv3",
   "TLSv1",
   "TLSv1.2",
-  NULL
 };
 
 static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
@@ -310,36 +274,35 @@
   }
 }
 
-static bool TestCipherRule(CipherTest *t) {
+static bool TestCipherRule(const CipherTest &t) {
   ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
 
-  if (!SSL_CTX_set_cipher_list(ctx.get(), t->rule)) {
-    fprintf(stderr, "Error testing cipher rule '%s'\n", t->rule);
+  if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
+    fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
     return false;
   }
 
   // Compare the two lists.
-  size_t i;
-  for (i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
+  if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
+    fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
+    PrintCipherPreferenceList(ctx->cipher_list);
+    return false;
+  }
+
+  for (size_t i = 0; i < t.expected.size(); i++) {
     const SSL_CIPHER *cipher =
         sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
-    if (t->expected[i].id != SSL_CIPHER_get_id(cipher) ||
-        t->expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
-      fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
+    if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
+        t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
+      fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
       PrintCipherPreferenceList(ctx->cipher_list);
       return false;
     }
   }
 
-  if (t->expected[i].id != 0) {
-    fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
-    PrintCipherPreferenceList(ctx->cipher_list);
-    return false;
-  }
-
   return true;
 }
 
@@ -362,26 +325,26 @@
 }
 
 static bool TestCipherRules() {
-  for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
-    if (!TestCipherRule(&kCipherTests[i])) {
+  for (const CipherTest &test : kCipherTests) {
+    if (!TestCipherRule(test)) {
       return false;
     }
   }
 
-  for (size_t i = 0; kBadRules[i] != NULL; i++) {
+  for (const char *rule : kBadRules) {
     ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
     if (!ctx) {
       return false;
     }
-    if (SSL_CTX_set_cipher_list(ctx.get(), kBadRules[i])) {
-      fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", kBadRules[i]);
+    if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
+      fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
       return false;
     }
     ERR_clear_error();
   }
 
-  for (size_t i = 0; kMustNotIncludeNull[i] != NULL; i++) {
-    if (!TestRuleDoesNotIncludeNull(kMustNotIncludeNull[i])) {
+  for (const char *rule : kMustNotIncludeNull) {
+    if (!TestRuleDoesNotIncludeNull(rule)) {
       return false;
     }
   }
@@ -932,23 +895,6 @@
   return ret;
 }
 
-// TODO(davidben): Switch this to a |std::vector<ScopedSSL_SESSION>| once we can
-// rely on a move-aware |std::vector|.
-class ScopedSessionVector {
- public:
-  explicit ScopedSessionVector(std::vector<SSL_SESSION*> *sessions)
-      : sessions_(sessions) {}
-
-  ~ScopedSessionVector() {
-    for (SSL_SESSION *session : *sessions_) {
-      SSL_SESSION_free(session);
-    }
-  }
-
- private:
-  std::vector<SSL_SESSION*> *const sessions_;
-};
-
 // Test that the internal session cache behaves as expected.
 static bool TestInternalSessionCache() {
   ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
@@ -957,38 +903,38 @@
   }
 
   // Prepare 10 test sessions.
-  std::vector<SSL_SESSION*> sessions;
-  ScopedSessionVector cleanup(&sessions);
+  std::vector<ScopedSSL_SESSION> sessions;
   for (int i = 0; i < 10; i++) {
     ScopedSSL_SESSION session = CreateTestSession(i);
     if (!session) {
       return false;
     }
-    sessions.push_back(session.release());
+    sessions.push_back(std::move(session));
   }
 
   SSL_CTX_sess_set_cache_size(ctx.get(), 5);
 
   // Insert all the test sessions.
-  for (SSL_SESSION *session : sessions) {
-    if (!SSL_CTX_add_session(ctx.get(), session)) {
+  for (const auto &session : sessions) {
+    if (!SSL_CTX_add_session(ctx.get(), session.get())) {
       return false;
     }
   }
 
   // Only the last five should be in the list.
-  std::vector<SSL_SESSION*> expected;
-  expected.push_back(sessions[9]);
-  expected.push_back(sessions[8]);
-  expected.push_back(sessions[7]);
-  expected.push_back(sessions[6]);
-  expected.push_back(sessions[5]);
+  std::vector<SSL_SESSION*> expected = {
+      sessions[9].get(),
+      sessions[8].get(),
+      sessions[7].get(),
+      sessions[6].get(),
+      sessions[5].get(),
+  };
   if (!ExpectCache(ctx.get(), expected)) {
     return false;
   }
 
   // Inserting an element already in the cache should fail.
-  if (SSL_CTX_add_session(ctx.get(), sessions[7]) ||
+  if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
       !ExpectCache(ctx.get(), expected)) {
     return false;
   }
@@ -999,32 +945,34 @@
   if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
     return false;
   }
-  expected.clear();
-  expected.push_back(collision.get());
-  expected.push_back(sessions[9]);
-  expected.push_back(sessions[8]);
-  expected.push_back(sessions[6]);
-  expected.push_back(sessions[5]);
+  expected = {
+      collision.get(),
+      sessions[9].get(),
+      sessions[8].get(),
+      sessions[6].get(),
+      sessions[5].get(),
+  };
   if (!ExpectCache(ctx.get(), expected)) {
     return false;
   }
 
   // Removing sessions behaves correctly.
-  if (!SSL_CTX_remove_session(ctx.get(), sessions[6])) {
+  if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
     return false;
   }
-  expected.clear();
-  expected.push_back(collision.get());
-  expected.push_back(sessions[9]);
-  expected.push_back(sessions[8]);
-  expected.push_back(sessions[5]);
+  expected = {
+      collision.get(),
+      sessions[9].get(),
+      sessions[8].get(),
+      sessions[5].get(),
+  };
   if (!ExpectCache(ctx.get(), expected)) {
     return false;
   }
 
   // Removing sessions requires an exact match.
-  if (SSL_CTX_remove_session(ctx.get(), sessions[0]) ||
-      SSL_CTX_remove_session(ctx.get(), sessions[7]) ||
+  if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
+      SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
       !ExpectCache(ctx.get(), expected)) {
     return false;
   }
@@ -1032,6 +980,157 @@
   return true;
 }
 
+static uint16_t EpochFromSequence(uint64_t seq) {
+  return static_cast<uint16_t>(seq >> 48);
+}
+
+static ScopedX509 GetTestCertificate() {
+  static const char kCertPEM[] =
+      "-----BEGIN CERTIFICATE-----\n"
+      "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
+      "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
+      "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
+      "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
+      "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
+      "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
+      "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
+      "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
+      "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
+      "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
+      "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
+      "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
+      "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
+      "-----END CERTIFICATE-----\n";
+  ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+  return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static ScopedEVP_PKEY GetTestKey() {
+  static const char kKeyPEM[] =
+      "-----BEGIN RSA PRIVATE KEY-----\n"
+      "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
+      "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
+      "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
+      "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
+      "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
+      "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
+      "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
+      "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
+      "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
+      "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
+      "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
+      "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
+      "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
+      "-----END RSA PRIVATE KEY-----\n";
+  ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+  return ScopedEVP_PKEY(
+      PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static bool TestSequenceNumber(bool dtls) {
+  ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+  ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+  if (!client_ctx || !server_ctx) {
+    return false;
+  }
+
+  ScopedX509 cert = GetTestCertificate();
+  ScopedEVP_PKEY key = GetTestKey();
+  if (!cert || !key ||
+      !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+      !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+    return false;
+  }
+
+  // Create a client and server connected to each other.
+  ScopedSSL client(SSL_new(client_ctx.get())), server(SSL_new(server_ctx.get()));
+  if (!client || !server) {
+    return false;
+  }
+  SSL_set_connect_state(client.get());
+  SSL_set_accept_state(server.get());
+
+  BIO *bio1, *bio2;
+  if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
+    return false;
+  }
+  // SSL_set_bio takes ownership.
+  SSL_set_bio(client.get(), bio1, bio1);
+  SSL_set_bio(server.get(), bio2, bio2);
+
+  // Drive both their handshakes to completion.
+  for (;;) {
+    int client_ret = SSL_do_handshake(client.get());
+    int client_err = SSL_get_error(client.get(), client_ret);
+    if (client_err != SSL_ERROR_NONE &&
+        client_err != SSL_ERROR_WANT_READ &&
+        client_err != SSL_ERROR_WANT_WRITE) {
+      fprintf(stderr, "Client error: %d\n", client_err);
+      return false;
+    }
+
+    int server_ret = SSL_do_handshake(server.get());
+    int server_err = SSL_get_error(server.get(), server_ret);
+    if (server_err != SSL_ERROR_NONE &&
+        server_err != SSL_ERROR_WANT_READ &&
+        server_err != SSL_ERROR_WANT_WRITE) {
+      fprintf(stderr, "Server error: %d\n", server_err);
+      return false;
+    }
+
+    if (client_ret == 1 && server_ret == 1) {
+      break;
+    }
+  }
+
+  uint64_t client_read_seq = SSL_get_read_sequence(client.get());
+  uint64_t client_write_seq = SSL_get_write_sequence(client.get());
+  uint64_t server_read_seq = SSL_get_read_sequence(server.get());
+  uint64_t server_write_seq = SSL_get_write_sequence(server.get());
+
+  if (dtls) {
+    // Both client and server must be at epoch 1.
+    if (EpochFromSequence(client_read_seq) != 1 ||
+        EpochFromSequence(client_write_seq) != 1 ||
+        EpochFromSequence(server_read_seq) != 1 ||
+        EpochFromSequence(server_write_seq) != 1) {
+      fprintf(stderr, "Bad epochs.\n");
+      return false;
+    }
+
+    // The next record to be written should exceed the largest received.
+    if (client_write_seq <= server_read_seq ||
+        server_write_seq <= client_read_seq) {
+      fprintf(stderr, "Inconsistent sequence numbers.\n");
+      return false;
+    }
+  } else {
+    // The next record to be written should equal the next to be received.
+    if (client_write_seq != server_read_seq ||
+        server_write_seq != client_write_seq) {
+      fprintf(stderr, "Inconsistent sequence numbers.\n");
+      return false;
+    }
+  }
+
+  // Send a record from client to server.
+  uint8_t byte = 0;
+  if (SSL_write(client.get(), &byte, 1) != 1 ||
+      SSL_read(server.get(), &byte, 1) != 1) {
+    fprintf(stderr, "Could not send byte.\n");
+    return false;
+  }
+
+  // The client write and server read sequence numbers should have incremented.
+  if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
+      server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
+    fprintf(stderr, "Sequence numbers did not increment.\n");\
+    return false;
+  }
+
+  return true;
+}
+
 int main() {
   CRYPTO_library_init();
 
@@ -1053,7 +1152,9 @@
       !TestCipherGetRFCName() ||
       !TestPaddingExtension() ||
       !TestClientCAList() ||
-      !TestInternalSessionCache()) {
+      !TestInternalSessionCache() ||
+      !TestSequenceNumber(false /* TLS */) ||
+      !TestSequenceNumber(true /* DTLS */)) {
     ERR_print_errors_fp(stderr);
     return 1;
   }
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 0f1d683..b599207 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -136,7 +136,6 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
-#include <stdio.h>
 #include <string.h>
 
 #include <openssl/err.h>
@@ -144,7 +143,7 @@
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 
 #include "internal.h"
@@ -224,11 +223,10 @@
   return ret;
 }
 
-int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
-             size_t secret_len, const char *label, size_t label_len,
-             const uint8_t *seed1, size_t seed1_len,
-             const uint8_t *seed2, size_t seed2_len) {
-
+static int tls1_prf(const SSL *ssl, uint8_t *out, size_t out_len,
+                    const uint8_t *secret, size_t secret_len, const char *label,
+                    size_t label_len, const uint8_t *seed1, size_t seed1_len,
+                    const uint8_t *seed2, size_t seed2_len) {
   if (out_len == 0) {
     return 1;
   }
@@ -260,15 +258,12 @@
   return 1;
 }
 
-static int tls1_generate_key_block(SSL *ssl, uint8_t *out, size_t out_len) {
-  return ssl->enc_method->prf(
-      ssl, out, out_len, ssl->session->master_key,
-      ssl->session->master_key_length, TLS_MD_KEY_EXPANSION_CONST,
-      TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE,
-      ssl->s3->client_random, SSL3_RANDOM_SIZE);
-}
-
 int tls1_change_cipher_state(SSL *ssl, int which) {
+  /* Ensure the key block is set up. */
+  if (!tls1_setup_key_block(ssl)) {
+    return 0;
+  }
+
   /* 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. */
   const char is_read = (which & SSL3_CC_READ) != 0;
@@ -277,63 +272,28 @@
    * or a server reading a client's ChangeCipherSpec. */
   const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
                                which == SSL3_CHANGE_CIPHER_SERVER_READ;
-  const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
-  const uint8_t *client_write_key, *server_write_key, *key;
-  const uint8_t *client_write_iv, *server_write_iv, *iv;
-  const EVP_AEAD *aead = ssl->s3->tmp.new_aead;
-  size_t key_len, iv_len, mac_secret_len;
-  const uint8_t *key_data;
 
-  /* Reset sequence number to zero. */
-  if (is_read) {
-    if (SSL_IS_DTLS(ssl)) {
-      ssl->d1->r_epoch++;
-      memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap));
-    }
-    memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
-  } else {
-    if (SSL_IS_DTLS(ssl)) {
-      ssl->d1->w_epoch++;
-      memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence,
-             sizeof(ssl->s3->write_sequence));
-    }
-    memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
-  }
+  size_t mac_secret_len = ssl->s3->tmp.new_mac_secret_len;
+  size_t key_len = ssl->s3->tmp.new_key_len;
+  size_t iv_len = ssl->s3->tmp.new_fixed_iv_len;
+  assert((mac_secret_len + key_len + iv_len) * 2 ==
+         ssl->s3->tmp.key_block_length);
 
-  mac_secret_len = ssl->s3->tmp.new_mac_secret_len;
-  iv_len = ssl->s3->tmp.new_fixed_iv_len;
-
-  if (aead == NULL) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-
-  key_len = EVP_AEAD_key_length(aead);
-  if (mac_secret_len > 0) {
-    /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher
-     * suites) the key length reported by |EVP_AEAD_key_length| will
-     * include the MAC and IV key bytes. */
-    if (key_len < mac_secret_len + iv_len) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-    key_len -= mac_secret_len + iv_len;
-  }
-
-  key_data = ssl->s3->tmp.key_block;
-  client_write_mac_secret = key_data;
+  const uint8_t *key_data = ssl->s3->tmp.key_block;
+  const uint8_t *client_write_mac_secret = key_data;
   key_data += mac_secret_len;
-  server_write_mac_secret = key_data;
+  const uint8_t *server_write_mac_secret = key_data;
   key_data += mac_secret_len;
-  client_write_key = key_data;
+  const uint8_t *client_write_key = key_data;
   key_data += key_len;
-  server_write_key = key_data;
+  const uint8_t *server_write_key = key_data;
   key_data += key_len;
-  client_write_iv = key_data;
+  const uint8_t *client_write_iv = key_data;
   key_data += iv_len;
-  server_write_iv = key_data;
+  const uint8_t *server_write_iv = key_data;
   key_data += iv_len;
 
+  const uint8_t *mac_secret, *key, *iv;
   if (use_client_keys) {
     mac_secret = client_write_mac_secret;
     key = client_write_key;
@@ -344,50 +304,51 @@
     iv = server_write_iv;
   }
 
-  if (key_data - ssl->s3->tmp.key_block != ssl->s3->tmp.key_block_length) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+  SSL_AEAD_CTX *aead_ctx =
+      SSL_AEAD_CTX_new(is_read ? evp_aead_open : evp_aead_seal,
+                       ssl3_protocol_version(ssl), ssl->s3->tmp.new_cipher, key,
+                       key_len, mac_secret, mac_secret_len, iv, iv_len);
+  if (aead_ctx == NULL) {
     return 0;
   }
 
   if (is_read) {
-    SSL_AEAD_CTX_free(ssl->aead_read_ctx);
-    ssl->aead_read_ctx = SSL_AEAD_CTX_new(
-        evp_aead_open, ssl3_version_from_wire(ssl, ssl->version),
-        ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
-        iv_len);
-    return ssl->aead_read_ctx != NULL;
+    ssl_set_read_state(ssl, aead_ctx);
+  } else {
+    ssl_set_write_state(ssl, aead_ctx);
   }
+  return 1;
+}
 
-  SSL_AEAD_CTX_free(ssl->aead_write_ctx);
-  ssl->aead_write_ctx = SSL_AEAD_CTX_new(
-      evp_aead_seal, ssl3_version_from_wire(ssl, ssl->version),
-      ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
-      iv_len);
-  return ssl->aead_write_ctx != NULL;
+size_t SSL_get_key_block_len(const SSL *ssl) {
+  return 2 * ((size_t)ssl->s3->tmp.new_mac_secret_len +
+              (size_t)ssl->s3->tmp.new_key_len +
+              (size_t)ssl->s3->tmp.new_fixed_iv_len);
+}
+
+int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {
+  return ssl->s3->enc_method->prf(
+      ssl, out, out_len, ssl->session->master_key,
+      ssl->session->master_key_length, TLS_MD_KEY_EXPANSION_CONST,
+      TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE,
+      ssl->s3->client_random, SSL3_RANDOM_SIZE);
 }
 
 int tls1_setup_key_block(SSL *ssl) {
-  uint8_t *p;
-  const EVP_AEAD *aead = NULL;
-  int ret = 0;
-  size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len;
-  size_t key_block_len;
-
   if (ssl->s3->tmp.key_block_length != 0) {
     return 1;
   }
 
-  if (ssl->session->cipher == NULL) {
-    goto cipher_unavailable_err;
-  }
-
-  if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
+  const EVP_AEAD *aead = NULL;
+  size_t mac_secret_len, fixed_iv_len;
+  if (ssl->session->cipher == NULL ||
+      !ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
                                ssl->session->cipher,
-                               ssl3_version_from_wire(ssl, ssl->version))) {
-    goto cipher_unavailable_err;
+                               ssl3_protocol_version(ssl))) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+    return 0;
   }
-  key_len = EVP_AEAD_key_length(aead);
-  variable_iv_len = EVP_AEAD_nonce_length(aead);
+  size_t key_len = EVP_AEAD_key_length(aead);
   if (mac_secret_len > 0) {
     /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the
      * key length reported by |EVP_AEAD_key_length| will include the MAC key
@@ -397,53 +358,38 @@
       return 0;
     }
     key_len -= mac_secret_len + fixed_iv_len;
-  } else {
-    /* The nonce is split into a fixed portion and a variable portion. */
-    if (variable_iv_len < fixed_iv_len) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-    variable_iv_len -= fixed_iv_len;
   }
 
   assert(mac_secret_len < 256);
+  assert(key_len < 256);
   assert(fixed_iv_len < 256);
-  assert(variable_iv_len < 256);
 
-  ssl->s3->tmp.new_aead = aead;
   ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
+  ssl->s3->tmp.new_key_len = (uint8_t)key_len;
   ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
-  ssl->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
 
-  key_block_len = key_len + mac_secret_len + fixed_iv_len;
-  key_block_len *= 2;
+  size_t key_block_len = SSL_get_key_block_len(ssl);
 
   ssl3_cleanup_key_block(ssl);
 
-  p = (uint8_t *)OPENSSL_malloc(key_block_len);
-  if (p == NULL) {
+  uint8_t *keyblock = OPENSSL_malloc(key_block_len);
+  if (keyblock == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-    goto err;
+    return 0;
   }
 
-  ssl->s3->tmp.key_block_length = key_block_len;
-  ssl->s3->tmp.key_block = p;
-
-  if (!tls1_generate_key_block(ssl, p, key_block_len)) {
-    goto err;
+  if (!SSL_generate_key_block(ssl, keyblock, key_block_len)) {
+    OPENSSL_free(keyblock);
+    return 0;
   }
 
-  ret = 1;
-
-err:
-  return ret;
-
-cipher_unavailable_err:
-  OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
-  return 0;
+  assert(key_block_len < 256);
+  ssl->s3->tmp.key_block_length = (uint8_t)key_block_len;
+  ssl->s3->tmp.key_block = keyblock;
+  return 1;
 }
 
-int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *out) {
+static int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *out) {
   const EVP_MD_CTX *ctx_template;
   if (md_nid == NID_md5) {
     ctx_template = &ssl->s3->handshake_md5;
@@ -512,57 +458,58 @@
   return (int)(md5_len + len);
 }
 
-int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *out) {
-  uint8_t buf[2 * EVP_MAX_MD_SIZE];
-  int err = 0;
-  int digests_len;
-
+static int tls1_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
   /* At this point, the handshake should have released the handshake buffer on
    * its own. */
   assert(ssl->s3->handshake_buffer == NULL);
 
-  digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
+  const char *label = TLS_MD_CLIENT_FINISH_CONST;
+  size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
+  if (from_server) {
+    label = TLS_MD_SERVER_FINISH_CONST;
+    label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
+  }
+
+  uint8_t buf[EVP_MAX_MD_SIZE];
+  int digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
   if (digests_len < 0) {
-    err = 1;
-    digests_len = 0;
-  }
-
-  if (!ssl->enc_method->prf(ssl, out, 12, ssl->session->master_key,
-                            ssl->session->master_key_length, str, slen, buf,
-                            digests_len, NULL, 0)) {
-    err = 1;
-  }
-
-  if (err) {
     return 0;
-  } else {
-    return 12;
   }
+
+  static const size_t kFinishedLen = 12;
+  if (!ssl->s3->enc_method->prf(ssl, out, kFinishedLen,
+                                ssl->session->master_key,
+                                ssl->session->master_key_length, label,
+                                label_len, buf, digests_len, NULL, 0)) {
+    return 0;
+  }
+
+  return (int)kFinishedLen;
 }
 
 int tls1_generate_master_secret(SSL *ssl, uint8_t *out,
                                 const uint8_t *premaster,
                                 size_t premaster_len) {
   if (ssl->s3->tmp.extended_master_secret) {
-    uint8_t digests[2 * EVP_MAX_MD_SIZE];
+    uint8_t digests[EVP_MAX_MD_SIZE];
     int digests_len = tls1_handshake_digest(ssl, digests, sizeof(digests));
     if (digests_len == -1) {
       return 0;
     }
 
-    if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
-                              premaster_len,
-                              TLS_MD_EXTENDED_MASTER_SECRET_CONST,
-                              TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
-                              digests_len, NULL, 0)) {
+    if (!ssl->s3->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
+                                  premaster_len,
+                                  TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+                                  TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
+                                  digests, digests_len, NULL, 0)) {
       return 0;
     }
   } else {
-    if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
-                              premaster_len, TLS_MD_MASTER_SECRET_CONST,
-                              TLS_MD_MASTER_SECRET_CONST_SIZE,
-                              ssl->s3->client_random, SSL3_RANDOM_SIZE,
-                              ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
+    if (!ssl->s3->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
+                                  premaster_len, TLS_MD_MASTER_SECRET_CONST,
+                                  TLS_MD_MASTER_SECRET_CONST_SIZE,
+                                  ssl->s3->client_random, SSL3_RANDOM_SIZE,
+                                  ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
       return 0;
     }
   }
@@ -570,12 +517,11 @@
   return SSL3_MASTER_SECRET_SIZE;
 }
 
-int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
-                                const char *label, size_t label_len,
-                                const uint8_t *context, size_t context_len,
-                                int use_context) {
+int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
+                               const char *label, size_t label_len,
+                               const uint8_t *context, size_t context_len,
+                               int use_context) {
   if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
 
@@ -601,108 +547,16 @@
     memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len);
   }
 
-  int ret = ssl->enc_method->prf(ssl, out, out_len, ssl->session->master_key,
-                                 ssl->session->master_key_length, label,
-                                 label_len, seed, seed_len, NULL, 0);
+  int ret =
+      ssl->s3->enc_method->prf(ssl, out, out_len, ssl->session->master_key,
+                               ssl->session->master_key_length, label,
+                               label_len, seed, seed_len, NULL, 0);
   OPENSSL_free(seed);
   return ret;
 }
 
-int tls1_alert_code(int code) {
-  switch (code) {
-    case SSL_AD_CLOSE_NOTIFY:
-      return SSL3_AD_CLOSE_NOTIFY;
-
-    case SSL_AD_UNEXPECTED_MESSAGE:
-      return SSL3_AD_UNEXPECTED_MESSAGE;
-
-    case SSL_AD_BAD_RECORD_MAC:
-      return SSL3_AD_BAD_RECORD_MAC;
-
-    case SSL_AD_DECRYPTION_FAILED:
-      return TLS1_AD_DECRYPTION_FAILED;
-
-    case SSL_AD_RECORD_OVERFLOW:
-      return TLS1_AD_RECORD_OVERFLOW;
-
-    case SSL_AD_DECOMPRESSION_FAILURE:
-      return SSL3_AD_DECOMPRESSION_FAILURE;
-
-    case SSL_AD_HANDSHAKE_FAILURE:
-      return SSL3_AD_HANDSHAKE_FAILURE;
-
-    case SSL_AD_NO_CERTIFICATE:
-      return -1;
-
-    case SSL_AD_BAD_CERTIFICATE:
-      return SSL3_AD_BAD_CERTIFICATE;
-
-    case SSL_AD_UNSUPPORTED_CERTIFICATE:
-      return SSL3_AD_UNSUPPORTED_CERTIFICATE;
-
-    case SSL_AD_CERTIFICATE_REVOKED:
-      return SSL3_AD_CERTIFICATE_REVOKED;
-
-    case SSL_AD_CERTIFICATE_EXPIRED:
-      return SSL3_AD_CERTIFICATE_EXPIRED;
-
-    case SSL_AD_CERTIFICATE_UNKNOWN:
-      return SSL3_AD_CERTIFICATE_UNKNOWN;
-
-    case SSL_AD_ILLEGAL_PARAMETER:
-      return SSL3_AD_ILLEGAL_PARAMETER;
-
-    case SSL_AD_UNKNOWN_CA:
-      return TLS1_AD_UNKNOWN_CA;
-
-    case SSL_AD_ACCESS_DENIED:
-      return TLS1_AD_ACCESS_DENIED;
-
-    case SSL_AD_DECODE_ERROR:
-      return TLS1_AD_DECODE_ERROR;
-
-    case SSL_AD_DECRYPT_ERROR:
-      return TLS1_AD_DECRYPT_ERROR;
-    case SSL_AD_EXPORT_RESTRICTION:
-      return TLS1_AD_EXPORT_RESTRICTION;
-
-    case SSL_AD_PROTOCOL_VERSION:
-      return TLS1_AD_PROTOCOL_VERSION;
-
-    case SSL_AD_INSUFFICIENT_SECURITY:
-      return TLS1_AD_INSUFFICIENT_SECURITY;
-
-    case SSL_AD_INTERNAL_ERROR:
-      return TLS1_AD_INTERNAL_ERROR;
-
-    case SSL_AD_USER_CANCELLED:
-      return TLS1_AD_USER_CANCELLED;
-
-    case SSL_AD_NO_RENEGOTIATION:
-      return TLS1_AD_NO_RENEGOTIATION;
-
-    case SSL_AD_UNSUPPORTED_EXTENSION:
-      return TLS1_AD_UNSUPPORTED_EXTENSION;
-
-    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
-      return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
-
-    case SSL_AD_UNRECOGNIZED_NAME:
-      return TLS1_AD_UNRECOGNIZED_NAME;
-
-    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
-      return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
-
-    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
-      return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
-
-    case SSL_AD_UNKNOWN_PSK_IDENTITY:
-      return TLS1_AD_UNKNOWN_PSK_IDENTITY;
-
-    case SSL_AD_INAPPROPRIATE_FALLBACK:
-      return SSL3_AD_INAPPROPRIATE_FALLBACK;
-
-    default:
-      return -1;
-  }
-}
+const SSL3_ENC_METHOD TLSv1_enc_data = {
+    tls1_prf,
+    tls1_final_finish_mac,
+    tls1_cert_verify_mac,
+};
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 5aea08b..eac9579 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -110,7 +110,6 @@
 
 #include <assert.h>
 #include <limits.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -120,7 +119,7 @@
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/type_check.h>
 
@@ -130,48 +129,6 @@
 static int ssl_check_clienthello_tlsext(SSL *ssl);
 static int ssl_check_serverhello_tlsext(SSL *ssl);
 
-const SSL3_ENC_METHOD TLSv1_enc_data = {
-    tls1_prf,
-    tls1_setup_key_block,
-    tls1_generate_master_secret,
-    tls1_change_cipher_state,
-    tls1_final_finish_mac,
-    tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
-    tls1_alert_code,
-    tls1_export_keying_material,
-    0,
-};
-
-const SSL3_ENC_METHOD TLSv1_1_enc_data = {
-    tls1_prf,
-    tls1_setup_key_block,
-    tls1_generate_master_secret,
-    tls1_change_cipher_state,
-    tls1_final_finish_mac,
-    tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
-    tls1_alert_code,
-    tls1_export_keying_material,
-    SSL_ENC_FLAG_EXPLICIT_IV,
-};
-
-const SSL3_ENC_METHOD TLSv1_2_enc_data = {
-    tls1_prf,
-    tls1_setup_key_block,
-    tls1_generate_master_secret,
-    tls1_change_cipher_state,
-    tls1_final_finish_mac,
-    tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
-    tls1_alert_code,
-    tls1_export_keying_material,
-    SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF,
-};
-
 static int compare_uint16_t(const void *p1, const void *p2) {
   uint16_t u1 = *((const uint16_t *)p1);
   uint16_t u2 = *((const uint16_t *)p2);
@@ -211,8 +168,7 @@
     return 1;
   }
 
-  extension_types =
-      (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
+  extension_types = OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
   if (extension_types == NULL) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     goto done;
@@ -336,6 +292,7 @@
 }
 
 static const uint16_t eccurves_default[] = {
+    SSL_CURVE_X25519,
     SSL_CURVE_SECP256R1,
     SSL_CURVE_SECP384R1,
 #if defined(BORINGSSL_ANDROID_SYSTEM)
@@ -418,7 +375,7 @@
   uint16_t *curve_ids;
   size_t i;
 
-  curve_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t));
+  curve_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
   if (curve_ids == NULL) {
     return 0;
   }
@@ -551,7 +508,6 @@
     tlsext_sigalg(TLSEXT_hash_sha512)
     tlsext_sigalg(TLSEXT_hash_sha384)
     tlsext_sigalg(TLSEXT_hash_sha256)
-    tlsext_sigalg(TLSEXT_hash_sha224)
     tlsext_sigalg(TLSEXT_hash_sha1)
 };
 
@@ -731,82 +687,44 @@
     return 1;
   }
 
-  /* The servername extension is treated as follows:
-   *
-   * - Only the hostname type is supported with a maximum length of 255.
-   * - The servername is rejected if too long or if it contains zeros, in
-   *   which case an fatal alert is generated.
-   * - The servername field is maintained together with the session cache.
-   * - When a session is resumed, the servername callback is invoked in order
-   *   to allow the application to position itself to the right context.
-   * - The servername is acknowledged if it is new for a session or when
-   *   it is identical to a previously used for the same session.
-   *   Applications can control the behaviour.  They can at any time
-   *   set a 'desirable' servername for a new SSL object. This can be the
-   *   case for example with HTTPS when a Host: header field is received and
-   *   a renegotiation is requested. In this case, a possible servername
-   *   presented in the new client hello is only acknowledged if it matches
-   *   the value of the Host: field.
-   * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
-   *   if they provide for changing an explicit servername context for the
-   *   session,
-   *   i.e. when the session has been established with a servername extension.
-   */
-
-  CBS server_name_list;
-  char have_seen_host_name = 0;
-
+  CBS server_name_list, host_name;
+  uint8_t name_type;
   if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
-      CBS_len(&server_name_list) == 0 ||
+      !CBS_get_u8(&server_name_list, &name_type) ||
+      /* Although the server_name extension was intended to be extensible to
+       * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
+       * different name types will cause an error. Further, RFC 4366 originally
+       * defined syntax inextensibly. RFC 6066 corrected this mistake, but
+       * adding new name types is no longer feasible.
+       *
+       * Act as if the extensibility does not exist to simplify parsing. */
+      !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+      CBS_len(&server_name_list) != 0 ||
       CBS_len(contents) != 0) {
     return 0;
   }
 
-  /* Decode each ServerName in the extension. */
-  while (CBS_len(&server_name_list) > 0) {
-    uint8_t name_type;
-    CBS host_name;
+  if (name_type != TLSEXT_NAMETYPE_host_name ||
+      CBS_len(&host_name) == 0 ||
+      CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
+      CBS_contains_zero_byte(&host_name)) {
+    *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+    return 0;
+  }
 
-    if (!CBS_get_u8(&server_name_list, &name_type) ||
-        !CBS_get_u16_length_prefixed(&server_name_list, &host_name)) {
+  /* TODO(davidben): SNI should be resolved before resumption. We have the
+   * early callback as a replacement, but we should fix the current callback
+   * and avoid the need for |SSL_CTX_set_session_id_context|. */
+  if (!ssl->hit) {
+    assert(ssl->session->tlsext_hostname == NULL);
+
+    /* Copy the hostname as a string. */
+    if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
+      *out_alert = SSL_AD_INTERNAL_ERROR;
       return 0;
     }
 
-    /* Only host_name is supported. */
-    if (name_type != TLSEXT_NAMETYPE_host_name) {
-      continue;
-    }
-
-    if (have_seen_host_name) {
-      /* The ServerNameList MUST NOT contain more than one name of the same
-       * name_type. */
-      return 0;
-    }
-
-    have_seen_host_name = 1;
-
-    if (CBS_len(&host_name) == 0 ||
-        CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
-        CBS_contains_zero_byte(&host_name)) {
-      *out_alert = SSL_AD_UNRECOGNIZED_NAME;
-      return 0;
-    }
-
-    if (!ssl->hit) {
-      assert(ssl->session->tlsext_hostname == NULL);
-      if (ssl->session->tlsext_hostname) {
-        /* This should be impossible. */
-        return 0;
-      }
-
-      /* Copy the hostname as a string. */
-      if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
-        *out_alert = SSL_AD_INTERNAL_ERROR;
-        return 0;
-      }
-
-      ssl->s3->tmp.should_ack_sni = 1;
-    }
+    ssl->s3->tmp.should_ack_sni = 1;
   }
 
   return 1;
@@ -975,7 +893,7 @@
 
 /* Extended Master Secret.
  *
- * https://tools.ietf.org/html/draft-ietf-tls-session-hash-05 */
+ * https://tools.ietf.org/html/rfc7627 */
 
 static void ext_ems_init(SSL *ssl) {
   ssl->s3->tmp.extended_master_secret = 0;
@@ -1185,6 +1103,7 @@
 
 static void ext_ocsp_init(SSL *ssl) {
   ssl->s3->tmp.certificate_status_expected = 0;
+  ssl->tlsext_status_type = -1;
 }
 
 static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
@@ -1202,6 +1121,7 @@
     return 0;
   }
 
+  ssl->tlsext_status_type = TLSEXT_STATUSTYPE_ocsp;
   return 1;
 }
 
@@ -1317,14 +1237,14 @@
     return 0;
   }
 
-  OPENSSL_free(ssl->next_proto_negotiated);
-  ssl->next_proto_negotiated = BUF_memdup(selected, selected_len);
-  if (ssl->next_proto_negotiated == NULL) {
+  OPENSSL_free(ssl->s3->next_proto_negotiated);
+  ssl->s3->next_proto_negotiated = BUF_memdup(selected, selected_len);
+  if (ssl->s3->next_proto_negotiated == NULL) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return 0;
   }
 
-  ssl->next_proto_negotiated_len = selected_len;
+  ssl->s3->next_proto_negotiated_len = selected_len;
   ssl->s3->next_proto_neg_seen = 1;
 
   return 1;
@@ -1945,9 +1865,7 @@
     return 0;
   }
 
-  ssl->s3->tmp.peer_ellipticcurvelist =
-      (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
-
+  ssl->s3->tmp.peer_ellipticcurvelist = OPENSSL_malloc(CBS_len(&elliptic_curve_list));
   if (ssl->s3->tmp.peer_ellipticcurvelist == NULL) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return 0;
@@ -2081,6 +1999,9 @@
     ext_ec_point_parse_clienthello,
     ext_ec_point_add_serverhello,
   },
+  /* The final extension must be non-empty. WebSphere Application Server 7.0 is
+   * intolerant to the last extension being zero-length. See
+   * https://crbug.com/363583. */
   {
     TLSEXT_TYPE_elliptic_curves,
     ext_ec_curves_init,
@@ -2167,9 +2088,10 @@
        * NB: because this code works out the length of all existing extensions
        * it MUST always appear last. */
       size_t padding_len = 0x200 - header_len;
-      /* Extensions take at least four bytes to encode. Always include least
+      /* Extensions take at least four bytes to encode. Always include at least
        * one byte of data if including the extension. WebSphere Application
-       * Server 7.0 is intolerant to the last extension being zero-length. */
+       * Server 7.0 is intolerant to the last extension being zero-length. See
+       * https://crbug.com/363583. */
       if (padding_len >= 4 + 1) {
         padding_len -= 4;
       } else {
@@ -2411,14 +2333,10 @@
   int ret = SSL_TLSEXT_ERR_NOACK;
   int al = SSL_AD_UNRECOGNIZED_NAME;
 
-  /* The handling of the ECPointFormats extension is done elsewhere, namely in
-   * ssl3_choose_cipher in s3_lib.c. */
-
-  if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+  if (ssl->ctx->tlsext_servername_callback != 0) {
     ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
-                                             ssl->ctx->tlsext_servername_arg);
-  } else if (ssl->initial_ctx != NULL &&
-             ssl->initial_ctx->tlsext_servername_callback != 0) {
+                                               ssl->ctx->tlsext_servername_arg);
+  } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
     ret = ssl->initial_ctx->tlsext_servername_callback(
         ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
   }
@@ -2445,11 +2363,10 @@
   int ret = SSL_TLSEXT_ERR_OK;
   int al = SSL_AD_UNRECOGNIZED_NAME;
 
-  if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+  if (ssl->ctx->tlsext_servername_callback != 0) {
     ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
-                                             ssl->ctx->tlsext_servername_arg);
-  } else if (ssl->initial_ctx != NULL &&
-             ssl->initial_ctx->tlsext_servername_callback != 0) {
+                                               ssl->ctx->tlsext_servername_arg);
+  } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
     ret = ssl->initial_ctx->tlsext_servername_callback(
         ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
   }
@@ -2484,7 +2401,7 @@
 }
 
 int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
-                       int *out_send_ticket, const uint8_t *ticket,
+                       int *out_renew_ticket, const uint8_t *ticket,
                        size_t ticket_len, const uint8_t *session_id,
                        size_t session_id_len) {
   int ret = 1; /* Most errors are non-fatal. */
@@ -2496,19 +2413,13 @@
   EVP_CIPHER_CTX cipher_ctx;
   EVP_CIPHER_CTX_init(&cipher_ctx);
 
-  *out_send_ticket = 0;
+  *out_renew_ticket = 0;
   *out_session = NULL;
 
   if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
     goto done;
   }
 
-  if (ticket_len == 0) {
-    /* The client will accept a ticket but doesn't currently have one. */
-    *out_send_ticket = 1;
-    goto done;
-  }
-
   /* Ensure there is room for the key name and the largest IV
    * |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but
    * the maximum IV length should be well under the minimum size for the
@@ -2530,7 +2441,7 @@
       goto done;
     }
     if (cb_ret == 2) {
-      *out_send_ticket = 1;
+      *out_renew_ticket = 1;
     }
   } else {
     /* Check the key name matches. */
@@ -2609,12 +2520,12 @@
   int id;
 } tls12_lookup;
 
-static const tls12_lookup tls12_md[] = {{NID_md5, TLSEXT_hash_md5},
-                                        {NID_sha1, TLSEXT_hash_sha1},
-                                        {NID_sha224, TLSEXT_hash_sha224},
-                                        {NID_sha256, TLSEXT_hash_sha256},
-                                        {NID_sha384, TLSEXT_hash_sha384},
-                                        {NID_sha512, TLSEXT_hash_sha512}};
+static const tls12_lookup tls12_md[] = {
+    {NID_sha1, TLSEXT_hash_sha1},
+    {NID_sha256, TLSEXT_hash_sha256},
+    {NID_sha384, TLSEXT_hash_sha384},
+    {NID_sha512, TLSEXT_hash_sha512},
+};
 
 static const tls12_lookup tls12_sig[] = {{EVP_PKEY_RSA, TLSEXT_signature_rsa},
                                          {EVP_PKEY_EC, TLSEXT_signature_ecdsa}};
@@ -2648,15 +2559,9 @@
 
 const EVP_MD *tls12_get_hash(uint8_t hash_alg) {
   switch (hash_alg) {
-    case TLSEXT_hash_md5:
-      return EVP_md5();
-
     case TLSEXT_hash_sha1:
       return EVP_sha1();
 
-    case TLSEXT_hash_sha224:
-      return EVP_sha224();
-
     case TLSEXT_hash_sha256:
       return EVP_sha256();
 
@@ -2691,7 +2596,7 @@
 
 int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
   /* Extension ignored for inappropriate versions */
-  if (!SSL_USE_SIGALGS(ssl)) {
+  if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
     return 1;
   }
 
@@ -2742,7 +2647,7 @@
   size_t i, j;
 
   static const int kDefaultDigestList[] = {NID_sha256, NID_sha384, NID_sha512,
-                                           NID_sha224, NID_sha1};
+                                           NID_sha1};
 
   const int *digest_nids = kDefaultDigestList;
   size_t num_digest_nids =
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 74674a4..5effa58 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -46,7 +46,7 @@
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/hmac.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/ssl.h>
 
@@ -138,13 +138,20 @@
   return (TestState *)SSL_get_ex_data(ssl, g_state_index);
 }
 
+static ScopedX509 LoadCertificate(const std::string &file) {
+  ScopedBIO bio(BIO_new(BIO_s_file()));
+  if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
+    return nullptr;
+  }
+  return ScopedX509(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
+}
+
 static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
   ScopedBIO bio(BIO_new(BIO_s_file()));
   if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
     return nullptr;
   }
-  ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
-  return pkey;
+  return ScopedEVP_PKEY(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
 }
 
 static int AsyncPrivateKeyType(SSL *ssl) {
@@ -291,9 +298,9 @@
   }
 };
 
-static bool InstallCertificate(SSL *ssl) {
+static bool GetCertificate(SSL *ssl, ScopedX509 *out_x509,
+                           ScopedEVP_PKEY *out_pkey) {
   const TestConfig *config = GetConfigPtr(ssl);
-  TestState *test_state = GetTestState(ssl);
 
   if (!config->digest_prefs.empty()) {
     std::unique_ptr<char, Free<char>> digest_prefs(
@@ -317,21 +324,16 @@
   }
 
   if (!config->key_file.empty()) {
-    if (config->async) {
-      test_state->private_key = LoadPrivateKey(config->key_file.c_str());
-      if (!test_state->private_key) {
-        return false;
-      }
-      SSL_set_private_key_method(ssl, &g_async_private_key_method);
-    } else if (!SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
-                                        SSL_FILETYPE_PEM)) {
+    *out_pkey = LoadPrivateKey(config->key_file.c_str());
+    if (!*out_pkey) {
       return false;
     }
   }
-  if (!config->cert_file.empty() &&
-      !SSL_use_certificate_file(ssl, config->cert_file.c_str(),
-                                SSL_FILETYPE_PEM)) {
-    return false;
+  if (!config->cert_file.empty()) {
+    *out_x509 = LoadCertificate(config->cert_file.c_str());
+    if (!*out_x509) {
+      return false;
+    }
   }
   if (!config->ocsp_response.empty() &&
       !SSL_CTX_set_ocsp_response(ssl->ctx,
@@ -342,6 +344,31 @@
   return true;
 }
 
+static bool InstallCertificate(SSL *ssl) {
+  ScopedX509 x509;
+  ScopedEVP_PKEY pkey;
+  if (!GetCertificate(ssl, &x509, &pkey)) {
+    return false;
+  }
+
+  if (pkey) {
+    TestState *test_state = GetTestState(ssl);
+    const TestConfig *config = GetConfigPtr(ssl);
+    if (config->async) {
+      test_state->private_key = std::move(pkey);
+      SSL_set_private_key_method(ssl, &g_async_private_key_method);
+    } else if (!SSL_use_PrivateKey(ssl, pkey.get())) {
+      return false;
+    }
+  }
+
+  if (x509 && !SSL_use_certificate(ssl, x509.get())) {
+    return false;
+  }
+
+  return true;
+}
+
 static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
   const TestConfig *config = GetConfigPtr(ctx->ssl);
   GetTestState(ctx->ssl)->early_callback_called = true;
@@ -394,6 +421,28 @@
   return 1;
 }
 
+static int ClientCertCallback(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
+  if (GetConfigPtr(ssl)->async && !GetTestState(ssl)->cert_ready) {
+    return -1;
+  }
+
+  ScopedX509 x509;
+  ScopedEVP_PKEY pkey;
+  if (!GetCertificate(ssl, &x509, &pkey)) {
+    return -1;
+  }
+
+  // Return zero for no certificate.
+  if (!x509) {
+    return 0;
+  }
+
+  // Asynchronous private keys are not supported with client_cert_cb.
+  *out_x509 = x509.release();
+  *out_pkey = pkey.release();
+  return 1;
+}
+
 static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) {
   SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
       SSL_get_ex_data_X509_STORE_CTX_idx());
@@ -444,7 +493,7 @@
 static int AlpnSelectCallback(SSL* ssl, const uint8_t** out, uint8_t* outlen,
                               const uint8_t* in, unsigned inlen, void* arg) {
   const TestConfig *config = GetConfigPtr(ssl);
-  if (config->select_alpn.empty()) {
+  if (config->decline_alpn) {
     return SSL_TLSEXT_ERR_NOACK;
   }
 
@@ -732,6 +781,9 @@
   }
 
   ScopedDH dh(DH_get_2048_256(NULL));
+  if (!dh) {
+    return nullptr;
+  }
 
   if (config->use_sparse_dh_prime) {
     // This prime number is 2^1024 + 643 – a value just above a power of two.
@@ -747,10 +799,12 @@
         !BN_set_word(dh->g, 2)) {
       return nullptr;
     }
+    BN_free(dh->q);
+    dh->q = NULL;
     dh->priv_length = 0;
   }
 
-  if (!dh || !SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
+  if (!SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
     return nullptr;
   }
 
@@ -766,6 +820,10 @@
 
   SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
 
+  if (config->use_old_client_cert_callback) {
+    SSL_CTX_set_client_cert_cb(ssl_ctx.get(), ClientCertCallback);
+  }
+
   SSL_CTX_set_next_protos_advertised_cb(
       ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
   if (!config->select_next_proto.empty()) {
@@ -773,7 +831,7 @@
                                      NULL);
   }
 
-  if (!config->select_alpn.empty()) {
+  if (!config->select_alpn.empty() || config->decline_alpn) {
     SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
   }
 
@@ -1138,9 +1196,8 @@
       !SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
     return false;
   }
-  if (!config->use_early_callback) {
+  if (!config->use_early_callback && !config->use_old_client_cert_callback) {
     if (config->async) {
-      // TODO(davidben): Also test |s->ctx->client_cert_cb| on the client.
       SSL_set_cert_cb(ssl.get(), CertCallback, NULL);
     } else if (!InstallCertificate(ssl.get())) {
       return false;
@@ -1253,7 +1310,7 @@
   }
   if (config->enable_all_curves) {
     static const int kAllCurves[] = {
-        NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_x25519,
+        NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_X25519,
     };
     if (!SSL_set1_curves(ssl.get(), kAllCurves,
                          sizeof(kAllCurves) / sizeof(kAllCurves[0]))) {
@@ -1274,12 +1331,18 @@
   if (config->is_dtls) {
     ScopedBIO packeted =
         PacketedBioCreate(&GetTestState(ssl.get())->clock_delta);
+    if (!packeted) {
+      return false;
+    }
     BIO_push(packeted.get(), bio.release());
     bio = std::move(packeted);
   }
   if (config->async) {
     ScopedBIO async_scoped =
         config->is_dtls ? AsyncBioCreateDatagram() : AsyncBioCreate();
+    if (!async_scoped) {
+      return false;
+    }
     BIO_push(async_scoped.get(), bio.release());
     GetTestState(ssl.get())->async_bio = async_scoped.get();
     bio = std::move(async_scoped);
@@ -1483,7 +1546,16 @@
   return true;
 }
 
+class StderrDelimiter {
+ public:
+  ~StderrDelimiter() { fprintf(stderr, "--- DONE ---\n"); }
+};
+
 int main(int argc, char **argv) {
+  // To distinguish ASan's output from ours, add a trailing message to stderr.
+  // Anything following this line will be considered an error.
+  StderrDelimiter delimiter;
+
 #if defined(OPENSSL_WINDOWS)
   /* Initialize Winsock. */
   WORD wsa_version = MAKEWORD(2, 2);
diff --git a/src/ssl/test/runner/alert.go b/src/ssl/test/runner/alert.go
index 541216e..7db6826 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -22,6 +22,7 @@
 	alertRecordOverflow         alert = 22
 	alertDecompressionFailure   alert = 30
 	alertHandshakeFailure       alert = 40
+	alertNoCertficate           alert = 41
 	alertBadCertificate         alert = 42
 	alertUnsupportedCertificate alert = 43
 	alertCertificateRevoked     alert = 44
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index db3c675..2e9ce04 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -424,6 +424,10 @@
 	// to be wrong.
 	InvalidSKXCurve bool
 
+	// InvalidECDHPoint, if true, causes the ECC points in
+	// ServerKeyExchange or ClientKeyExchange messages to be invalid.
+	InvalidECDHPoint bool
+
 	// BadECDSAR controls ways in which the 'r' value of an ECDSA signature
 	// can be invalid.
 	BadECDSAR BadValue
@@ -469,6 +473,10 @@
 	// NewSessionTicket message despite promising to in ServerHello.
 	SkipNewSessionTicket bool
 
+	// SkipClientCertificate causes the client to skip the Certificate
+	// message.
+	SkipClientCertificate bool
+
 	// SkipChangeCipherSpec causes the implementation to skip
 	// sending the ChangeCipherSpec message (and adjusting cipher
 	// state accordingly for the Finished message).
@@ -517,6 +525,10 @@
 	// two records.
 	FragmentAlert bool
 
+	// DoubleAlert will cause all alerts to be sent as two copies packed
+	// within one record.
+	DoubleAlert bool
+
 	// SendSpuriousAlert, if non-zero, will cause an spurious, unwanted
 	// alert to be sent.
 	SendSpuriousAlert alert
@@ -814,6 +826,14 @@
 	// BadHelloRequest, if not nil, is what to send instead of a
 	// HelloRequest.
 	BadHelloRequest []byte
+
+	// RequireSessionTickets, if true, causes the client to require new
+	// sessions use session tickets instead of session IDs.
+	RequireSessionTickets bool
+
+	// NullAllCiphers, if true, causes every cipher to behave like the null
+	// cipher.
+	NullAllCiphers bool
 }
 
 func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index cb60a92..43548e8 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -189,6 +189,11 @@
 	hc.nextMac = nil
 	hc.config = config
 	hc.incEpoch()
+
+	if config.Bugs.NullAllCiphers {
+		hc.cipher = nil
+		hc.mac = nil
+	}
 	return nil
 }
 
@@ -837,6 +842,9 @@
 	if c.config.Bugs.FragmentAlert {
 		c.writeRecord(recordTypeAlert, c.tmp[0:1])
 		c.writeRecord(recordTypeAlert, c.tmp[1:2])
+	} else if c.config.Bugs.DoubleAlert {
+		copy(c.tmp[2:4], c.tmp[0:2])
+		c.writeRecord(recordTypeAlert, c.tmp[0:4])
 	} else {
 		c.writeRecord(recordTypeAlert, c.tmp[0:2])
 	}
@@ -851,7 +859,7 @@
 // L < c.out.Mutex.
 func (c *Conn) sendAlert(err alert) error {
 	level := byte(alertLevelError)
-	if err == alertNoRenegotiation || err == alertCloseNotify {
+	if err == alertNoRenegotiation || err == alertCloseNotify || err == alertNoCertficate {
 		level = alertLevelWarning
 	}
 	return c.SendAlert(level, err)
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 64630ba..67609fc 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -363,6 +363,9 @@
 	}
 
 	if sessionCache != nil && hs.session != nil && session != hs.session {
+		if c.config.Bugs.RequireSessionTickets && len(hs.session.sessionTicket) == 0 {
+			return errors.New("tls: new session used session IDs instead of tickets")
+		}
 		sessionCache.Put(cacheKey, hs.session)
 	}
 
@@ -561,15 +564,20 @@
 	hs.writeServerHash(shd.marshal())
 
 	// If the server requested a certificate then we have to send a
-	// Certificate message, even if it's empty because we don't have a
-	// certificate to send.
+	// Certificate message in TLS, even if it's empty because we don't have
+	// a certificate to send. In SSL 3.0, skip the message and send a
+	// no_certificate warning alert.
 	if certRequested {
-		certMsg := new(certificateMsg)
-		if chainToSend != nil {
-			certMsg.certificates = chainToSend.Certificate
+		if c.vers == VersionSSL30 && chainToSend == nil {
+			c.sendAlert(alertNoCertficate)
+		} else if !c.config.Bugs.SkipClientCertificate {
+			certMsg := new(certificateMsg)
+			if chainToSend != nil {
+				certMsg.certificates = chainToSend.Certificate
+			}
+			hs.writeClientHash(certMsg.marshal())
+			c.writeRecord(recordTypeHandshake, certMsg.marshal())
 		}
-		hs.writeClientHash(certMsg.marshal())
-		c.writeRecord(recordTypeHandshake, certMsg.marshal())
 	}
 
 	preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index 530ddbc..092f51e 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -349,7 +349,7 @@
 		z = z[4:]
 	}
 	if m.extendedMasterSecret {
-		// https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
+		// https://tools.ietf.org/html/rfc7627
 		z[0] = byte(extensionExtendedMasterSecret >> 8)
 		z[1] = byte(extensionExtendedMasterSecret & 0xff)
 		z = z[4:]
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 0232772..d2cac98 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -626,13 +626,22 @@
 	// certificate message, even if it's empty.
 	if config.ClientAuth >= RequestClientCert {
 		var certMsg *certificateMsg
-		if certMsg, ok = msg.(*certificateMsg); !ok {
+		var certificates [][]byte
+		if certMsg, ok = msg.(*certificateMsg); ok {
+			if c.vers == VersionSSL30 && len(certMsg.certificates) == 0 {
+				return errors.New("tls: empty certificate message in SSL 3.0")
+			}
+
+			hs.writeClientHash(certMsg.marshal())
+			certificates = certMsg.certificates
+		} else if c.vers != VersionSSL30 {
+			// In TLS, the Certificate message is required. In SSL
+			// 3.0, the peer skips it when sending no certificates.
 			c.sendAlert(alertUnexpectedMessage)
 			return unexpectedMessageError(certMsg, msg)
 		}
-		hs.writeClientHash(certMsg.marshal())
 
-		if len(certMsg.certificates) == 0 {
+		if len(certificates) == 0 {
 			// The client didn't actually send a certificate
 			switch config.ClientAuth {
 			case RequireAnyClientCert, RequireAndVerifyClientCert:
@@ -641,14 +650,16 @@
 			}
 		}
 
-		pub, err = hs.processCertsFromClient(certMsg.certificates)
+		pub, err = hs.processCertsFromClient(certificates)
 		if err != nil {
 			return err
 		}
 
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
+		if ok {
+			msg, err = c.readHandshake()
+			if err != nil {
+				return err
+			}
 		}
 	}
 
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 4f399d9..54aa3d3 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -312,8 +312,7 @@
 	copy(peerKeyCopy[:], peerKey)
 	curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
 
-	// Per draft-irtf-cfrg-curves-11, reject the all-zero value in constant
-	// time.
+	// Per RFC 7748, reject the all-zero value in constant time.
 	var zeros [32]byte
 	if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 {
 		return nil, errors.New("tls: X25519 value with wrong order")
@@ -567,6 +566,9 @@
 	}
 	serverECDHParams[3] = byte(len(publicKey))
 	copy(serverECDHParams[4:], publicKey)
+	if config.Bugs.InvalidECDHPoint {
+		serverECDHParams[4] ^= 0xff
+	}
 
 	return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
 }
@@ -623,6 +625,9 @@
 	ckx.ciphertext = make([]byte, 1+len(publicKey))
 	ckx.ciphertext[0] = byte(len(publicKey))
 	copy(ckx.ciphertext[1:], publicKey)
+	if config.Bugs.InvalidECDHPoint {
+		ckx.ciphertext[1] ^= 0xff
+	}
 
 	return preMasterSecret, ckx, nil
 }
diff --git a/src/ssl/test/runner/prf.go b/src/ssl/test/runner/prf.go
index 8521aba..f1b26de 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -153,7 +153,7 @@
 
 // extendedMasterFromPreMasterSecret generates the master secret from the
 // pre-master secret when the Triple Handshake fix is in effect. See
-// https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
+// https://tools.ietf.org/html/rfc7627
 func extendedMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret []byte, h finishedHash) []byte {
 	masterSecret := make([]byte, masterSecretLength)
 	prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, h.Sum())
diff --git a/src/ssl/test/runner/recordingconn.go b/src/ssl/test/runner/recordingconn.go
index 39deb19..752610e 100644
--- a/src/ssl/test/runner/recordingconn.go
+++ b/src/ssl/test/runner/recordingconn.go
@@ -92,6 +92,17 @@
 	}
 }
 
+func (r *recordingConn) Transcript() []byte {
+	var ret []byte
+	for _, flow := range r.flows {
+		if flow.flowType != writeFlow {
+			continue
+		}
+		ret = append(ret, flow.data...)
+	}
+	return ret
+}
+
 func parseTestData(r io.Reader) (flows [][]byte, err error) {
 	var currentFlow []byte
 
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 45bb0b7..5b746c6 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -37,6 +37,9 @@
 	numWorkers      = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
 	shimPath        = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
 	resourceDir     = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
+	fuzzer          = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.")
+	transcriptDir   = flag.String("transcript-dir", "", "The directory in which to write transcripts.")
+	timeout         = flag.Int("timeout", 15, "The number of seconds to wait for a read or write to bssl_shim.")
 )
 
 const (
@@ -244,15 +247,68 @@
 
 var testCases []testCase
 
+func writeTranscript(test *testCase, isResume bool, data []byte) {
+	if len(data) == 0 {
+		return
+	}
+
+	protocol := "tls"
+	if test.protocol == dtls {
+		protocol = "dtls"
+	}
+
+	side := "client"
+	if test.testType == serverTest {
+		side = "server"
+	}
+
+	dir := path.Join(*transcriptDir, protocol, side)
+	if err := os.MkdirAll(dir, 0755); err != nil {
+		fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err)
+		return
+	}
+
+	name := test.name
+	if isResume {
+		name += "-Resume"
+	} else {
+		name += "-Normal"
+	}
+
+	if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil {
+		fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err)
+	}
+}
+
+// A timeoutConn implements an idle timeout on each Read and Write operation.
+type timeoutConn struct {
+	net.Conn
+	timeout time.Duration
+}
+
+func (t *timeoutConn) Read(b []byte) (int, error) {
+	if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
+		return 0, err
+	}
+	return t.Conn.Read(b)
+}
+
+func (t *timeoutConn) Write(b []byte) (int, error) {
+	if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
+		return 0, err
+	}
+	return t.Conn.Write(b)
+}
+
 func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
-	var connDamage *damageAdaptor
+	conn = &timeoutConn{conn, time.Duration(*timeout) * time.Second}
 
 	if test.protocol == dtls {
 		config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
 		conn = config.Bugs.PacketAdaptor
 	}
 
-	if *flagDebug {
+	if *flagDebug || len(*transcriptDir) != 0 {
 		local, peer := "client", "server"
 		if test.testType == clientTest {
 			local, peer = peer, local
@@ -264,9 +320,14 @@
 			peer:       peer,
 		}
 		conn = connDebug
-		defer func() {
-			connDebug.WriteTo(os.Stdout)
-		}()
+		if *flagDebug {
+			defer connDebug.WriteTo(os.Stdout)
+		}
+		if len(*transcriptDir) != 0 {
+			defer func() {
+				writeTranscript(test, isResume, connDebug.Transcript())
+			}()
+		}
 
 		if config.Bugs.PacketAdaptor != nil {
 			config.Bugs.PacketAdaptor.debug = connDebug
@@ -277,6 +338,7 @@
 		conn = newReplayAdaptor(conn)
 	}
 
+	var connDamage *damageAdaptor
 	if test.damageFirstWrite {
 		connDamage = newDamageAdaptor(conn)
 		conn = connDamage
@@ -686,6 +748,9 @@
 			config.ServerName = "test"
 		}
 	}
+	if *fuzzer {
+		config.Bugs.NullAllCiphers = true
+	}
 
 	conn, err := acceptOrWait(listener, waitChan)
 	if err == nil {
@@ -713,6 +778,9 @@
 				resumeConfig.ClientSessionCache = config.ClientSessionCache
 				resumeConfig.ServerSessionCache = config.ServerSessionCache
 			}
+			if *fuzzer {
+				resumeConfig.Bugs.NullAllCiphers = true
+			}
 		} else {
 			resumeConfig = config
 		}
@@ -736,8 +804,18 @@
 		}
 	}
 
-	stdout := string(stdoutBuf.Bytes())
-	stderr := string(stderrBuf.Bytes())
+	// Account for Windows line endings.
+	stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
+	stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
+
+	// Separate the errors from the shim and those from tools like
+	// AddressSanitizer.
+	var extraStderr string
+	if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
+		stderr = stderrParts[0]
+		extraStderr = stderrParts[1]
+	}
+
 	failed := err != nil || childErr != nil
 	correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
 	localError := "none"
@@ -769,8 +847,8 @@
 		return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr)
 	}
 
-	if !*useValgrind && !failed && len(stderr) > 0 {
-		println(stderr)
+	if !*useValgrind && (len(extraStderr) > 0 || (!failed && len(stderr) > 0)) {
+		return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
 	}
 
 	return nil
@@ -1128,6 +1206,31 @@
 		},
 		{
 			testType: serverTest,
+			name:     "DoubleAlert",
+			config: Config{
+				Bugs: ProtocolBugs{
+					DoubleAlert:       true,
+					SendSpuriousAlert: alertRecordOverflow,
+				},
+			},
+			shouldFail:    true,
+			expectedError: ":BAD_ALERT:",
+		},
+		{
+			protocol: dtls,
+			testType: serverTest,
+			name:     "DoubleAlert-DTLS",
+			config: Config{
+				Bugs: ProtocolBugs{
+					DoubleAlert:       true,
+					SendSpuriousAlert: alertRecordOverflow,
+				},
+			},
+			shouldFail:    true,
+			expectedError: ":BAD_ALERT:",
+		},
+		{
+			testType: serverTest,
 			name:     "EarlyChangeCipherSpec-server-1",
 			config: Config{
 				Bugs: ProtocolBugs{
@@ -1708,7 +1811,18 @@
 			expectedError: ":WRONG_CURVE:",
 		},
 		{
-			name: "BadFinished",
+			name: "BadFinished-Client",
+			config: Config{
+				Bugs: ProtocolBugs{
+					BadFinished: true,
+				},
+			},
+			shouldFail:    true,
+			expectedError: ":DIGEST_CHECK_FAILED:",
+		},
+		{
+			testType: serverTest,
+			name:     "BadFinished-Server",
 			config: Config{
 				Bugs: ProtocolBugs{
 					BadFinished: true,
@@ -2088,6 +2202,40 @@
 			shouldFail:    true,
 			expectedError: ":BAD_HELLO_REQUEST:",
 		},
+		{
+			testType: serverTest,
+			name:     "SupportTicketsWithSessionID",
+			config: Config{
+				SessionTicketsDisabled: true,
+			},
+			resumeConfig:  &Config{},
+			resumeSession: true,
+		},
+		{
+			name: "InvalidECDHPoint-Client",
+			config: Config{
+				CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				CurvePreferences: []CurveID{CurveP256},
+				Bugs: ProtocolBugs{
+					InvalidECDHPoint: true,
+				},
+			},
+			shouldFail:    true,
+			expectedError: ":INVALID_ENCODING:",
+		},
+		{
+			testType: serverTest,
+			name:     "InvalidECDHPoint-Server",
+			config: Config{
+				CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				CurvePreferences: []CurveID{CurveP256},
+				Bugs: ProtocolBugs{
+					InvalidECDHPoint: true,
+				},
+			},
+			shouldFail:    true,
+			expectedError: ":INVALID_ENCODING:",
+		},
 	}
 	testCases = append(testCases, basicTests...)
 }
@@ -2280,6 +2428,16 @@
 		flags: []string{"-use-sparse-dh-prime"},
 	})
 
+	// The server must be tolerant to bogus ciphers.
+	const bogusCipher = 0x1234
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "UnknownCipher",
+		config: Config{
+			CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+		},
+	})
+
 	// versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
 	// 1.1 specific cipher suite settings. A server is setup with the given
 	// cipher lists and then a connection is made for each member of
@@ -2383,7 +2541,7 @@
 					},
 				},
 				shouldFail:    true,
-				expectedError: "SIGNATURE",
+				expectedError: ":BAD_SIGNATURE:",
 			})
 		}
 	}
@@ -2409,7 +2567,7 @@
 			},
 		},
 		shouldFail:    true,
-		expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
 	})
 	// OpenSSL previously had an issue where the first byte of padding in
 	// 255 bytes of padding wasn't checked.
@@ -2424,7 +2582,7 @@
 		},
 		messageLen:    12, // 20 bytes of SHA-1 + 12 == 0 % block size
 		shouldFail:    true,
-		expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
 	})
 }
 
@@ -2523,6 +2681,39 @@
 			})
 		}
 	}
+
+	testCases = append(testCases, testCase{
+		testType:      serverTest,
+		name:          "RequireAnyClientCertificate",
+		flags:         []string{"-require-any-client-certificate"},
+		shouldFail:    true,
+		expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+	})
+
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "RequireAnyClientCertificate-SSL3",
+		config: Config{
+			MaxVersion: VersionSSL30,
+		},
+		flags:         []string{"-require-any-client-certificate"},
+		shouldFail:    true,
+		expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+	})
+
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "SkipClientCertificate",
+		config: Config{
+			Bugs: ProtocolBugs{
+				SkipClientCertificate: true,
+			},
+		},
+		// Setting SSL_VERIFY_PEER allows anonymous clients.
+		flags:         []string{"-verify-peer"},
+		shouldFail:    true,
+		expectedError: ":UNEXPECTED_MESSAGE:",
+	})
 }
 
 func addExtendedMasterSecretTests() {
@@ -2667,6 +2858,8 @@
 	tests = append(tests, testCase{
 		name:          "Basic-Client",
 		resumeSession: true,
+		// Ensure session tickets are used, not session IDs.
+		noSessionCache: true,
 	})
 	tests = append(tests, testCase{
 		name: "Basic-Client-RenewTicket",
@@ -2691,8 +2884,13 @@
 		resumeSession: true,
 	})
 	tests = append(tests, testCase{
-		testType:      serverTest,
-		name:          "Basic-Server",
+		testType: serverTest,
+		name:     "Basic-Server",
+		config: Config{
+			Bugs: ProtocolBugs{
+				RequireSessionTickets: true,
+			},
+		},
 		resumeSession: true,
 	})
 	tests = append(tests, testCase{
@@ -2719,6 +2917,46 @@
 	// TLS client auth.
 	tests = append(tests, testCase{
 		testType: clientTest,
+		name:     "ClientAuth-NoCertificate-Client",
+		config: Config{
+			ClientAuth: RequestClientCert,
+		},
+	})
+	tests = append(tests, testCase{
+		testType: serverTest,
+		name:     "ClientAuth-NoCertificate-Server",
+		// Setting SSL_VERIFY_PEER allows anonymous clients.
+		flags: []string{"-verify-peer"},
+	})
+	if protocol == tls {
+		tests = append(tests, testCase{
+			testType: clientTest,
+			name:     "ClientAuth-NoCertificate-Client-SSL3",
+			config: Config{
+				MaxVersion: VersionSSL30,
+				ClientAuth: RequestClientCert,
+			},
+		})
+		tests = append(tests, testCase{
+			testType: serverTest,
+			name:     "ClientAuth-NoCertificate-Server-SSL3",
+			config: Config{
+				MaxVersion: VersionSSL30,
+			},
+			// Setting SSL_VERIFY_PEER allows anonymous clients.
+			flags: []string{"-verify-peer"},
+		})
+	}
+	tests = append(tests, testCase{
+		testType: clientTest,
+		name:     "ClientAuth-NoCertificate-OldCallback",
+		config: Config{
+			ClientAuth: RequestClientCert,
+		},
+		flags: []string{"-use-old-client-cert-callback"},
+	})
+	tests = append(tests, testCase{
+		testType: clientTest,
 		name:     "ClientAuth-RSA-Client",
 		config: Config{
 			ClientAuth: RequireAnyClientCert,
@@ -2739,6 +2977,19 @@
 			"-key-file", path.Join(*resourceDir, ecdsaKeyFile),
 		},
 	})
+	tests = append(tests, testCase{
+		testType: clientTest,
+		name:     "ClientAuth-OldCallback",
+		config: Config{
+			ClientAuth: RequireAnyClientCert,
+		},
+		flags: []string{
+			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+			"-key-file", path.Join(*resourceDir, rsaKeyFile),
+			"-use-old-client-cert-callback",
+		},
+	})
+
 	if async {
 		// Test async keys against each key exchange.
 		tests = append(tests, testCase{
@@ -3223,11 +3474,7 @@
 				} else {
 					shouldFail = true
 					expectedError = ":UNSUPPORTED_PROTOCOL:"
-					if runnerVers.version > VersionSSL30 {
-						expectedLocalError = "remote error: protocol version not supported"
-					} else {
-						expectedLocalError = "remote error: handshake failure"
-					}
+					expectedLocalError = "remote error: protocol version not supported"
 				}
 
 				testCases = append(testCases, testCase{
@@ -3381,6 +3628,16 @@
 		expectedNextProtoType: alpn,
 		resumeSession:         true,
 	})
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "ALPNServer-Decline",
+		config: Config{
+			NextProtos: []string{"foo", "bar", "baz"},
+		},
+		flags:             []string{"-decline-alpn"},
+		expectNoNextProto: true,
+		resumeSession:     true,
+	})
 	// Test that the server prefers ALPN over NPN.
 	testCases = append(testCases, testCase{
 		testType: serverTest,
@@ -4087,7 +4344,6 @@
 	id   uint8
 }{
 	{"SHA1", hashSHA1},
-	{"SHA224", hashSHA224},
 	{"SHA256", hashSHA256},
 	{"SHA384", hashSHA384},
 	{"SHA512", hashSHA512},
@@ -4668,6 +4924,17 @@
 			flags: []string{"-enable-all-curves"},
 		})
 	}
+
+	// The server must be tolerant to bogus curves.
+	const bogusCurve = 0x1234
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "UnknownCurve",
+		config: Config{
+			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+			CurvePreferences: []CurveID{bogusCurve, CurveP256},
+		},
+	})
 }
 
 func addKeyExchangeInfoTests() {
@@ -4845,11 +5112,17 @@
 		go worker(statusChan, testChan, *shimPath, &wg)
 	}
 
+	var foundTest bool
 	for i := range testCases {
 		if len(*testToRun) == 0 || *testToRun == testCases[i].name {
+			foundTest = true
 			testChan <- &testCases[i]
 		}
 	}
+	if !foundTest {
+		fmt.Fprintf(os.Stderr, "No test named '%s'\n", *testToRun)
+		os.Exit(1)
+	}
 
 	close(testChan)
 	wg.Wait()
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 1cf316d..67a017d 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -62,6 +62,7 @@
   { "-no-ssl3", &TestConfig::no_ssl3 },
   { "-shim-writes-first", &TestConfig::shim_writes_first },
   { "-expect-session-miss", &TestConfig::expect_session_miss },
+  { "-decline-alpn", &TestConfig::decline_alpn },
   { "-expect-extended-master-secret",
     &TestConfig::expect_extended_master_secret },
   { "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
@@ -98,6 +99,8 @@
   { "-p384-only", &TestConfig::p384_only },
   { "-enable-all-curves", &TestConfig::enable_all_curves },
   { "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
+  { "-use-old-client-cert-callback",
+    &TestConfig::use_old_client_cert_callback },
 };
 
 const Flag<std::string> kStringFlags[] = {
@@ -178,12 +181,14 @@
       size_t len;
       if (!EVP_DecodedLength(&len, strlen(argv[i]))) {
         fprintf(stderr, "Invalid base64: %s\n", argv[i]);
+        return false;
       }
       std::unique_ptr<uint8_t[]> decoded(new uint8_t[len]);
       if (!EVP_DecodeBase64(decoded.get(), &len, len,
                             reinterpret_cast<const uint8_t *>(argv[i]),
                             strlen(argv[i]))) {
         fprintf(stderr, "Invalid base64: %s\n", argv[i]);
+        return false;
       }
       base64_field->assign(reinterpret_cast<const char *>(decoded.get()), len);
       continue;
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 4e0a46a..fe117d8 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -50,6 +50,7 @@
   std::string expected_alpn;
   std::string expected_advertised_alpn;
   std::string select_alpn;
+  bool decline_alpn = false;
   bool expect_session_miss = false;
   bool expect_extended_master_secret = false;
   std::string psk;
@@ -102,6 +103,7 @@
   bool enable_all_curves = false;
   bool use_sparse_dh_prime = false;
   int expect_key_exchange_info = 0;
+  bool use_old_client_cert_callback = false;
 };
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
index 3381eae..b71da17 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.c
@@ -109,6 +109,7 @@
 #include <openssl/ssl.h>
 
 #include <assert.h>
+#include <string.h>
 
 #include <openssl/bytestring.h>
 #include <openssl/err.h>
@@ -125,31 +126,44 @@
 /* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher
  * state needs record-splitting and zero otherwise. */
 static int ssl_needs_record_splitting(const SSL *ssl) {
-  return !SSL_USE_EXPLICIT_IV(ssl) && ssl->aead_write_ctx != NULL &&
+  return ssl->s3->aead_write_ctx != NULL &&
+         ssl3_protocol_version(ssl) < TLS1_1_VERSION &&
          (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
-         SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher);
+         SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher);
+}
+
+int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
+  size_t i;
+  for (i = seq_len - 1; i < seq_len; i--) {
+    ++seq[i];
+    if (seq[i] != 0) {
+      return 1;
+    }
+  }
+  OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+  return 0;
 }
 
 size_t ssl_record_prefix_len(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
   } else {
     return SSL3_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
   }
 }
 
 size_t ssl_seal_prefix_len(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
   } else {
     size_t ret = SSL3_RT_HEADER_LENGTH +
-                 SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+                 SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
     if (ssl_needs_record_splitting(ssl)) {
       ret += SSL3_RT_HEADER_LENGTH;
-      ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher);
+      ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher);
     }
     return ret;
   }
@@ -158,10 +172,10 @@
 size_t ssl_max_seal_overhead(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+           SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
   } else {
     size_t ret = SSL3_RT_HEADER_LENGTH +
-                 SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+                 SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
     if (ssl_needs_record_splitting(ssl)) {
       ret *= 2;
     }
@@ -215,14 +229,14 @@
 
   /* Decrypt the body. */
   size_t plaintext_len;
-  if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+  if (!SSL_AEAD_CTX_open(ssl->s3->aead_read_ctx, out, &plaintext_len, max_out,
                          type, version, ssl->s3->read_sequence, CBS_data(&body),
                          CBS_len(&body))) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
     *out_alert = SSL_AD_BAD_RECORD_MAC;
     return ssl_open_record_error;
   }
-  if (!ssl3_record_sequence_update(ssl->s3->read_sequence, 8)) {
+  if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return ssl_open_record_error;
   }
@@ -280,11 +294,11 @@
   out[2] = wire_version & 0xff;
 
   size_t ciphertext_len;
-  if (!SSL_AEAD_CTX_seal(ssl->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+  if (!SSL_AEAD_CTX_seal(ssl->s3->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
                          &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
                          type, wire_version, ssl->s3->write_sequence, in,
                          in_len) ||
-      !ssl3_record_sequence_update(ssl->s3->write_sequence, 8)) {
+      !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
     return 0;
   }
 
@@ -329,9 +343,11 @@
     out += frag_len;
     max_out -= frag_len;
 
-    assert(SSL3_RT_HEADER_LENGTH +
-               ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher) ==
+#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+    assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
+                                       ssl->s3->aead_write_ctx->cipher) ==
            frag_len);
+#endif
   }
 
   if (!do_seal_record(ssl, out, out_len, max_out, type, in, in_len)) {
@@ -340,3 +356,26 @@
   *out_len += frag_len;
   return 1;
 }
+
+void ssl_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
+  if (SSL_IS_DTLS(ssl)) {
+    ssl->d1->r_epoch++;
+    memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap));
+  }
+  memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
+
+  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+  ssl->s3->aead_read_ctx = aead_ctx;
+}
+
+void ssl_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
+  if (SSL_IS_DTLS(ssl)) {
+    ssl->d1->w_epoch++;
+    memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence,
+           sizeof(ssl->s3->write_sequence));
+  }
+  memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
+
+  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
+  ssl->s3->aead_write_ctx = aead_ctx;
+}
diff --git a/src/tool/digest.cc b/src/tool/digest.cc
index 7cd8827..012202c 100644
--- a/src/tool/digest.cc
+++ b/src/tool/digest.cc
@@ -41,6 +41,8 @@
 
 #include <openssl/digest.h>
 
+#include "internal.h"
+
 
 struct close_delete {
   void operator()(int *fd) {
diff --git a/src/tool/internal.h b/src/tool/internal.h
index 84f8c4d..6d26209 100644
--- a/src/tool/internal.h
+++ b/src/tool/internal.h
@@ -55,6 +55,21 @@
                  unsigned default_value,
                  const std::map<std::string, std::string> &args);
 
+bool Ciphers(const std::vector<std::string> &args);
+bool Client(const std::vector<std::string> &args);
+bool DoPKCS12(const std::vector<std::string> &args);
+bool GenerateEd25519Key(const std::vector<std::string> &args);
+bool GenerateRSAKey(const std::vector<std::string> &args);
+bool MD5Sum(const std::vector<std::string> &args);
+bool Rand(const std::vector<std::string> &args);
+bool SHA1Sum(const std::vector<std::string> &args);
+bool SHA224Sum(const std::vector<std::string> &args);
+bool SHA256Sum(const std::vector<std::string> &args);
+bool SHA384Sum(const std::vector<std::string> &args);
+bool SHA512Sum(const std::vector<std::string> &args);
+bool Server(const std::vector<std::string> &args);
+bool Speed(const std::vector<std::string> &args);
+
 // These values are DER encoded, RSA private keys.
 extern const uint8_t kDERRSAPrivate2048[];
 extern const size_t kDERRSAPrivate2048Len;
diff --git a/src/tool/rand.cc b/src/tool/rand.cc
index 10078e2..3701748 100644
--- a/src/tool/rand.cc
+++ b/src/tool/rand.cc
@@ -71,7 +71,7 @@
     }
     RAND_bytes(buf, todo);
     if (hex) {
-      static const char hextable[] = "0123456789abdef";
+      static const char hextable[16 + 1] = "0123456789abcdef";
       for (unsigned i = 0; i < todo; i++) {
         hex_buf[i*2] = hextable[buf[i] >> 4];
         hex_buf[i*2 + 1] = hextable[buf[i] & 0xf];
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index db7c5fa..68d78e2 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -24,7 +24,8 @@
 #include <openssl/curve25519.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
+#include <openssl/newhope.h>
+#include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
 
@@ -467,6 +468,82 @@
   return true;
 }
 
+static bool SpeedSPAKE2(const std::string &selected) {
+  if (!selected.empty() && selected.find("SPAKE2") == std::string::npos) {
+    return true;
+  }
+
+  TimeResults results;
+
+  static const uint8_t kAliceName[] = {'A'};
+  static const uint8_t kBobName[] = {'B'};
+  static const uint8_t kPassword[] = "password";
+  ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(spake2_role_alice, kAliceName,
+                                        sizeof(kAliceName), kBobName,
+                                        sizeof(kBobName)));
+  uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
+  size_t alice_msg_len;
+
+  if (!SPAKE2_generate_msg(alice.get(), alice_msg, &alice_msg_len,
+                           sizeof(alice_msg),
+                           kPassword, sizeof(kPassword))) {
+    fprintf(stderr, "SPAKE2_generate_msg failed.\n");
+    return false;
+  }
+
+  if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
+        ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(spake2_role_bob, kBobName,
+                                            sizeof(kBobName), kAliceName,
+                                            sizeof(kAliceName)));
+        uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
+        size_t bob_msg_len, bob_key_len;
+        if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
+                                 sizeof(bob_msg), kPassword,
+                                 sizeof(kPassword)) ||
+            !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len,
+                                sizeof(bob_key), alice_msg, alice_msg_len)) {
+          return false;
+        }
+
+        return true;
+      })) {
+    fprintf(stderr, "SPAKE2 failed.\n");
+  }
+
+  results.Print("SPAKE2 over Ed25519");
+
+  return true;
+}
+
+static bool SpeedNewHope(const std::string &selected) {
+  if (!selected.empty() && selected.find("newhope") == std::string::npos) {
+    return true;
+  }
+
+  TimeResults results;
+  NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+  uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+  RAND_bytes(clientmsg, sizeof(clientmsg));
+
+  if (!TimeFunction(&results, [sk, &clientmsg]() -> bool {
+        uint8_t server_key[SHA256_DIGEST_LENGTH];
+        uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+        NEWHOPE_keygen(servermsg, sk);
+        if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+                                        NEWHOPE_CLIENTMSG_LENGTH)) {
+          return false;
+        }
+        return true;
+      })) {
+    fprintf(stderr, "failed to exchange key.\n");
+    return false;
+  }
+
+  NEWHOPE_POLY_free(sk);
+  results.Print("newhope server key exchange");
+  return true;
+}
+
 bool Speed(const std::vector<std::string> &args) {
   std::string selected;
   if (args.size() > 1) {
@@ -546,7 +623,9 @@
       !SpeedRandom(selected) ||
       !SpeedECDH(selected) ||
       !SpeedECDSA(selected) ||
-      !Speed25519(selected)) {
+      !Speed25519(selected) ||
+      !SpeedSPAKE2(selected) ||
+      !SpeedNewHope(selected)) {
     return false;
   }
 
diff --git a/src/tool/tool.cc b/src/tool/tool.cc
index b825008..34851b4 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -26,21 +26,8 @@
 #include <libgen.h>
 #endif
 
+#include "internal.h"
 
-bool Ciphers(const std::vector<std::string> &args);
-bool Client(const std::vector<std::string> &args);
-bool DoPKCS12(const std::vector<std::string> &args);
-bool GenerateEd25519Key(const std::vector<std::string> &args);
-bool GenerateRSAKey(const std::vector<std::string> &args);
-bool MD5Sum(const std::vector<std::string> &args);
-bool Rand(const std::vector<std::string> &args);
-bool SHA1Sum(const std::vector<std::string> &args);
-bool SHA224Sum(const std::vector<std::string> &args);
-bool SHA256Sum(const std::vector<std::string> &args);
-bool SHA384Sum(const std::vector<std::string> &args);
-bool SHA512Sum(const std::vector<std::string> &args);
-bool Server(const std::vector<std::string> &args);
-bool Speed(const std::vector<std::string> &args);
 
 typedef bool (*tool_func_t)(const std::vector<std::string> &args);
 
@@ -83,7 +70,7 @@
   }
 }
 
-tool_func_t FindTool(const std::string &name) {
+static tool_func_t FindTool(const std::string &name) {
   for (size_t i = 0;; i++) {
     const Tool &tool = kTools[i];
     if (tool.func == nullptr || name == tool.name) {
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 2c15c00..9115214 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -44,8 +44,10 @@
 
 #include <openssl/err.h>
 #include <openssl/ssl.h>
+#include <openssl/x509.h>
 
 #include "internal.h"
+#include "transport_common.h"
 
 
 #if !defined(OPENSSL_WINDOWS)
@@ -190,6 +192,19 @@
   unsigned alpn_len;
   SSL_get0_alpn_selected(ssl, &alpn, &alpn_len);
   fprintf(stderr, "  ALPN protocol: %.*s\n", alpn_len, alpn);
+
+  // Print the server cert subject and issuer names.
+  X509 *peer = SSL_get_peer_certificate(ssl);
+  if (peer != NULL) {
+    fprintf(stderr, "  Cert subject: ");
+    X509_NAME_print_ex_fp(stderr, X509_get_subject_name(peer), 0,
+                          XN_FLAG_ONELINE);
+    fprintf(stderr, "\n  Cert issuer: ");
+    X509_NAME_print_ex_fp(stderr, X509_get_issuer_name(peer), 0,
+                          XN_FLAG_ONELINE);
+    fprintf(stderr, "\n");
+    X509_free(peer);
+  }
 }
 
 bool SocketSetNonBlocking(int sock, bool is_non_blocking) {
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 566c3f7..d361651 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -24,6 +24,7 @@
 	"path"
 	"strconv"
 	"strings"
+	"sync"
 	"syscall"
 	"time"
 )
@@ -32,8 +33,10 @@
 
 var (
 	useValgrind     = flag.Bool("valgrind", false, "If true, run code under valgrind")
+	useCallgrind    = flag.Bool("callgrind", false, "If true, run code under valgrind to generate callgrind traces.")
 	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.")
+	numWorkers      = flag.Int("num-workers", 1, "Runs the given number of workers when testing.")
 	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.")
@@ -41,6 +44,12 @@
 
 type test []string
 
+type result struct {
+	Test   test
+	Passed bool
+	Error  error
+}
+
 // testOutput is a representation of Chromium's JSON test result format. See
 // https://www.chromium.org/developers/the-json-test-results-format
 type testOutput struct {
@@ -105,6 +114,14 @@
 	return exec.Command("valgrind", valgrindArgs...)
 }
 
+func callgrindOf(path string, args ...string) *exec.Cmd {
+	valgrindArgs := []string{"-q", "--tool=callgrind", "--dump-instr=yes", "--collect-jumps=yes", "--callgrind-out-file=" + *buildDir + "/callgrind/callgrind.out.%p"}
+	valgrindArgs = append(valgrindArgs, path)
+	valgrindArgs = append(valgrindArgs, args...)
+
+	return exec.Command("valgrind", valgrindArgs...)
+}
+
 func gdbOf(path string, args ...string) *exec.Cmd {
 	xtermArgs := []string{"-e", "gdb", "--args"}
 	xtermArgs = append(xtermArgs, path)
@@ -127,6 +144,8 @@
 	var cmd *exec.Cmd
 	if *useValgrind {
 		cmd = valgrindOf(false, prog, args...)
+	} else if *useCallgrind {
+		cmd = callgrindOf(prog, args...)
 	} else if *useGDB {
 		cmd = gdbOf(prog, args...)
 	} else {
@@ -225,28 +244,55 @@
 	return result, nil
 }
 
+func worker(tests <-chan test, results chan<- result, done *sync.WaitGroup) {
+	defer done.Done()
+	for test := range tests {
+		passed, err := runTest(test)
+		results <- result{test, passed, err}
+	}
+}
+
 func main() {
 	flag.Parse()
 	setWorkingDirectory()
 
-	tests, err := parseTestConfig("util/all_tests.json")
+	testCases, err := parseTestConfig("util/all_tests.json")
 	if err != nil {
 		fmt.Printf("Failed to parse input: %s\n", err)
 		os.Exit(1)
 	}
 
+	var wg sync.WaitGroup
+	tests := make(chan test, *numWorkers)
+	results := make(chan result, *numWorkers)
+
+	for i := 0; i < *numWorkers; i++ {
+		wg.Add(1)
+		go worker(tests, results, &wg)
+	}
+
+	go func() {
+		for _, test := range testCases {
+			tests <- test
+		}
+		close(tests)
+
+		wg.Wait()
+		close(results)
+	}()
+
 	testOutput := newTestOutput()
 	var failed []test
-	for _, test := range tests {
-		fmt.Printf("%s\n", strings.Join([]string(test), " "))
+	for testResult := range results {
+		test := testResult.Test
 
+		fmt.Printf("%s\n", strings.Join([]string(test), " "))
 		name := shortTestName(test)
-		passed, err := runTest(test)
-		if err != nil {
-			fmt.Printf("%s failed to complete: %s\n", test[0], err)
+		if testResult.Error != nil {
+			fmt.Printf("%s failed to complete: %s\n", test[0], testResult.Error)
 			failed = append(failed, test)
 			testOutput.addResult(name, "CRASHED")
-		} else if !passed {
+		} else if !testResult.Passed {
 			fmt.Printf("%s failed to print PASS on the last line.\n", test[0])
 			failed = append(failed, test)
 			testOutput.addResult(name, "FAIL")
@@ -262,7 +308,7 @@
 	}
 
 	if len(failed) > 0 {
-		fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(tests))
+		fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(testCases))
 		for _, test := range failed {
 			fmt.Printf("\t%s\n", strings.Join([]string(test), " "))
 		}
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index c621799..3de0694 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -1,9 +1,11 @@
 [
 	["crypto/aes/aes_test"],
+	["crypto/asn1/asn1_test"],
 	["crypto/base64/base64_test"],
 	["crypto/bio/bio_test"],
 	["crypto/bn/bn_test"],
 	["crypto/bytestring/bytestring_test"],
+	["crypto/chacha/chacha_test"],
 	["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"],
 	["crypto/cipher/aead_test", "aes-128-key-wrap", "crypto/cipher/test/aes_128_key_wrap_tests.txt"],
 	["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
@@ -33,6 +35,7 @@
 	["crypto/constant_time_test"],
 	["crypto/curve25519/ed25519_test", "crypto/curve25519/ed25519_tests.txt"],
 	["crypto/curve25519/x25519_test"],
+	["crypto/curve25519/spake25519_test"],
 	["crypto/dh/dh_test"],
 	["crypto/digest/digest_test"],
 	["crypto/dsa/dsa_test"],
@@ -47,15 +50,19 @@
 	["crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"],
 	["crypto/lhash/lhash_test"],
 	["crypto/modes/gcm_test"],
-	["crypto/pkcs8/pkcs8_test"],
+	["crypto/newhope/newhope_test"],
+	["crypto/obj/obj_test"],
 	["crypto/pkcs8/pkcs12_test"],
+	["crypto/pkcs8/pkcs8_test"],
 	["crypto/poly1305/poly1305_test", "crypto/poly1305/poly1305_test.txt"],
 	["crypto/refcount_test"],
 	["crypto/rsa/rsa_test"],
 	["crypto/thread_test"],
 	["crypto/x509/pkcs7_test"],
+	["crypto/x509/x509_test"],
 	["crypto/x509v3/tab_test"],
 	["crypto/x509v3/v3name_test"],
+	["decrepit/ripemd/ripemd_test"],
 	["ssl/pqueue/pqueue_test"],
 	["ssl/ssl_test"]
 ]
diff --git a/src/util/bot/DEPS b/src/util/bot/DEPS
index 738fbd3..0a4de21 100644
--- a/src/util/bot/DEPS
+++ b/src/util/bot/DEPS
@@ -18,7 +18,7 @@
 
 deps = {
   'boringssl/util/bot/gyp':
-    Var('chromium_git') + '/external/gyp.git' + '@' + '4a9b712d5cb4a5ba7a9950128a7219569caf7263',
+    Var('chromium_git') + '/external/gyp.git' + '@' + '61259d585ce99d9de8b35188cd0025bdbcb58411',
 }
 
 hooks = [
diff --git a/src/util/bot/UPDATING b/src/util/bot/UPDATING
new file mode 100644
index 0000000..4e16c6d
--- /dev/null
+++ b/src/util/bot/UPDATING
@@ -0,0 +1,46 @@
+This directory consumes tools from other repositories for use on the
+bots. To update to newer revisions, follow these instructions:
+
+DEPS: Set the external/gyp.git revision to the revision used in Chromium, found at
+    https://chromium.googlesource.com/chromium/src/+/master/DEPS
+    (Search for 'gyp.git'.)
+
+go/bootstrap.py: Set TOOLSET_VERSION to the latest release of Go, found at
+    https://golang.org/dl/.
+
+update_clang.py: Set CLANG_REVISION and CLANG_SUB_REVISION to the values used in
+    Chromium, found at
+    https://chromium.googlesource.com/chromium/src/+/master/tools/clang/scripts/update.py
+
+vs_toolchain.py: Set the hash in _GetDesiredVsToolchainHashes to the toolchain
+    used in Chromium, found at
+    https://chromium.googlesource.com/chromium/src/+/master/build/vs_toolchain.py
+    This may require taking other updates to that file.
+
+The .sha1 files correspond to files downloaded from Google Cloud Storage. To
+update, place the updated files in their intended location and run:
+
+    upload_to_google_storage.py -b chromium-tools FILE
+
+cmake-linux64.tar.gz: Download the latest CMake source tarball, found at
+    https://cmake.org/download/. Build it with:
+
+        ./bootstrap --prefix=$PWD/cmake-linux64 && make && make install
+        tar -czf cmake-linux64.tar.gz cmake-linux64/
+
+cmake-mac.tar.gz: Follow the same instructions as above on a Mac, but replace
+    cmake-linux64 with cmake-mac.
+
+cmake-win32.zip: Update to the latest prebuilt release of CMake, found at
+    https://cmake.org/download/. Use the file labeled "Windows ZIP". The
+    download will be named cmake-VERSION-win32-x86.zip.
+
+perl-win32.zip: Update to the latest 32-bit prebuilt "PortableZip" edition of
+    Strawberry Perl, found at http://strawberryperl.com/releases.html. The
+    download will be named strawberry-perl-VERSION-32bit-portable.zip.
+
+yasm-win32.exe: Update to the appropriate release of Yasm. Use the same version
+    as Chromium, found at
+    https://chromium.googlesource.com/chromium/src/+/master/third_party/yasm/README.chromium
+    Use the release at http://yasm.tortall.net/Download.html labeled
+    "Win32 .exe". The download will be named yasm-VERSION-win32.exe.
diff --git a/src/util/bot/cmake-linux64.tar.gz.sha1 b/src/util/bot/cmake-linux64.tar.gz.sha1
index 6a8aa1c..404570f 100644
--- a/src/util/bot/cmake-linux64.tar.gz.sha1
+++ b/src/util/bot/cmake-linux64.tar.gz.sha1
@@ -1 +1 @@
-32cd1d5fe84ae569dbb36f5767650d62efb8be38
\ No newline at end of file
+6ea4ad07a4bab113ea74c45fafb14b8d0b0feab5
\ No newline at end of file
diff --git a/src/util/bot/cmake-mac.tar.gz.sha1 b/src/util/bot/cmake-mac.tar.gz.sha1
index cb7251b..19c9b61 100644
--- a/src/util/bot/cmake-mac.tar.gz.sha1
+++ b/src/util/bot/cmake-mac.tar.gz.sha1
@@ -1 +1 @@
-310df6945ae7f8c9da559d22f5794ee8e578a663
\ No newline at end of file
+f3166dab96234c9516ece56dc2851bf4c8e70fe8
\ No newline at end of file
diff --git a/src/util/bot/cmake-win32.zip.sha1 b/src/util/bot/cmake-win32.zip.sha1
index 9196b58..6bb460e 100644
--- a/src/util/bot/cmake-win32.zip.sha1
+++ b/src/util/bot/cmake-win32.zip.sha1
@@ -1 +1 @@
-e9493171de0edd8879755aa7229a701010a19561
\ No newline at end of file
+ed4e1939d246374b0bae724a1a4200fd60e7efe8
\ No newline at end of file
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 4a52d9e..28aa13d 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,7 +45,7 @@
 EXE_SFX = '.exe' if sys.platform == 'win32' else ''
 
 # Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.5.1'
+TOOLSET_VERSION = 'go1.6'
 
 # Platform dependent portion of a download URL. See http://golang.org/dl/.
 TOOLSET_VARIANTS = {
diff --git a/src/util/bot/perl-win32.zip.sha1 b/src/util/bot/perl-win32.zip.sha1
index a5559d8..8874fbb 100644
--- a/src/util/bot/perl-win32.zip.sha1
+++ b/src/util/bot/perl-win32.zip.sha1
@@ -1 +1 @@
-ab6e7aee6a915c4d820b86f5227094763b649fce
\ No newline at end of file
+3db2b4964d56f6e23cc48ced40a6cee05419a0af
\ No newline at end of file
diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py
index 1824393..48d0d9b 100644
--- a/src/util/bot/update_clang.py
+++ b/src/util/bot/update_clang.py
@@ -22,7 +22,7 @@
 # CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
 # to use. These should be synced with tools/clang/scripts/update.py in
 # Chromium.
-CLANG_REVISION = "233105"
+CLANG_REVISION = "261368"
 CLANG_SUB_REVISION = "1"
 
 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py
index 2a54b9e..175502e 100644
--- a/src/util/bot/vs_toolchain.py
+++ b/src/util/bot/vs_toolchain.py
@@ -65,7 +65,7 @@
   """Load a list of SHA1s corresponding to the toolchains that we want installed
   to build with."""
   # Use Chromium's VS2013.
-  return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
+  return ['4087e065abebdca6dbd0caca2910c6718d2ec67f']
 
 
 def FindDepotTools():
diff --git a/src/util/doc.config b/src/util/doc.config
index cbee543..e7cfa82 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -33,8 +33,10 @@
       "include/openssl/ecdh.h",
       "include/openssl/ecdsa.h",
       "include/openssl/engine.h",
+      "include/openssl/hkdf.h",
       "include/openssl/hmac.h",
       "include/openssl/md5.h",
+      "include/openssl/newhope.h",
       "include/openssl/rc4.h",
       "include/openssl/rsa.h",
       "include/openssl/sha.h"
diff --git a/src/util/doc.go b/src/util/doc.go
index 7d15d9b..ace7a58 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -203,15 +203,28 @@
 	for strings.HasPrefix(decl, "#if") || strings.HasPrefix(decl, "#elif") {
 		decl = skipLine(decl)
 	}
-	if strings.HasPrefix(decl, "struct ") {
+
+	if strings.HasPrefix(decl, "typedef ") {
 		return "", false
 	}
-	if strings.HasPrefix(decl, "#define ") {
-		// This is a preprocessor #define. The name is the next symbol.
-		decl = strings.TrimPrefix(decl, "#define ")
+
+	for _, prefix := range []string{"struct ", "enum ", "#define "} {
+		if !strings.HasPrefix(decl, prefix) {
+			continue
+		}
+
+		decl = strings.TrimPrefix(decl, prefix)
+
 		for len(decl) > 0 && decl[0] == ' ' {
 			decl = decl[1:]
 		}
+
+		// struct and enum types can be the return type of a
+		// function.
+		if prefix[0] != '#' && strings.Index(decl, "{") == -1 {
+			break
+		}
+
 		i := strings.IndexAny(decl, "( ")
 		if i < 0 {
 			return "", false
diff --git a/src/util/generate-asm-lcov.py b/src/util/generate-asm-lcov.py
new file mode 100755
index 0000000..257ae84
--- /dev/null
+++ b/src/util/generate-asm-lcov.py
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+# Copyright (c) 2016, Google Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import os
+import os.path
+import subprocess
+import sys
+
+# The LCOV output format for each source file is:
+#
+# SF:<filename>
+# DA:<line>,<execution count>
+# ...
+# end_of_record
+#
+# The <execution count> can either be 0 for an unexecuted instruction or a
+# value representing the number of executions. The DA line should be omitted
+# for lines not representing an instruction.
+
+SECTION_SEPERATOR = '-' * 80
+
+def is_asm(l):
+  """Returns whether a line should be considered to be an instruction."""
+  l = l.strip()
+  # Empty lines
+  if l == '':
+    return False
+  # Comments
+  if l.startswith('#'):
+    return False
+  # Assembly Macros
+  if l.startswith('.'):
+    return False
+  # Label
+  if l.endswith(':'):
+    return False
+  return True
+
+def merge(callgrind_files, srcs):
+  """Calls callgrind_annotate over the set of callgrind output
+  |callgrind_files| using the sources |srcs| and merges the results
+  together."""
+  out = ''
+  for file in callgrind_files:
+    data = subprocess.check_output(['callgrind_annotate', file] + srcs)
+    out += '%s\n%s\n' % (data, SECTION_SEPERATOR)
+  return out
+
+def parse(filename, data, current):
+  """Parses an annotated execution flow |data| from callgrind_annotate for
+  source |filename| and updates the current execution counts from |current|."""
+  with open(filename) as f:
+    source = f.read().split('\n')
+
+  out = current
+  if out == None:
+    out = [0 if is_asm(l) else None for l in source]
+
+  # Lines are of the following formats:
+  #   -- line: Indicates that analysis continues from a different place.
+  #   Ir     : Indicates the start of a file.
+  #   =>     : Indicates a call/jump in the control flow.
+  #   <Count> <Code>: Indicates that the line has been executed that many times.
+  line = None
+  for l in data:
+    l = l.strip() + ' '
+    if l.startswith('-- line'):
+      line = int(l.split(' ')[2]) - 1
+    elif l.strip() == 'Ir':
+      line = 0
+    elif line != None and l.strip() and '=>' not in l and 'unidentified lines' not in l:
+      count = l.split(' ')[0].replace(',', '').replace('.', '0')
+      instruction = l.split(' ', 1)[1].strip()
+      if count != '0' or is_asm(instruction):
+        if out[line] == None:
+          out[line] = 0
+        out[line] += int(count)
+      line += 1
+
+  return out
+
+
+def generate(data):
+  """Parses the merged callgrind_annotate output |data| and generates execution
+  counts for all annotated files."""
+  out = {}
+  data = [p.strip() for p in data.split(SECTION_SEPERATOR)]
+
+
+  # Most sections are ignored, but a section with:
+  #  User-annotated source: <file>
+  # precedes a listing of execution count for that <file>.
+  for i in range(len(data)):
+    if 'User-annotated source' in data[i] and i < len(data) - 1:
+      filename = data[i].split(':', 1)[1].strip()
+      res = data[i + 1]
+      if filename not in out:
+        out[filename] = None
+      if 'No information' in res:
+        res = []
+      else:
+        res = res.split('\n')
+      out[filename] = parse(filename, res, out[filename])
+  return out
+
+def output(data):
+  """Takes a dictionary |data| of filenames and execution counts and generates
+  a LCOV coverage output."""
+  out = ''
+  for filename, counts in data.iteritems():
+    out += 'SF:%s\n' % (os.path.abspath(filename))
+    for line, count in enumerate(counts):
+      if count != None:
+        out += 'DA:%d,%s\n' % (line + 1, count)
+    out += 'end_of_record\n'
+  return out
+
+if __name__ == '__main__':
+  if len(sys.argv) != 3:
+    print '%s <Callgrind Folder> <Build Folder>' % (__file__)
+    sys.exit()
+
+  cg_folder = sys.argv[1]
+  build_folder = sys.argv[2]
+
+  cg_files = []
+  for (cwd, _, files) in os.walk(cg_folder):
+    for f in files:
+      if f.startswith('callgrind.out'):
+        cg_files.append(os.path.abspath(os.path.join(cwd, f)))
+
+  srcs = []
+  for (cwd, _, files) in os.walk(build_folder):
+    for f in files:
+      fn = os.path.join(cwd, f)
+      if fn.endswith('.S'):
+        srcs.append(fn)
+
+  annotated = merge(cg_files, srcs)
+  lcov = generate(annotated)
+  print output(lcov)
diff --git a/src/util/generate-coverage.sh b/src/util/generate-coverage.sh
new file mode 100755
index 0000000..2fbe6b8
--- /dev/null
+++ b/src/util/generate-coverage.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Copyright (c) 2016, Google Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+set -xe
+
+SRC=$PWD
+
+BUILD=$(mktemp -d '/tmp/boringssl.XXXXXX')
+BUILD_SRC=$(mktemp -d '/tmp/boringssl-src.XXXXXX')
+LCOV=$(mktemp -d '/tmp/boringssl-lcov.XXXXXX')
+
+if [ -n "$1" ]; then
+  LCOV=$(readlink -f "$1")
+  mkdir -p "$LCOV"
+fi
+
+cd "$BUILD"
+cmake "$SRC" -GNinja -DCMAKE_C_FLAGS='-fprofile-arcs -ftest-coverage' \
+  -DCMAKE_CXX_FLAGS='-fprofile-arcs -ftest-coverage' -DCMAKE_ASM_FLAGS='-Wa,-g'
+ninja
+
+cp -r "$SRC/crypto" "$SRC/decrepit" "$SRC/include" "$SRC/ssl" "$SRC/tool" \
+  "$BUILD_SRC"
+cp -r "$BUILD"/* "$BUILD_SRC"
+mkdir "$BUILD/callgrind/"
+
+cd "$SRC"
+go run "$SRC/util/all_tests.go" -build-dir "$BUILD" -callgrind -num-workers 16
+util/generate-asm-lcov.py "$BUILD/callgrind" "$BUILD" > "$BUILD/asm.info"
+
+go run "util/all_tests.go" -build-dir "$BUILD"
+
+cd "$SRC/ssl/test/runner"
+go test -shim-path "$BUILD/ssl/test/bssl_shim" -num-workers 1
+
+cd "$LCOV"
+lcov -c -d "$BUILD" -b "$BUILD" -o "$BUILD/lcov.info"
+lcov -r "$BUILD/lcov.info" "*_test.c" -o "$BUILD/lcov-1.info"
+lcov -r "$BUILD/lcov-1.info" "*_test.cc" -o "$BUILD/lcov-2.info"
+cat "$BUILD/lcov-2.info" "$BUILD/asm.info" > "$BUILD/final.info"
+sed -i "s;$BUILD;$BUILD_SRC;g" "$BUILD/final.info"
+sed -i "s;$SRC;$BUILD_SRC;g" "$BUILD/final.info"
+genhtml -p "$BUILD_SRC" "$BUILD/final.info"
+
+rm -rf "$BUILD"
+rm -rf "$BUILD_SRC"
+
+xdg-open index.html
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 6321c5c..a3721fe 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -39,84 +39,15 @@
 # perlasm system.
 NON_PERL_FILES = {
     ('linux', 'arm'): [
-        'src/crypto/chacha/chacha_vec_arm.S',
-        'src/crypto/cpu-arm-asm.S',
         'src/crypto/curve25519/asm/x25519-asm-arm.S',
         'src/crypto/poly1305/poly1305_arm_asm.S',
     ],
+    ('linux', 'x86_64'): [
+        'src/crypto/curve25519/asm/x25519-asm-x86_64.S',
+    ],
 }
 
 
-class Chromium(object):
-
-  def __init__(self):
-    self.header = \
-"""# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is created by generate_build_files.py. Do not edit manually.
-
-"""
-
-  def PrintVariableSection(self, out, name, files):
-    out.write('    \'%s\': [\n' % name)
-    for f in sorted(files):
-      out.write('      \'%s\',\n' % f)
-    out.write('    ],\n')
-
-  def WriteFiles(self, files, asm_outputs):
-    with open('boringssl.gypi', 'w+') as gypi:
-      gypi.write(self.header + '{\n  \'variables\': {\n')
-
-      self.PrintVariableSection(
-          gypi, 'boringssl_ssl_sources', files['ssl'])
-      self.PrintVariableSection(
-          gypi, 'boringssl_crypto_sources', files['crypto'])
-
-      for ((osname, arch), asm_files) in asm_outputs:
-        self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' %
-                                  (osname, arch), asm_files)
-
-      gypi.write('  }\n}\n')
-
-    with open('boringssl_tests.gypi', 'w+') as test_gypi:
-      test_gypi.write(self.header + '{\n  \'targets\': [\n')
-
-      test_names = []
-      for test in sorted(files['test']):
-        test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
-        test_gypi.write("""    {
-      'target_name': '%s',
-      'type': 'executable',
-      'dependencies': [
-        'boringssl.gyp:boringssl',
-      ],
-      'sources': [
-        '%s',
-        '<@(boringssl_test_support_sources)',
-      ],
-      # TODO(davidben): Fix size_t truncations in BoringSSL.
-      # https://crbug.com/429039
-      'msvs_disabled_warnings': [ 4267, ],
-    },\n""" % (test_name, test))
-        test_names.append(test_name)
-
-      test_names.sort()
-
-      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)
-
-      test_gypi.write('    ],\n  }\n}\n')
-
-
 class Android(object):
 
   def __init__(self):
@@ -283,6 +214,151 @@
         out.write('  )\n')
 
 
+class GN(object):
+
+  def __init__(self):
+    self.firstSection = True
+    self.header = \
+"""# Copyright (c) 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file is created by generate_build_files.py. Do not edit manually.
+
+"""
+
+  def PrintVariableSection(self, out, name, files):
+    if not self.firstSection:
+      out.write('\n')
+    self.firstSection = False
+
+    out.write('%s = [\n' % name)
+    for f in sorted(files):
+      out.write('  "%s",\n' % f)
+    out.write(']\n')
+
+  def WriteFiles(self, files, asm_outputs):
+    with open('BUILD.generated.gni', 'w+') as out:
+      out.write(self.header)
+
+      self.PrintVariableSection(out, 'crypto_sources', files['crypto'])
+      self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
+
+      for ((osname, arch), asm_files) in asm_outputs:
+        self.PrintVariableSection(
+            out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
+
+      fuzzers = [os.path.splitext(os.path.basename(fuzzer))[0]
+                 for fuzzer in files['fuzz']]
+      self.PrintVariableSection(out, 'fuzzers', fuzzers)
+
+    with open('BUILD.generated_tests.gni', 'w+') as out:
+      self.firstSection = True
+      out.write(self.header)
+
+      self.PrintVariableSection(out, '_test_support_sources',
+                                files['test_support'])
+      out.write('\n')
+
+      out.write('template("create_tests") {\n')
+
+      all_tests = []
+      for test in sorted(files['test']):
+        test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
+        all_tests.append(test_name)
+
+        out.write('  executable("%s") {\n' % test_name)
+        out.write('    sources = [\n')
+        out.write('      "%s",\n' % test)
+        out.write('    ]\n')
+        out.write('    sources += _test_support_sources\n')
+        out.write('    if (defined(invoker.configs_exclude)) {\n')
+        out.write('      configs -= invoker.configs_exclude\n')
+        out.write('    }\n')
+        out.write('    configs += invoker.configs\n')
+        out.write('    deps = invoker.deps\n')
+        out.write('  }\n')
+        out.write('\n')
+
+      out.write('  group(target_name) {\n')
+      out.write('    deps = [\n')
+      for test_name in sorted(all_tests):
+        out.write('      ":%s",\n' % test_name)
+      out.write('    ]\n')
+      out.write('  }\n')
+      out.write('}\n')
+
+
+class GYP(object):
+
+  def __init__(self):
+    self.header = \
+"""# Copyright (c) 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file is created by generate_build_files.py. Do not edit manually.
+
+"""
+
+  def PrintVariableSection(self, out, name, files):
+    out.write('    \'%s\': [\n' % name)
+    for f in sorted(files):
+      out.write('      \'%s\',\n' % f)
+    out.write('    ],\n')
+
+  def WriteFiles(self, files, asm_outputs):
+    with open('boringssl.gypi', 'w+') as gypi:
+      gypi.write(self.header + '{\n  \'variables\': {\n')
+
+      self.PrintVariableSection(
+          gypi, 'boringssl_ssl_sources', files['ssl'])
+      self.PrintVariableSection(
+          gypi, 'boringssl_crypto_sources', files['crypto'])
+
+      for ((osname, arch), asm_files) in asm_outputs:
+        self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' %
+                                  (osname, arch), asm_files)
+
+      gypi.write('  }\n}\n')
+
+    with open('boringssl_tests.gypi', 'w+') as test_gypi:
+      test_gypi.write(self.header + '{\n  \'targets\': [\n')
+
+      test_names = []
+      for test in sorted(files['test']):
+        test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
+        test_gypi.write("""    {
+      'target_name': '%s',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        '%s',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },\n""" % (test_name, test))
+        test_names.append(test_name)
+
+      test_names.sort()
+
+      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 sorted(test_names):
+        test_gypi.write("""      '%s',\n""" % test)
+
+      test_gypi.write('    ],\n  }\n}\n')
+
+
 def FindCMakeFiles(directory):
   """Returns list of all CMakeLists.txt files recursively in directory."""
   cmakefiles = []
@@ -456,7 +532,7 @@
 def main(platforms):
   crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTests)
   ssl_c_files = FindCFiles(os.path.join('src', 'ssl'), NoTests)
-  tool_cc_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
+  tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
 
   # Generate err_data.c
   with open('err_data.c', 'w+') as err_data:
@@ -465,12 +541,14 @@
                           stdout=err_data)
   crypto_c_files.append('err_data.c')
 
-  test_support_cc_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
-                                     AllFiles)
+  test_support_c_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)
 
+  fuzz_c_files = FindCFiles(os.path.join('src', 'fuzz'), NoTests)
+
   ssl_h_files = (
       FindHeaderFiles(
           os.path.join('src', 'include', 'openssl'),
@@ -489,6 +567,8 @@
 
   with open('src/util/all_tests.json', 'r') as f:
     tests = json.load(f)
+  # Skip tests for libdecrepit. Consumers import that manually.
+  tests = [test for test in tests if not test[0].startswith("decrepit/")]
   test_binaries = set([test[0] for test in tests])
   test_sources = set([
       test.replace('.cc', '').replace('.c', '').replace(
@@ -508,12 +588,13 @@
       'crypto': crypto_c_files,
       'crypto_headers': crypto_h_files,
       'crypto_internal_headers': crypto_internal_h_files,
+      'fuzz': fuzz_c_files,
       'ssl': ssl_c_files,
       'ssl_headers': ssl_h_files,
       'ssl_internal_headers': ssl_internal_h_files,
-      'tool': tool_cc_files,
+      'tool': tool_c_files,
       'test': test_c_files,
-      'test_support': test_support_cc_files,
+      'test_support': test_support_c_files,
       'tests': tests,
   }
 
@@ -526,7 +607,7 @@
 
 
 def Usage():
-  print 'Usage: python %s [chromium|android|android-standalone|bazel]' % sys.argv[0]
+  print 'Usage: python %s [android|android-standalone|bazel|gn|gyp]' % sys.argv[0]
   sys.exit(1)
 
 
@@ -536,14 +617,16 @@
 
   platforms = []
   for s in sys.argv[1:]:
-    if s == 'chromium' or s == 'gyp':
-      platforms.append(Chromium())
-    elif s == 'android':
+    if s == 'android':
       platforms.append(Android())
     elif s == 'android-standalone':
       platforms.append(AndroidStandalone())
     elif s == 'bazel':
       platforms.append(Bazel())
+    elif s == 'gn':
+      platforms.append(GN())
+    elif s == 'gyp':
+      platforms.append(GYP())
     else:
       Usage()
 
diff --git a/src/util/run_android_tests.go b/src/util/run_android_tests.go
new file mode 100644
index 0000000..b0a388f
--- /dev/null
+++ b/src/util/run_android_tests.go
@@ -0,0 +1,211 @@
+// Copyright (c) 2016, Google Inc.
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+package main
+
+import (
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+var (
+	buildDir     = flag.String("build-dir", "build", "Specifies the build directory to push.")
+	device       = flag.String("device", "", "Specifies the device or emulator. See adb's -s argument.")
+	aarch64      = flag.Bool("aarch64", false, "Build the test runners for aarch64 instead of arm.")
+	arm          = flag.Int("arm", 7, "Which arm revision to build for.")
+	allTestsArgs = flag.String("all-tests-args", "", "Specifies space-separated arguments to pass to all_tests.go")
+	runnerArgs   = flag.String("runner-args", "", "Specifies space-separated arguments to pass to ssl/test/runner")
+)
+
+func adb(args ...string) error {
+	if len(*device) > 0 {
+		args = append([]string{"-s", *device}, args...)
+	}
+	cmd := exec.Command("adb", args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	return cmd.Run()
+}
+
+func goTool(args ...string) error {
+	cmd := exec.Command("go", args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+
+	if *aarch64 {
+		cmd.Env = append(cmd.Env, "GOARCH=arm64")
+	} else {
+		cmd.Env = append(cmd.Env, "GOARCH=arm")
+		cmd.Env = append(cmd.Env, fmt.Sprintf("GOARM=%d", *arm))
+	}
+	return cmd.Run()
+}
+
+// setWorkingDirectory walks up directories as needed until the current working
+// directory is the top of a BoringSSL checkout.
+func setWorkingDirectory() {
+	for i := 0; i < 64; i++ {
+		if _, err := os.Stat("BUILDING.md"); err == nil {
+			return
+		}
+		os.Chdir("..")
+	}
+
+	panic("Couldn't find BUILDING.md in a parent directory!")
+}
+
+type test []string
+
+func parseTestConfig(filename string) ([]test, error) {
+	in, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer in.Close()
+
+	decoder := json.NewDecoder(in)
+	var result []test
+	if err := decoder.Decode(&result); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+func copyFile(dst, src string) error {
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer srcFile.Close()
+
+	srcInfo, err := srcFile.Stat()
+	if err != nil {
+		return err
+	}
+
+	dir := filepath.Dir(dst)
+	if err := os.MkdirAll(dir, 0777); err != nil {
+		return err
+	}
+
+	dstFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, srcInfo.Mode())
+	if err != nil {
+		return err
+	}
+	defer dstFile.Close()
+
+	_, err = io.Copy(dstFile, srcFile)
+	return err
+}
+
+func main() {
+	flag.Parse()
+	setWorkingDirectory()
+
+	tests, err := parseTestConfig("util/all_tests.json")
+	if err != nil {
+		fmt.Printf("Failed to parse input: %s\n", err)
+		os.Exit(1)
+	}
+
+	// Clear the target directory.
+	if err := adb("shell", "rm -Rf /data/local/tmp/boringssl-tmp"); err != nil {
+		fmt.Printf("Failed to clear target directory: %s\n", err)
+		os.Exit(1)
+	}
+
+	// Stage everything in a temporary directory.
+	tmpDir, err := ioutil.TempDir("", "boringssl-android")
+	if err != nil {
+		fmt.Printf("Error making temporary directory: %s\n", err)
+		os.Exit(1)
+	}
+	defer os.RemoveAll(tmpDir)
+
+	seenBinary := make(map[string]struct{})
+	binaries := []string{"ssl/test/bssl_shim"}
+	files := []string{
+		"BUILDING.md",
+		"util/all_tests.json",
+		"ssl/test/runner/cert.pem",
+		"ssl/test/runner/channel_id_key.pem",
+		"ssl/test/runner/ecdsa_cert.pem",
+		"ssl/test/runner/ecdsa_key.pem",
+		"ssl/test/runner/key.pem",
+	}
+	for _, test := range tests {
+		if _, ok := seenBinary[test[0]]; !ok {
+			binaries = append(binaries, test[0])
+			seenBinary[test[0]] = struct{}{}
+		}
+		for _, arg := range test[1:] {
+			if strings.Contains(arg, "/") {
+				files = append(files, arg)
+			}
+		}
+	}
+
+	fmt.Printf("Copying test binaries...\n")
+	for _, binary := range binaries {
+		if err := copyFile(filepath.Join(tmpDir, "build", binary), filepath.Join(*buildDir, binary)); err != nil {
+			fmt.Printf("Failed to copy %s: %s\n", binary, err)
+			os.Exit(1)
+		}
+	}
+
+	fmt.Printf("Copying data files...\n")
+	for _, file := range files {
+		if err := copyFile(filepath.Join(tmpDir, file), file); err != nil {
+			fmt.Printf("Failed to copy %s: %s\n", file, err)
+			os.Exit(1)
+		}
+	}
+
+	fmt.Printf("Building all_tests...\n")
+	if err := goTool("build", "-o", filepath.Join(tmpDir, "util/all_tests"), "util/all_tests.go"); err != nil {
+		fmt.Printf("Error building all_tests.go: %s\n", err)
+		os.Exit(1)
+	}
+
+	fmt.Printf("Building runner...\n")
+	if err := goTool("test", "-c", "-o", filepath.Join(tmpDir, "ssl/test/runner/runner"), "./ssl/test/runner/"); err != nil {
+		fmt.Printf("Error building runner: %s\n", err)
+		os.Exit(1)
+	}
+
+	fmt.Printf("Uploading files...\n")
+	if err := adb("push", "-p", tmpDir, "/data/local/tmp/boringssl-tmp"); err != nil {
+		fmt.Printf("Failed to push runner: %s\n", err)
+		os.Exit(1)
+	}
+
+	fmt.Printf("Running unit tests...\n")
+	if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp && ./util/all_tests %s", *allTestsArgs)); err != nil {
+		fmt.Printf("Failed to run unit tests: %s\n", err)
+		os.Exit(1)
+	}
+
+	fmt.Printf("Running SSL tests...\n")
+	if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp/ssl/test/runner && ./runner %s", *runnerArgs)); err != nil {
+		fmt.Printf("Failed to run SSL tests: %s\n", err)
+		os.Exit(1)
+	}
+}
diff --git a/win-x86/crypto/chacha/chacha-x86.asm b/win-x86/crypto/chacha/chacha-x86.asm
new file mode 100644
index 0000000..283c8e4
--- /dev/null
+++ b/win-x86/crypto/chacha/chacha-x86.asm
@@ -0,0 +1,997 @@
+%ifidn __OUTPUT_FORMAT__,obj
+section	code	use32 class=code align=64
+%elifidn __OUTPUT_FORMAT__,win32
+%ifdef __YASM_VERSION_ID__
+%if __YASM_VERSION_ID__ < 01010000h
+%error yasm version 1.1.0 or later needed.
+%endif
+; Yasm automatically includes .00 and complains about redefining it.
+; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
+%else
+$@feat.00 equ 1
+%endif
+section	.text	code align=64
+%else
+section	.text	code
+%endif
+global	_ChaCha20_ctr32
+align	16
+_ChaCha20_ctr32:
+L$_ChaCha20_ctr32_begin:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+	xor	eax,eax
+	cmp	eax,DWORD [28+esp]
+	je	NEAR L$000no_data
+	call	L$pic_point
+L$pic_point:
+	pop	eax
+	lea	ebp,[_OPENSSL_ia32cap_P]
+	test	DWORD [ebp],16777216
+	jz	NEAR L$001x86
+	test	DWORD [4+ebp],512
+	jz	NEAR L$001x86
+	jmp	NEAR L$ssse3_shortcut
+L$001x86:
+	mov	esi,DWORD [32+esp]
+	mov	edi,DWORD [36+esp]
+	sub	esp,132
+	mov	eax,DWORD [esi]
+	mov	ebx,DWORD [4+esi]
+	mov	ecx,DWORD [8+esi]
+	mov	edx,DWORD [12+esi]
+	mov	DWORD [80+esp],eax
+	mov	DWORD [84+esp],ebx
+	mov	DWORD [88+esp],ecx
+	mov	DWORD [92+esp],edx
+	mov	eax,DWORD [16+esi]
+	mov	ebx,DWORD [20+esi]
+	mov	ecx,DWORD [24+esi]
+	mov	edx,DWORD [28+esi]
+	mov	DWORD [96+esp],eax
+	mov	DWORD [100+esp],ebx
+	mov	DWORD [104+esp],ecx
+	mov	DWORD [108+esp],edx
+	mov	eax,DWORD [edi]
+	mov	ebx,DWORD [4+edi]
+	mov	ecx,DWORD [8+edi]
+	mov	edx,DWORD [12+edi]
+	sub	eax,1
+	mov	DWORD [112+esp],eax
+	mov	DWORD [116+esp],ebx
+	mov	DWORD [120+esp],ecx
+	mov	DWORD [124+esp],edx
+	jmp	NEAR L$002entry
+align	16
+L$003outer_loop:
+	mov	DWORD [156+esp],ebx
+	mov	DWORD [152+esp],eax
+	mov	DWORD [160+esp],ecx
+L$002entry:
+	mov	eax,1634760805
+	mov	DWORD [4+esp],857760878
+	mov	DWORD [8+esp],2036477234
+	mov	DWORD [12+esp],1797285236
+	mov	ebx,DWORD [84+esp]
+	mov	ebp,DWORD [88+esp]
+	mov	ecx,DWORD [104+esp]
+	mov	esi,DWORD [108+esp]
+	mov	edx,DWORD [116+esp]
+	mov	edi,DWORD [120+esp]
+	mov	DWORD [20+esp],ebx
+	mov	DWORD [24+esp],ebp
+	mov	DWORD [40+esp],ecx
+	mov	DWORD [44+esp],esi
+	mov	DWORD [52+esp],edx
+	mov	DWORD [56+esp],edi
+	mov	ebx,DWORD [92+esp]
+	mov	edi,DWORD [124+esp]
+	mov	edx,DWORD [112+esp]
+	mov	ebp,DWORD [80+esp]
+	mov	ecx,DWORD [96+esp]
+	mov	esi,DWORD [100+esp]
+	add	edx,1
+	mov	DWORD [28+esp],ebx
+	mov	DWORD [60+esp],edi
+	mov	DWORD [112+esp],edx
+	mov	ebx,10
+	jmp	NEAR L$004loop
+align	16
+L$004loop:
+	add	eax,ebp
+	mov	DWORD [128+esp],ebx
+	mov	ebx,ebp
+	xor	edx,eax
+	rol	edx,16
+	add	ecx,edx
+	xor	ebx,ecx
+	mov	edi,DWORD [52+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [20+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [esp],eax
+	rol	edx,8
+	mov	eax,DWORD [4+esp]
+	add	ecx,edx
+	mov	DWORD [48+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	mov	DWORD [32+esp],ecx
+	rol	edi,16
+	mov	DWORD [16+esp],ebx
+	add	esi,edi
+	mov	ecx,DWORD [40+esp]
+	xor	ebp,esi
+	mov	edx,DWORD [56+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [24+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [4+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [8+esp]
+	add	esi,edi
+	mov	DWORD [52+esp],edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	mov	DWORD [36+esp],esi
+	rol	edx,16
+	mov	DWORD [20+esp],ebp
+	add	ecx,edx
+	mov	esi,DWORD [44+esp]
+	xor	ebx,ecx
+	mov	edi,DWORD [60+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [28+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [8+esp],eax
+	rol	edx,8
+	mov	eax,DWORD [12+esp]
+	add	ecx,edx
+	mov	DWORD [56+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	rol	edi,16
+	mov	DWORD [24+esp],ebx
+	add	esi,edi
+	xor	ebp,esi
+	rol	ebp,12
+	mov	ebx,DWORD [20+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [12+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [esp]
+	add	esi,edi
+	mov	edx,edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	rol	edx,16
+	mov	DWORD [28+esp],ebp
+	add	ecx,edx
+	xor	ebx,ecx
+	mov	edi,DWORD [48+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [24+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [esp],eax
+	rol	edx,8
+	mov	eax,DWORD [4+esp]
+	add	ecx,edx
+	mov	DWORD [60+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	mov	DWORD [40+esp],ecx
+	rol	edi,16
+	mov	DWORD [20+esp],ebx
+	add	esi,edi
+	mov	ecx,DWORD [32+esp]
+	xor	ebp,esi
+	mov	edx,DWORD [52+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [28+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [4+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [8+esp]
+	add	esi,edi
+	mov	DWORD [48+esp],edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	mov	DWORD [44+esp],esi
+	rol	edx,16
+	mov	DWORD [24+esp],ebp
+	add	ecx,edx
+	mov	esi,DWORD [36+esp]
+	xor	ebx,ecx
+	mov	edi,DWORD [56+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [16+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [8+esp],eax
+	rol	edx,8
+	mov	eax,DWORD [12+esp]
+	add	ecx,edx
+	mov	DWORD [52+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	rol	edi,16
+	mov	DWORD [28+esp],ebx
+	add	esi,edi
+	xor	ebp,esi
+	mov	edx,DWORD [48+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [128+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [12+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [esp]
+	add	esi,edi
+	mov	DWORD [56+esp],edi
+	xor	ebp,esi
+	rol	ebp,7
+	dec	ebx
+	jnz	NEAR L$004loop
+	mov	ebx,DWORD [160+esp]
+	add	eax,1634760805
+	add	ebp,DWORD [80+esp]
+	add	ecx,DWORD [96+esp]
+	add	esi,DWORD [100+esp]
+	cmp	ebx,64
+	jb	NEAR L$005tail
+	mov	ebx,DWORD [156+esp]
+	add	edx,DWORD [112+esp]
+	add	edi,DWORD [120+esp]
+	xor	eax,DWORD [ebx]
+	xor	ebp,DWORD [16+ebx]
+	mov	DWORD [esp],eax
+	mov	eax,DWORD [152+esp]
+	xor	ecx,DWORD [32+ebx]
+	xor	esi,DWORD [36+ebx]
+	xor	edx,DWORD [48+ebx]
+	xor	edi,DWORD [56+ebx]
+	mov	DWORD [16+esp],ebp
+	mov	ebp,DWORD [esp]
+	mov	DWORD [32+esp],ecx
+	mov	DWORD [36+esp],esi
+	mov	DWORD [48+esp],edx
+	mov	DWORD [56+esp],edi
+	mov	DWORD [eax],ebp
+	mov	ebp,DWORD [4+esp]
+	mov	ecx,DWORD [8+esp]
+	mov	esi,DWORD [12+esp]
+	mov	edx,DWORD [20+esp]
+	mov	edi,DWORD [24+esp]
+	add	ebp,857760878
+	add	ecx,2036477234
+	add	esi,1797285236
+	add	edx,DWORD [84+esp]
+	add	edi,DWORD [88+esp]
+	xor	ebp,DWORD [4+ebx]
+	xor	ecx,DWORD [8+ebx]
+	xor	esi,DWORD [12+ebx]
+	xor	edx,DWORD [20+ebx]
+	xor	edi,DWORD [24+ebx]
+	mov	DWORD [4+eax],ebp
+	mov	ebp,DWORD [16+esp]
+	mov	DWORD [8+eax],ecx
+	mov	DWORD [12+eax],esi
+	mov	DWORD [16+eax],ebp
+	mov	DWORD [20+eax],edx
+	mov	DWORD [24+eax],edi
+	mov	ecx,DWORD [28+esp]
+	mov	edx,DWORD [32+esp]
+	mov	edi,DWORD [36+esp]
+	add	ecx,DWORD [92+esp]
+	mov	ebp,DWORD [40+esp]
+	xor	ecx,DWORD [28+ebx]
+	mov	esi,DWORD [44+esp]
+	mov	DWORD [28+eax],ecx
+	mov	DWORD [32+eax],edx
+	mov	DWORD [36+eax],edi
+	add	ebp,DWORD [104+esp]
+	add	esi,DWORD [108+esp]
+	xor	ebp,DWORD [40+ebx]
+	xor	esi,DWORD [44+ebx]
+	mov	DWORD [40+eax],ebp
+	mov	DWORD [44+eax],esi
+	mov	ecx,DWORD [48+esp]
+	mov	esi,DWORD [56+esp]
+	mov	edx,DWORD [52+esp]
+	mov	edi,DWORD [60+esp]
+	add	edx,DWORD [116+esp]
+	add	edi,DWORD [124+esp]
+	xor	edx,DWORD [52+ebx]
+	xor	edi,DWORD [60+ebx]
+	lea	ebx,[64+ebx]
+	mov	DWORD [48+eax],ecx
+	mov	ecx,DWORD [160+esp]
+	mov	DWORD [52+eax],edx
+	mov	DWORD [56+eax],esi
+	mov	DWORD [60+eax],edi
+	lea	eax,[64+eax]
+	sub	ecx,64
+	jnz	NEAR L$003outer_loop
+	jmp	NEAR L$006done
+L$005tail:
+	add	edx,DWORD [112+esp]
+	add	edi,DWORD [120+esp]
+	mov	DWORD [esp],eax
+	mov	DWORD [16+esp],ebp
+	mov	DWORD [32+esp],ecx
+	mov	DWORD [36+esp],esi
+	mov	DWORD [48+esp],edx
+	mov	DWORD [56+esp],edi
+	mov	ebp,DWORD [4+esp]
+	mov	ecx,DWORD [8+esp]
+	mov	esi,DWORD [12+esp]
+	mov	edx,DWORD [20+esp]
+	mov	edi,DWORD [24+esp]
+	add	ebp,857760878
+	add	ecx,2036477234
+	add	esi,1797285236
+	add	edx,DWORD [84+esp]
+	add	edi,DWORD [88+esp]
+	mov	DWORD [4+esp],ebp
+	mov	DWORD [8+esp],ecx
+	mov	DWORD [12+esp],esi
+	mov	DWORD [20+esp],edx
+	mov	DWORD [24+esp],edi
+	mov	ebp,DWORD [28+esp]
+	mov	ecx,DWORD [40+esp]
+	mov	esi,DWORD [44+esp]
+	mov	edx,DWORD [52+esp]
+	mov	edi,DWORD [60+esp]
+	add	ebp,DWORD [92+esp]
+	add	ecx,DWORD [104+esp]
+	add	esi,DWORD [108+esp]
+	add	edx,DWORD [116+esp]
+	add	edi,DWORD [124+esp]
+	mov	DWORD [28+esp],ebp
+	mov	ebp,DWORD [156+esp]
+	mov	DWORD [40+esp],ecx
+	mov	ecx,DWORD [152+esp]
+	mov	DWORD [44+esp],esi
+	xor	esi,esi
+	mov	DWORD [52+esp],edx
+	mov	DWORD [60+esp],edi
+	xor	eax,eax
+	xor	edx,edx
+L$007tail_loop:
+	mov	al,BYTE [ebp*1+esi]
+	mov	dl,BYTE [esi*1+esp]
+	lea	esi,[1+esi]
+	xor	al,dl
+	mov	BYTE [esi*1+ecx-1],al
+	dec	ebx
+	jnz	NEAR L$007tail_loop
+L$006done:
+	add	esp,132
+L$000no_data:
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+global	_ChaCha20_ssse3
+align	16
+_ChaCha20_ssse3:
+L$_ChaCha20_ssse3_begin:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+L$ssse3_shortcut:
+	mov	edi,DWORD [20+esp]
+	mov	esi,DWORD [24+esp]
+	mov	ecx,DWORD [28+esp]
+	mov	edx,DWORD [32+esp]
+	mov	ebx,DWORD [36+esp]
+	mov	ebp,esp
+	sub	esp,524
+	and	esp,-64
+	mov	DWORD [512+esp],ebp
+	lea	eax,[(L$ssse3_data-L$pic_point)+eax]
+	movdqu	xmm3,[ebx]
+	cmp	ecx,256
+	jb	NEAR L$0081x
+	mov	DWORD [516+esp],edx
+	mov	DWORD [520+esp],ebx
+	sub	ecx,256
+	lea	ebp,[384+esp]
+	movdqu	xmm7,[edx]
+	pshufd	xmm0,xmm3,0
+	pshufd	xmm1,xmm3,85
+	pshufd	xmm2,xmm3,170
+	pshufd	xmm3,xmm3,255
+	paddd	xmm0,[48+eax]
+	pshufd	xmm4,xmm7,0
+	pshufd	xmm5,xmm7,85
+	psubd	xmm0,[64+eax]
+	pshufd	xmm6,xmm7,170
+	pshufd	xmm7,xmm7,255
+	movdqa	[64+ebp],xmm0
+	movdqa	[80+ebp],xmm1
+	movdqa	[96+ebp],xmm2
+	movdqa	[112+ebp],xmm3
+	movdqu	xmm3,[16+edx]
+	movdqa	[ebp-64],xmm4
+	movdqa	[ebp-48],xmm5
+	movdqa	[ebp-32],xmm6
+	movdqa	[ebp-16],xmm7
+	movdqa	xmm7,[32+eax]
+	lea	ebx,[128+esp]
+	pshufd	xmm0,xmm3,0
+	pshufd	xmm1,xmm3,85
+	pshufd	xmm2,xmm3,170
+	pshufd	xmm3,xmm3,255
+	pshufd	xmm4,xmm7,0
+	pshufd	xmm5,xmm7,85
+	pshufd	xmm6,xmm7,170
+	pshufd	xmm7,xmm7,255
+	movdqa	[ebp],xmm0
+	movdqa	[16+ebp],xmm1
+	movdqa	[32+ebp],xmm2
+	movdqa	[48+ebp],xmm3
+	movdqa	[ebp-128],xmm4
+	movdqa	[ebp-112],xmm5
+	movdqa	[ebp-96],xmm6
+	movdqa	[ebp-80],xmm7
+	lea	esi,[128+esi]
+	lea	edi,[128+edi]
+	jmp	NEAR L$009outer_loop
+align	16
+L$009outer_loop:
+	movdqa	xmm1,[ebp-112]
+	movdqa	xmm2,[ebp-96]
+	movdqa	xmm3,[ebp-80]
+	movdqa	xmm5,[ebp-48]
+	movdqa	xmm6,[ebp-32]
+	movdqa	xmm7,[ebp-16]
+	movdqa	[ebx-112],xmm1
+	movdqa	[ebx-96],xmm2
+	movdqa	[ebx-80],xmm3
+	movdqa	[ebx-48],xmm5
+	movdqa	[ebx-32],xmm6
+	movdqa	[ebx-16],xmm7
+	movdqa	xmm2,[32+ebp]
+	movdqa	xmm3,[48+ebp]
+	movdqa	xmm4,[64+ebp]
+	movdqa	xmm5,[80+ebp]
+	movdqa	xmm6,[96+ebp]
+	movdqa	xmm7,[112+ebp]
+	paddd	xmm4,[64+eax]
+	movdqa	[32+ebx],xmm2
+	movdqa	[48+ebx],xmm3
+	movdqa	[64+ebx],xmm4
+	movdqa	[80+ebx],xmm5
+	movdqa	[96+ebx],xmm6
+	movdqa	[112+ebx],xmm7
+	movdqa	[64+ebp],xmm4
+	movdqa	xmm0,[ebp-128]
+	movdqa	xmm6,xmm4
+	movdqa	xmm3,[ebp-64]
+	movdqa	xmm4,[ebp]
+	movdqa	xmm5,[16+ebp]
+	mov	edx,10
+	nop
+align	16
+L$010loop:
+	paddd	xmm0,xmm3
+	movdqa	xmm2,xmm3
+	pxor	xmm6,xmm0
+	pshufb	xmm6,[eax]
+	paddd	xmm4,xmm6
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-48]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-112]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[80+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-128],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[64+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	movdqa	[ebx],xmm4
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-64],xmm2
+	paddd	xmm5,xmm7
+	movdqa	xmm4,[32+ebx]
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-32]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-96]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[96+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-112],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[80+ebx],xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	movdqa	[16+ebx],xmm5
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-48],xmm3
+	paddd	xmm4,xmm6
+	movdqa	xmm5,[48+ebx]
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-16]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-80]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[112+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-96],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[96+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-32],xmm2
+	paddd	xmm5,xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-48]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-128]
+	paddd	xmm1,xmm3
+	pxor	xmm7,xmm1
+	movdqa	[ebx-80],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	xmm6,xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-16],xmm3
+	paddd	xmm4,xmm6
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-32]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-112]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[64+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-128],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[112+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	movdqa	[32+ebx],xmm4
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-48],xmm2
+	paddd	xmm5,xmm7
+	movdqa	xmm4,[ebx]
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-16]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-96]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[80+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-112],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[64+ebx],xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	movdqa	[48+ebx],xmm5
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-32],xmm3
+	paddd	xmm4,xmm6
+	movdqa	xmm5,[16+ebx]
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-64]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-80]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[96+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-96],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[80+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-16],xmm2
+	paddd	xmm5,xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-128]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[64+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-80],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[96+ebx],xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	por	xmm3,xmm1
+	dec	edx
+	jnz	NEAR L$010loop
+	movdqa	[ebx-64],xmm3
+	movdqa	[ebx],xmm4
+	movdqa	[16+ebx],xmm5
+	movdqa	[64+ebx],xmm6
+	movdqa	[96+ebx],xmm7
+	movdqa	xmm1,[ebx-112]
+	movdqa	xmm2,[ebx-96]
+	movdqa	xmm3,[ebx-80]
+	paddd	xmm0,[ebp-128]
+	paddd	xmm1,[ebp-112]
+	paddd	xmm2,[ebp-96]
+	paddd	xmm3,[ebp-80]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqa	[ebx-128],xmm0
+	movdqa	xmm0,[ebx-64]
+	movdqa	[ebx-112],xmm1
+	movdqa	[ebx-96],xmm6
+	movdqa	[ebx-80],xmm3
+	movdqa	xmm1,[ebx-48]
+	movdqa	xmm2,[ebx-32]
+	movdqa	xmm3,[ebx-16]
+	paddd	xmm0,[ebp-64]
+	paddd	xmm1,[ebp-48]
+	paddd	xmm2,[ebp-32]
+	paddd	xmm3,[ebp-16]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqa	[ebx-64],xmm0
+	movdqa	xmm0,[ebx]
+	movdqa	[ebx-48],xmm1
+	movdqa	[ebx-32],xmm6
+	movdqa	[ebx-16],xmm3
+	movdqa	xmm1,[16+ebx]
+	movdqa	xmm2,[32+ebx]
+	movdqa	xmm3,[48+ebx]
+	paddd	xmm0,[ebp]
+	paddd	xmm1,[16+ebp]
+	paddd	xmm2,[32+ebp]
+	paddd	xmm3,[48+ebp]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqa	[ebx],xmm0
+	movdqa	xmm0,[64+ebx]
+	movdqa	[16+ebx],xmm1
+	movdqa	[32+ebx],xmm6
+	movdqa	[48+ebx],xmm3
+	movdqa	xmm1,[80+ebx]
+	movdqa	xmm2,[96+ebx]
+	movdqa	xmm3,[112+ebx]
+	paddd	xmm0,[64+ebp]
+	paddd	xmm1,[80+ebp]
+	paddd	xmm2,[96+ebp]
+	paddd	xmm3,[112+ebp]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqa	[64+ebx],xmm0
+	movdqa	[80+ebx],xmm1
+	movdqa	[96+ebx],xmm6
+	movdqa	[112+ebx],xmm3
+	movdqu	xmm0,[esi-128]
+	movdqu	xmm1,[esi-112]
+	movdqu	xmm2,[esi-96]
+	movdqu	xmm3,[esi-80]
+	pxor	xmm0,[ebx-128]
+	pxor	xmm1,[ebx-64]
+	pxor	xmm2,[ebx]
+	pxor	xmm3,[64+ebx]
+	movdqu	[edi-128],xmm0
+	movdqu	[edi-112],xmm1
+	movdqu	[edi-96],xmm2
+	movdqu	[edi-80],xmm3
+	movdqu	xmm0,[esi-64]
+	movdqu	xmm1,[esi-48]
+	movdqu	xmm2,[esi-32]
+	movdqu	xmm3,[esi-16]
+	pxor	xmm0,[ebx-112]
+	pxor	xmm1,[ebx-48]
+	pxor	xmm2,[16+ebx]
+	pxor	xmm3,[80+ebx]
+	movdqu	[edi-64],xmm0
+	movdqu	[edi-48],xmm1
+	movdqu	[edi-32],xmm2
+	movdqu	[edi-16],xmm3
+	movdqu	xmm0,[esi]
+	movdqu	xmm1,[16+esi]
+	movdqu	xmm2,[32+esi]
+	movdqu	xmm3,[48+esi]
+	pxor	xmm0,[ebx-96]
+	pxor	xmm1,[ebx-32]
+	pxor	xmm2,[32+ebx]
+	pxor	xmm3,[96+ebx]
+	movdqu	[edi],xmm0
+	movdqu	[16+edi],xmm1
+	movdqu	[32+edi],xmm2
+	movdqu	[48+edi],xmm3
+	movdqu	xmm0,[64+esi]
+	movdqu	xmm1,[80+esi]
+	movdqu	xmm2,[96+esi]
+	movdqu	xmm3,[112+esi]
+	pxor	xmm0,[ebx-80]
+	pxor	xmm1,[ebx-16]
+	pxor	xmm2,[48+ebx]
+	pxor	xmm3,[112+ebx]
+	movdqu	[64+edi],xmm0
+	movdqu	[80+edi],xmm1
+	movdqu	[96+edi],xmm2
+	movdqu	[112+edi],xmm3
+	lea	esi,[256+esi]
+	lea	edi,[256+edi]
+	sub	ecx,256
+	jnc	NEAR L$009outer_loop
+	add	ecx,256
+	jz	NEAR L$011done
+	mov	ebx,DWORD [520+esp]
+	lea	esi,[esi-128]
+	mov	edx,DWORD [516+esp]
+	lea	edi,[edi-128]
+	movd	xmm2,DWORD [64+ebp]
+	movdqu	xmm3,[ebx]
+	paddd	xmm2,[96+eax]
+	pand	xmm3,[112+eax]
+	por	xmm3,xmm2
+L$0081x:
+	movdqa	xmm0,[32+eax]
+	movdqu	xmm1,[edx]
+	movdqu	xmm2,[16+edx]
+	movdqa	xmm6,[eax]
+	movdqa	xmm7,[16+eax]
+	mov	DWORD [48+esp],ebp
+	movdqa	[esp],xmm0
+	movdqa	[16+esp],xmm1
+	movdqa	[32+esp],xmm2
+	movdqa	[48+esp],xmm3
+	mov	edx,10
+	jmp	NEAR L$012loop1x
+align	16
+L$013outer1x:
+	movdqa	xmm3,[80+eax]
+	movdqa	xmm0,[esp]
+	movdqa	xmm1,[16+esp]
+	movdqa	xmm2,[32+esp]
+	paddd	xmm3,[48+esp]
+	mov	edx,10
+	movdqa	[48+esp],xmm3
+	jmp	NEAR L$012loop1x
+align	16
+L$012loop1x:
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,57
+	pshufd	xmm3,xmm3,147
+	nop
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,147
+	pshufd	xmm3,xmm3,57
+	dec	edx
+	jnz	NEAR L$012loop1x
+	paddd	xmm0,[esp]
+	paddd	xmm1,[16+esp]
+	paddd	xmm2,[32+esp]
+	paddd	xmm3,[48+esp]
+	cmp	ecx,64
+	jb	NEAR L$014tail
+	movdqu	xmm4,[esi]
+	movdqu	xmm5,[16+esi]
+	pxor	xmm0,xmm4
+	movdqu	xmm4,[32+esi]
+	pxor	xmm1,xmm5
+	movdqu	xmm5,[48+esi]
+	pxor	xmm2,xmm4
+	pxor	xmm3,xmm5
+	lea	esi,[64+esi]
+	movdqu	[edi],xmm0
+	movdqu	[16+edi],xmm1
+	movdqu	[32+edi],xmm2
+	movdqu	[48+edi],xmm3
+	lea	edi,[64+edi]
+	sub	ecx,64
+	jnz	NEAR L$013outer1x
+	jmp	NEAR L$011done
+L$014tail:
+	movdqa	[esp],xmm0
+	movdqa	[16+esp],xmm1
+	movdqa	[32+esp],xmm2
+	movdqa	[48+esp],xmm3
+	xor	eax,eax
+	xor	edx,edx
+	xor	ebp,ebp
+L$015tail_loop:
+	mov	al,BYTE [ebp*1+esp]
+	mov	dl,BYTE [ebp*1+esi]
+	lea	ebp,[1+ebp]
+	xor	al,dl
+	mov	BYTE [ebp*1+edi-1],al
+	dec	ecx
+	jnz	NEAR L$015tail_loop
+L$011done:
+	mov	esp,DWORD [512+esp]
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+align	64
+L$ssse3_data:
+db	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+db	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+dd	1634760805,857760878,2036477234,1797285236
+dd	0,1,2,3
+dd	4,4,4,4
+dd	1,0,0,0
+dd	4,0,0,0
+dd	0,-1,-1,-1
+align	64
+db	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+db	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+db	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+db	114,103,62,0
+segment	.bss
+common	_OPENSSL_ia32cap_P 16
diff --git a/win-x86/crypto/rc4/rc4-586.asm b/win-x86/crypto/rc4/rc4-586.asm
index 08cd9f6..0bab2be 100644
--- a/win-x86/crypto/rc4/rc4-586.asm
+++ b/win-x86/crypto/rc4/rc4-586.asm
@@ -349,34 +349,5 @@
 	pop	ebx
 	pop	ebp
 	ret
-global	_RC4_options
-align	16
-_RC4_options:
-L$_RC4_options_begin:
-	call	L$016pic_point
-L$016pic_point:
-	pop	eax
-	lea	eax,[(L$017opts-L$016pic_point)+eax]
-	lea	edx,[_OPENSSL_ia32cap_P]
-	mov	edx,DWORD [edx]
-	bt	edx,20
-	jc	NEAR L$0181xchar
-	bt	edx,26
-	jnc	NEAR L$019ret
-	add	eax,25
-	ret
-L$0181xchar:
-	add	eax,12
-L$019ret:
-	ret
-align	64
-L$017opts:
-db	114,99,52,40,52,120,44,105,110,116,41,0
-db	114,99,52,40,49,120,44,99,104,97,114,41,0
-db	114,99,52,40,56,120,44,109,109,120,41,0
-db	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-db	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-db	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-align	64
 segment	.bss
 common	_OPENSSL_ia32cap_P 16
diff --git a/win-x86_64/crypto/bn/rsaz-x86_64.asm b/win-x86_64/crypto/bn/rsaz-x86_64.asm
index 04d5e39..72ec505 100644
--- a/win-x86_64/crypto/bn/rsaz-x86_64.asm
+++ b/win-x86_64/crypto/bn/rsaz-x86_64.asm
@@ -504,48 +504,104 @@
 	push	r14
 	push	r15
 
-	mov	r9d,r9d
-	sub	rsp,128+24
+	sub	rsp,328
+	movaps	XMMWORD[160+rsp],xmm6
+	movaps	XMMWORD[176+rsp],xmm7
+	movaps	XMMWORD[192+rsp],xmm8
+	movaps	XMMWORD[208+rsp],xmm9
+	movaps	XMMWORD[224+rsp],xmm10
+	movaps	XMMWORD[240+rsp],xmm11
+	movaps	XMMWORD[256+rsp],xmm12
+	movaps	XMMWORD[272+rsp],xmm13
+	movaps	XMMWORD[288+rsp],xmm14
+	movaps	XMMWORD[304+rsp],xmm15
 $L$mul_gather4_body:
-	mov	eax,DWORD[64+r9*4+rdx]
-DB	102,72,15,110,199
-	mov	ebx,DWORD[r9*4+rdx]
-DB	102,72,15,110,201
-	mov	QWORD[128+rsp],r8
+	movd	xmm8,r9d
+	movdqa	xmm1,XMMWORD[(($L$inc+16))]
+	movdqa	xmm0,XMMWORD[$L$inc]
 
-	shl	rax,32
-	or	rbx,rax
+	pshufd	xmm8,xmm8,0
+	movdqa	xmm7,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm8
+	movdqa	xmm3,xmm7
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm8
+	movdqa	xmm4,xmm7
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm8
+	movdqa	xmm5,xmm7
+	paddd	xmm4,xmm3
+	pcmpeqd	xmm3,xmm8
+	movdqa	xmm6,xmm7
+	paddd	xmm5,xmm4
+	pcmpeqd	xmm4,xmm8
+	paddd	xmm6,xmm5
+	pcmpeqd	xmm5,xmm8
+	paddd	xmm7,xmm6
+	pcmpeqd	xmm6,xmm8
+	pcmpeqd	xmm7,xmm8
+
+	movdqa	xmm8,XMMWORD[rdx]
+	movdqa	xmm9,XMMWORD[16+rdx]
+	movdqa	xmm10,XMMWORD[32+rdx]
+	movdqa	xmm11,XMMWORD[48+rdx]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rdx]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rdx]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rdx]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rdx]
+	lea	rbp,[128+rdx]
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+DB	102,76,15,126,195
+
+	mov	QWORD[128+rsp],r8
+	mov	QWORD[((128+8))+rsp],rdi
+	mov	QWORD[((128+16))+rsp],rcx
+
 	mov	rax,QWORD[rsi]
 	mov	rcx,QWORD[8+rsi]
-	lea	rbp,[128+r9*4+rdx]
 	mul	rbx
 	mov	QWORD[rsp],rax
 	mov	rax,rcx
 	mov	r8,rdx
 
 	mul	rbx
-	movd	xmm4,DWORD[rbp]
 	add	r8,rax
 	mov	rax,QWORD[16+rsi]
 	mov	r9,rdx
 	adc	r9,0
 
 	mul	rbx
-	movd	xmm5,DWORD[64+rbp]
 	add	r9,rax
 	mov	rax,QWORD[24+rsi]
 	mov	r10,rdx
 	adc	r10,0
 
 	mul	rbx
-	pslldq	xmm5,4
 	add	r10,rax
 	mov	rax,QWORD[32+rsi]
 	mov	r11,rdx
 	adc	r11,0
 
 	mul	rbx
-	por	xmm4,xmm5
 	add	r11,rax
 	mov	rax,QWORD[40+rsi]
 	mov	r12,rdx
@@ -558,14 +614,12 @@
 	adc	r13,0
 
 	mul	rbx
-	lea	rbp,[128+rbp]
 	add	r13,rax
 	mov	rax,QWORD[56+rsi]
 	mov	r14,rdx
 	adc	r14,0
 
 	mul	rbx
-DB	102,72,15,126,227
 	add	r14,rax
 	mov	rax,QWORD[rsi]
 	mov	r15,rdx
@@ -577,6 +631,35 @@
 
 ALIGN	32
 $L$oop_mul_gather:
+	movdqa	xmm8,XMMWORD[rbp]
+	movdqa	xmm9,XMMWORD[16+rbp]
+	movdqa	xmm10,XMMWORD[32+rbp]
+	movdqa	xmm11,XMMWORD[48+rbp]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rbp]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rbp]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rbp]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rbp]
+	lea	rbp,[128+rbp]
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+DB	102,76,15,126,195
+
 	mul	rbx
 	add	r8,rax
 	mov	rax,QWORD[8+rsi]
@@ -585,7 +668,6 @@
 	adc	r8,0
 
 	mul	rbx
-	movd	xmm4,DWORD[rbp]
 	add	r9,rax
 	mov	rax,QWORD[16+rsi]
 	adc	rdx,0
@@ -594,7 +676,6 @@
 	adc	r9,0
 
 	mul	rbx
-	movd	xmm5,DWORD[64+rbp]
 	add	r10,rax
 	mov	rax,QWORD[24+rsi]
 	adc	rdx,0
@@ -603,7 +684,6 @@
 	adc	r10,0
 
 	mul	rbx
-	pslldq	xmm5,4
 	add	r11,rax
 	mov	rax,QWORD[32+rsi]
 	adc	rdx,0
@@ -612,7 +692,6 @@
 	adc	r11,0
 
 	mul	rbx
-	por	xmm4,xmm5
 	add	r12,rax
 	mov	rax,QWORD[40+rsi]
 	adc	rdx,0
@@ -637,7 +716,6 @@
 	adc	r14,0
 
 	mul	rbx
-DB	102,72,15,126,227
 	add	r15,rax
 	mov	rax,QWORD[rsi]
 	adc	rdx,0
@@ -645,7 +723,6 @@
 	mov	r15,rdx
 	adc	r15,0
 
-	lea	rbp,[128+rbp]
 	lea	rdi,[8+rdi]
 
 	dec	ecx
@@ -660,8 +737,8 @@
 	mov	QWORD[48+rdi],r14
 	mov	QWORD[56+rdi],r15
 
-DB	102,72,15,126,199
-DB	102,72,15,126,205
+	mov	rdi,QWORD[((128+8))+rsp]
+	mov	rbp,QWORD[((128+16))+rsp]
 
 	mov	r8,QWORD[rsp]
 	mov	r9,QWORD[8+rsp]
@@ -686,6 +763,17 @@
 	call	__rsaz_512_subtract
 
 	lea	rax,[((128+24+48))+rsp]
+	movaps	xmm6,XMMWORD[((160-200))+rax]
+	movaps	xmm7,XMMWORD[((176-200))+rax]
+	movaps	xmm8,XMMWORD[((192-200))+rax]
+	movaps	xmm9,XMMWORD[((208-200))+rax]
+	movaps	xmm10,XMMWORD[((224-200))+rax]
+	movaps	xmm11,XMMWORD[((240-200))+rax]
+	movaps	xmm12,XMMWORD[((256-200))+rax]
+	movaps	xmm13,XMMWORD[((272-200))+rax]
+	movaps	xmm14,XMMWORD[((288-200))+rax]
+	movaps	xmm15,XMMWORD[((304-200))+rax]
+	lea	rax,[176+rax]
 	mov	r15,QWORD[((-48))+rax]
 	mov	r14,QWORD[((-40))+rax]
 	mov	r13,QWORD[((-32))+rax]
@@ -724,7 +812,7 @@
 	mov	r9d,r9d
 	sub	rsp,128+24
 $L$mul_scatter4_body:
-	lea	r8,[r9*4+r8]
+	lea	r8,[r9*8+r8]
 DB	102,72,15,110,199
 DB	102,72,15,110,202
 DB	102,73,15,110,208
@@ -760,30 +848,14 @@
 
 	call	__rsaz_512_subtract
 
-	mov	DWORD[rsi],r8d
-	shr	r8,32
-	mov	DWORD[128+rsi],r9d
-	shr	r9,32
-	mov	DWORD[256+rsi],r10d
-	shr	r10,32
-	mov	DWORD[384+rsi],r11d
-	shr	r11,32
-	mov	DWORD[512+rsi],r12d
-	shr	r12,32
-	mov	DWORD[640+rsi],r13d
-	shr	r13,32
-	mov	DWORD[768+rsi],r14d
-	shr	r14,32
-	mov	DWORD[896+rsi],r15d
-	shr	r15,32
-	mov	DWORD[64+rsi],r8d
-	mov	DWORD[192+rsi],r9d
-	mov	DWORD[320+rsi],r10d
-	mov	DWORD[448+rsi],r11d
-	mov	DWORD[576+rsi],r12d
-	mov	DWORD[704+rsi],r13d
-	mov	DWORD[832+rsi],r14d
-	mov	DWORD[960+rsi],r15d
+	mov	QWORD[rsi],r8
+	mov	QWORD[128+rsi],r9
+	mov	QWORD[256+rsi],r10
+	mov	QWORD[384+rsi],r11
+	mov	QWORD[512+rsi],r12
+	mov	QWORD[640+rsi],r13
+	mov	QWORD[768+rsi],r14
+	mov	QWORD[896+rsi],r15
 
 	lea	rax,[((128+24+48))+rsp]
 	mov	r15,QWORD[((-48))+rax]
@@ -1150,16 +1222,14 @@
 
 ALIGN	16
 rsaz_512_scatter4:
-	lea	rcx,[r8*4+rcx]
+	lea	rcx,[r8*8+rcx]
 	mov	r9d,8
 	jmp	NEAR $L$oop_scatter
 ALIGN	16
 $L$oop_scatter:
 	mov	rax,QWORD[rdx]
 	lea	rdx,[8+rdx]
-	mov	DWORD[rcx],eax
-	shr	rax,32
-	mov	DWORD[64+rcx],eax
+	mov	QWORD[rcx],rax
 	lea	rcx,[128+rcx]
 	dec	r9d
 	jnz	NEAR $L$oop_scatter
@@ -1170,22 +1240,98 @@
 
 ALIGN	16
 rsaz_512_gather4:
-	lea	rdx,[r8*4+rdx]
+$L$SEH_begin_rsaz_512_gather4:
+DB	0x48,0x81,0xec,0xa8,0x00,0x00,0x00
+DB	0x0f,0x29,0x34,0x24
+DB	0x0f,0x29,0x7c,0x24,0x10
+DB	0x44,0x0f,0x29,0x44,0x24,0x20
+DB	0x44,0x0f,0x29,0x4c,0x24,0x30
+DB	0x44,0x0f,0x29,0x54,0x24,0x40
+DB	0x44,0x0f,0x29,0x5c,0x24,0x50
+DB	0x44,0x0f,0x29,0x64,0x24,0x60
+DB	0x44,0x0f,0x29,0x6c,0x24,0x70
+DB	0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0
+DB	0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0
+	movd	xmm8,r8d
+	movdqa	xmm1,XMMWORD[(($L$inc+16))]
+	movdqa	xmm0,XMMWORD[$L$inc]
+
+	pshufd	xmm8,xmm8,0
+	movdqa	xmm7,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm8
+	movdqa	xmm3,xmm7
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm8
+	movdqa	xmm4,xmm7
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm8
+	movdqa	xmm5,xmm7
+	paddd	xmm4,xmm3
+	pcmpeqd	xmm3,xmm8
+	movdqa	xmm6,xmm7
+	paddd	xmm5,xmm4
+	pcmpeqd	xmm4,xmm8
+	paddd	xmm6,xmm5
+	pcmpeqd	xmm5,xmm8
+	paddd	xmm7,xmm6
+	pcmpeqd	xmm6,xmm8
+	pcmpeqd	xmm7,xmm8
 	mov	r9d,8
 	jmp	NEAR $L$oop_gather
 ALIGN	16
 $L$oop_gather:
-	mov	eax,DWORD[rdx]
-	mov	r8d,DWORD[64+rdx]
+	movdqa	xmm8,XMMWORD[rdx]
+	movdqa	xmm9,XMMWORD[16+rdx]
+	movdqa	xmm10,XMMWORD[32+rdx]
+	movdqa	xmm11,XMMWORD[48+rdx]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rdx]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rdx]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rdx]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rdx]
 	lea	rdx,[128+rdx]
-	shl	r8,32
-	or	rax,r8
-	mov	QWORD[rcx],rax
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+	movq	QWORD[rcx],xmm8
 	lea	rcx,[8+rcx]
 	dec	r9d
 	jnz	NEAR $L$oop_gather
+	movaps	xmm6,XMMWORD[rsp]
+	movaps	xmm7,XMMWORD[16+rsp]
+	movaps	xmm8,XMMWORD[32+rsp]
+	movaps	xmm9,XMMWORD[48+rsp]
+	movaps	xmm10,XMMWORD[64+rsp]
+	movaps	xmm11,XMMWORD[80+rsp]
+	movaps	xmm12,XMMWORD[96+rsp]
+	movaps	xmm13,XMMWORD[112+rsp]
+	movaps	xmm14,XMMWORD[128+rsp]
+	movaps	xmm15,XMMWORD[144+rsp]
+	add	rsp,0xa8
 	DB	0F3h,0C3h		;repret
+$L$SEH_end_rsaz_512_gather4:
 
+
+ALIGN	64
+$L$inc:
+	DD	0,0,1,1
+	DD	2,2,2,2
 EXTERN	__imp_RtlVirtualUnwind
 
 ALIGN	16
@@ -1221,6 +1367,18 @@
 
 	lea	rax,[((128+24+48))+rax]
 
+	lea	rbx,[$L$mul_gather4_epilogue]
+	cmp	rbx,r10
+	jne	NEAR $L$se_not_in_mul_gather4
+
+	lea	rax,[176+rax]
+
+	lea	rsi,[((-48-168))+rax]
+	lea	rdi,[512+r8]
+	mov	ecx,20
+	DD	0xa548f3fc
+
+$L$se_not_in_mul_gather4:
 	mov	rbx,QWORD[((-8))+rax]
 	mov	rbp,QWORD[((-16))+rax]
 	mov	r12,QWORD[((-24))+rax]
@@ -1296,6 +1454,10 @@
 	DD	$L$SEH_end_rsaz_512_mul_by_one wrt ..imagebase
 	DD	$L$SEH_info_rsaz_512_mul_by_one wrt ..imagebase
 
+	DD	$L$SEH_begin_rsaz_512_gather4 wrt ..imagebase
+	DD	$L$SEH_end_rsaz_512_gather4 wrt ..imagebase
+	DD	$L$SEH_info_rsaz_512_gather4 wrt ..imagebase
+
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_rsaz_512_sqr:
@@ -1318,3 +1480,16 @@
 DB	9,0,0,0
 	DD	se_handler wrt ..imagebase
 	DD	$L$mul_by_one_body wrt ..imagebase,$L$mul_by_one_epilogue wrt ..imagebase
+$L$SEH_info_rsaz_512_gather4:
+DB	0x01,0x46,0x16,0x00
+DB	0x46,0xf8,0x09,0x00
+DB	0x3d,0xe8,0x08,0x00
+DB	0x34,0xd8,0x07,0x00
+DB	0x2e,0xc8,0x06,0x00
+DB	0x28,0xb8,0x05,0x00
+DB	0x22,0xa8,0x04,0x00
+DB	0x1c,0x98,0x03,0x00
+DB	0x16,0x88,0x02,0x00
+DB	0x10,0x78,0x01,0x00
+DB	0x0b,0x68,0x00,0x00
+DB	0x07,0x01,0x15,0x00
diff --git a/win-x86_64/crypto/bn/x86_64-mont.asm b/win-x86_64/crypto/bn/x86_64-mont.asm
index db0d1b9..4d8e1cb 100644
--- a/win-x86_64/crypto/bn/x86_64-mont.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont.asm
@@ -677,20 +677,20 @@
 
 
 
-	lea	r11,[((-64))+r9*4+rsp]
+	lea	r11,[((-64))+r9*2+rsp]
 	mov	r8,QWORD[r8]
 	sub	r11,rsi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$sqr8x_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*4+rsp]
+	lea	rsp,[((-64))+r9*2+rsp]
 	jmp	NEAR $L$sqr8x_sp_done
 
 ALIGN	32
 $L$sqr8x_sp_alt:
-	lea	r10,[((4096-64))+r9*4]
-	lea	rsp,[((-64))+r9*4+rsp]
+	lea	r10,[((4096-64))+r9*2]
+	lea	rsp,[((-64))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -700,58 +700,80 @@
 	mov	r10,r9
 	neg	r9
 
-	lea	r11,[64+r9*2+rsp]
 	mov	QWORD[32+rsp],r8
 	mov	QWORD[40+rsp],rax
 $L$sqr8x_body:
 
-	mov	rbp,r9
-DB	102,73,15,110,211
-	shr	rbp,3+2
-	mov	eax,DWORD[((OPENSSL_ia32cap_P+8))]
-	jmp	NEAR $L$sqr8x_copy_n
-
-ALIGN	32
-$L$sqr8x_copy_n:
-	movq	xmm0,QWORD[rcx]
-	movq	xmm1,QWORD[8+rcx]
-	movq	xmm3,QWORD[16+rcx]
-	movq	xmm4,QWORD[24+rcx]
-	lea	rcx,[32+rcx]
-	movdqa	XMMWORD[r11],xmm0
-	movdqa	XMMWORD[16+r11],xmm1
-	movdqa	XMMWORD[32+r11],xmm3
-	movdqa	XMMWORD[48+r11],xmm4
-	lea	r11,[64+r11]
-	dec	rbp
-	jnz	NEAR $L$sqr8x_copy_n
-
+DB	102,72,15,110,209
 	pxor	xmm0,xmm0
 DB	102,72,15,110,207
 DB	102,73,15,110,218
 	call	bn_sqr8x_internal
 
-	pxor	xmm0,xmm0
-	lea	rax,[48+rsp]
-	lea	rdx,[64+r9*2+rsp]
-	shr	r9,3+2
-	mov	rsi,QWORD[40+rsp]
-	jmp	NEAR $L$sqr8x_zero
+
+
+
+	lea	rbx,[r9*1+rdi]
+	mov	rcx,r9
+	mov	rdx,r9
+DB	102,72,15,126,207
+	sar	rcx,3+2
+	jmp	NEAR $L$sqr8x_sub
 
 ALIGN	32
-$L$sqr8x_zero:
-	movdqa	XMMWORD[rax],xmm0
-	movdqa	XMMWORD[16+rax],xmm0
-	movdqa	XMMWORD[32+rax],xmm0
-	movdqa	XMMWORD[48+rax],xmm0
-	lea	rax,[64+rax]
-	movdqa	XMMWORD[rdx],xmm0
-	movdqa	XMMWORD[16+rdx],xmm0
-	movdqa	XMMWORD[32+rdx],xmm0
-	movdqa	XMMWORD[48+rdx],xmm0
-	lea	rdx,[64+rdx]
-	dec	r9
-	jnz	NEAR $L$sqr8x_zero
+$L$sqr8x_sub:
+	mov	r12,QWORD[rbx]
+	mov	r13,QWORD[8+rbx]
+	mov	r14,QWORD[16+rbx]
+	mov	r15,QWORD[24+rbx]
+	lea	rbx,[32+rbx]
+	sbb	r12,QWORD[rbp]
+	sbb	r13,QWORD[8+rbp]
+	sbb	r14,QWORD[16+rbp]
+	sbb	r15,QWORD[24+rbp]
+	lea	rbp,[32+rbp]
+	mov	QWORD[rdi],r12
+	mov	QWORD[8+rdi],r13
+	mov	QWORD[16+rdi],r14
+	mov	QWORD[24+rdi],r15
+	lea	rdi,[32+rdi]
+	inc	rcx
+	jnz	NEAR $L$sqr8x_sub
+
+	sbb	rax,0
+	lea	rbx,[r9*1+rbx]
+	lea	rdi,[r9*1+rdi]
+
+DB	102,72,15,110,200
+	pxor	xmm0,xmm0
+	pshufd	xmm1,xmm1,0
+	mov	rsi,QWORD[40+rsp]
+	jmp	NEAR $L$sqr8x_cond_copy
+
+ALIGN	32
+$L$sqr8x_cond_copy:
+	movdqa	xmm2,XMMWORD[rbx]
+	movdqa	xmm3,XMMWORD[16+rbx]
+	lea	rbx,[32+rbx]
+	movdqu	xmm4,XMMWORD[rdi]
+	movdqu	xmm5,XMMWORD[16+rdi]
+	lea	rdi,[32+rdi]
+	movdqa	XMMWORD[(-32)+rbx],xmm0
+	movdqa	XMMWORD[(-16)+rbx],xmm0
+	movdqa	XMMWORD[(-32)+rdx*1+rbx],xmm0
+	movdqa	XMMWORD[(-16)+rdx*1+rbx],xmm0
+	pcmpeqd	xmm0,xmm1
+	pand	xmm2,xmm1
+	pand	xmm3,xmm1
+	pand	xmm4,xmm0
+	pand	xmm5,xmm0
+	pxor	xmm0,xmm0
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqu	XMMWORD[(-32)+rdi],xmm4
+	movdqu	XMMWORD[(-16)+rdi],xmm5
+	add	r9,32
+	jnz	NEAR $L$sqr8x_cond_copy
 
 	mov	rax,1
 	mov	r15,QWORD[((-48))+rsi]
diff --git a/win-x86_64/crypto/bn/x86_64-mont5.asm b/win-x86_64/crypto/bn/x86_64-mont5.asm
index 560b384..cd9a6e5 100644
--- a/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -31,49 +31,151 @@
 $L$mul_enter:
 	mov	r9d,r9d
 	mov	rax,rsp
-	mov	r10d,DWORD[56+rsp]
+	movd	xmm5,DWORD[56+rsp]
+	lea	r10,[$L$inc]
 	push	rbx
 	push	rbp
 	push	r12
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
+
 	lea	r11,[2+r9]
 	neg	r11
-	lea	rsp,[r11*8+rsp]
+	lea	rsp,[((-264))+r11*8+rsp]
 	and	rsp,-1024
 
 	mov	QWORD[8+r9*8+rsp],rax
 $L$mul_body:
-	mov	r12,rdx
-	mov	r11,r10
-	shr	r10,3
-	and	r11,7
-	not	r10
-	lea	rax,[$L$magic_masks]
-	and	r10,3
-	lea	r12,[96+r11*8+r12]
-	movq	xmm4,QWORD[r10*8+rax]
-	movq	xmm5,QWORD[8+r10*8+rax]
-	movq	xmm6,QWORD[16+r10*8+rax]
-	movq	xmm7,QWORD[24+r10*8+rax]
+	lea	r12,[128+rdx]
+	movdqa	xmm0,XMMWORD[r10]
+	movdqa	xmm1,XMMWORD[16+r10]
+	lea	r10,[((24-112))+r9*8+rsp]
+	and	r10,-16
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+DB	0x67
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[112+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[128+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[144+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[160+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[176+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[192+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[208+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[224+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[240+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[256+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[272+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[288+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[304+r10],xmm0
+
+	paddd	xmm3,xmm2
+DB	0x67
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[320+r10],xmm1
+
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[336+r10],xmm2
+	pand	xmm0,XMMWORD[64+r12]
+
+	pand	xmm1,XMMWORD[80+r12]
+	pand	xmm2,XMMWORD[96+r12]
+	movdqa	XMMWORD[352+r10],xmm3
+	pand	xmm3,XMMWORD[112+r12]
 	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-128))+r12]
+	movdqa	xmm5,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	pand	xmm4,XMMWORD[112+r10]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm5,XMMWORD[128+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[144+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[160+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-64))+r12]
+	movdqa	xmm5,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	pand	xmm4,XMMWORD[176+r10]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm5,XMMWORD[192+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[208+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[224+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[r12]
+	movdqa	xmm5,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	pand	xmm4,XMMWORD[240+r10]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm5,XMMWORD[256+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[272+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[288+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	por	xmm0,xmm1
+	pshufd	xmm1,xmm0,0x4e
+	por	xmm0,xmm1
 	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 DB	102,72,15,126,195
 
 	mov	r8,QWORD[r8]
@@ -82,29 +184,14 @@
 	xor	r14,r14
 	xor	r15,r15
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-
 	mov	rbp,r8
 	mul	rbx
 	mov	r10,rax
 	mov	rax,QWORD[rcx]
 
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-
 	imul	rbp,r10
 	mov	r11,rdx
 
-	por	xmm0,xmm2
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+rsi]
@@ -137,14 +224,12 @@
 	cmp	r15,r9
 	jne	NEAR $L$1st
 
-DB	102,72,15,126,195
 
 	add	r13,rax
-	mov	rax,QWORD[rsi]
 	adc	rdx,0
 	add	r13,r11
 	adc	rdx,0
-	mov	QWORD[((-16))+r15*8+rsp],r13
+	mov	QWORD[((-16))+r9*8+rsp],r13
 	mov	r13,rdx
 	mov	r11,r10
 
@@ -158,33 +243,78 @@
 	jmp	NEAR $L$outer
 ALIGN	16
 $L$outer:
+	lea	rdx,[((24+128))+r9*8+rsp]
+	and	rdx,-16
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r12]
+	movdqa	xmm1,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm0,XMMWORD[((-128))+rdx]
+	pand	xmm1,XMMWORD[((-112))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r12]
+	movdqa	xmm1,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm0,XMMWORD[((-64))+rdx]
+	pand	xmm1,XMMWORD[((-48))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r12]
+	movdqa	xmm1,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm0,XMMWORD[rdx]
+	pand	xmm1,XMMWORD[16+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r12]
+	movdqa	xmm1,XMMWORD[80+r12]
+	movdqa	xmm2,XMMWORD[96+r12]
+	movdqa	xmm3,XMMWORD[112+r12]
+	pand	xmm0,XMMWORD[64+rdx]
+	pand	xmm1,XMMWORD[80+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
+	lea	r12,[256+r12]
+
+	mov	rax,QWORD[rsi]
+DB	102,72,15,126,195
+
 	xor	r15,r15
 	mov	rbp,r8
 	mov	r10,QWORD[rsp]
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-
 	mul	rbx
 	add	r10,rax
 	mov	rax,QWORD[rcx]
 	adc	rdx,0
 
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-
 	imul	rbp,r10
 	mov	r11,rdx
 
-	por	xmm0,xmm2
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+rsi]
@@ -220,15 +350,12 @@
 	cmp	r15,r9
 	jne	NEAR $L$inner
 
-DB	102,72,15,126,195
-
 	add	r13,rax
-	mov	rax,QWORD[rsi]
 	adc	rdx,0
 	add	r13,r10
-	mov	r10,QWORD[r15*8+rsp]
+	mov	r10,QWORD[r9*8+rsp]
 	adc	rdx,0
-	mov	QWORD[((-16))+r15*8+rsp],r13
+	mov	QWORD[((-16))+r9*8+rsp],r13
 	mov	r13,rdx
 
 	xor	rdx,rdx
@@ -274,8 +401,7 @@
 
 	mov	rsi,QWORD[8+r9*8+rsp]
 	mov	rax,1
-	movaps	xmm6,XMMWORD[((-88))+rsi]
-	movaps	xmm7,XMMWORD[((-72))+rsi]
+
 	mov	r15,QWORD[((-48))+rsi]
 	mov	r14,QWORD[((-40))+rsi]
 	mov	r13,QWORD[((-32))+rsi]
@@ -312,13 +438,10 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
+
 DB	0x67
-	mov	r10d,r9d
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10,[r9*2+r9]
 	neg	r9
 
 
@@ -328,19 +451,21 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$mul4xsp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$mul4xsp_done
 
 ALIGN	32
 $L$mul4xsp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -356,8 +481,7 @@
 
 	mov	rsi,QWORD[40+rsp]
 	mov	rax,1
-	movaps	xmm6,XMMWORD[((-88))+rsi]
-	movaps	xmm7,XMMWORD[((-72))+rsi]
+
 	mov	r15,QWORD[((-48))+rsi]
 	mov	r14,QWORD[((-40))+rsi]
 	mov	r13,QWORD[((-32))+rsi]
@@ -375,47 +499,141 @@
 ALIGN	32
 mul4x_internal:
 	shl	r9,5
-	mov	r10d,DWORD[56+rax]
-	lea	r13,[256+r9*1+rdx]
+	movd	xmm5,DWORD[56+rax]
+	lea	rax,[$L$inc]
+	lea	r13,[128+r9*1+rdx]
 	shr	r9,5
-	mov	r11,r10
-	shr	r10,3
-	and	r11,7
-	not	r10
-	lea	rax,[$L$magic_masks]
-	and	r10,3
-	lea	r12,[96+r11*8+rdx]
-	movq	xmm4,QWORD[r10*8+rax]
-	movq	xmm5,QWORD[8+r10*8+rax]
-	add	r11,7
-	movq	xmm6,QWORD[16+r10*8+rax]
-	movq	xmm7,QWORD[24+r10*8+rax]
-	and	r11,7
+	movdqa	xmm0,XMMWORD[rax]
+	movdqa	xmm1,XMMWORD[16+rax]
+	lea	r10,[((88-112))+r9*1+rsp]
+	lea	r12,[128+rdx]
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	lea	r14,[256+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+DB	0x67,0x67
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
 DB	0x67
-	por	xmm0,xmm1
-	movq	xmm1,QWORD[((-96))+r14]
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[112+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[128+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[144+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[160+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[176+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[192+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[208+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[224+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[240+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[256+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[272+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[288+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[304+r10],xmm0
+
+	paddd	xmm3,xmm2
 DB	0x67
-	pand	xmm3,xmm7
-DB	0x67
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[320+r10],xmm1
+
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[336+r10],xmm2
+	pand	xmm0,XMMWORD[64+r12]
+
+	pand	xmm1,XMMWORD[80+r12]
+	pand	xmm2,XMMWORD[96+r12]
+	movdqa	XMMWORD[352+r10],xmm3
+	pand	xmm3,XMMWORD[112+r12]
 	por	xmm0,xmm2
-	movq	xmm2,QWORD[((-32))+r14]
-DB	0x67
-	pand	xmm1,xmm4
-DB	0x67
-	por	xmm0,xmm3
-	movq	xmm3,QWORD[32+r14]
-
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-128))+r12]
+	movdqa	xmm5,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	pand	xmm4,XMMWORD[112+r10]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm5,XMMWORD[128+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[144+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[160+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-64))+r12]
+	movdqa	xmm5,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	pand	xmm4,XMMWORD[176+r10]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm5,XMMWORD[192+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[208+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[224+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[r12]
+	movdqa	xmm5,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	pand	xmm4,XMMWORD[240+r10]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm5,XMMWORD[256+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[272+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[288+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	por	xmm0,xmm1
+	pshufd	xmm1,xmm0,0x4e
+	por	xmm0,xmm1
+	lea	r12,[256+r12]
 DB	102,72,15,126,195
-	movq	xmm0,QWORD[96+r14]
+
 	mov	QWORD[((16+8))+rsp],r13
 	mov	QWORD[((56+8))+rsp],rdi
 
@@ -429,26 +647,10 @@
 	mov	r10,rax
 	mov	rax,QWORD[rcx]
 
-	pand	xmm2,xmm5
-	pand	xmm3,xmm6
-	por	xmm1,xmm2
-
 	imul	rbp,r10
-
-
-
-
-
-
-
-	lea	r14,[((64+8))+r11*8+rsp]
+	lea	r14,[((64+8))+rsp]
 	mov	r11,rdx
 
-	pand	xmm0,xmm7
-	por	xmm1,xmm3
-	lea	r12,[512+r12]
-	por	xmm0,xmm1
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+r9*1+rsi]
@@ -457,7 +659,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -467,7 +669,7 @@
 	adc	rdx,0
 	add	rdi,r11
 	lea	r15,[32+r9]
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[r14],rdi
 	mov	r13,rdx
@@ -477,7 +679,7 @@
 $L$1st4x:
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	lea	r14,[32+r14]
 	adc	rdx,0
 	mov	r11,rdx
@@ -493,7 +695,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -523,7 +725,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -532,7 +734,7 @@
 	mov	rax,QWORD[16+r15*1+rsi]
 	adc	rdx,0
 	add	rdi,r11
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[r14],rdi
 	mov	r13,rdx
@@ -542,7 +744,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	lea	r14,[32+r14]
 	adc	rdx,0
 	mov	r11,rdx
@@ -558,7 +760,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -571,8 +773,7 @@
 	mov	QWORD[((-16))+r14],rdi
 	mov	r13,rdx
 
-DB	102,72,15,126,195
-	lea	rcx,[r9*2+rcx]
+	lea	rcx,[r9*1+rcx]
 
 	xor	rdi,rdi
 	add	r13,r10
@@ -583,6 +784,63 @@
 
 ALIGN	32
 $L$outer4x:
+	lea	rdx,[((16+128))+r14]
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r12]
+	movdqa	xmm1,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm0,XMMWORD[((-128))+rdx]
+	pand	xmm1,XMMWORD[((-112))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r12]
+	movdqa	xmm1,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm0,XMMWORD[((-64))+rdx]
+	pand	xmm1,XMMWORD[((-48))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r12]
+	movdqa	xmm1,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm0,XMMWORD[rdx]
+	pand	xmm1,XMMWORD[16+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r12]
+	movdqa	xmm1,XMMWORD[80+r12]
+	movdqa	xmm2,XMMWORD[96+r12]
+	movdqa	xmm3,XMMWORD[112+r12]
+	pand	xmm0,XMMWORD[64+rdx]
+	pand	xmm1,XMMWORD[80+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
+	lea	r12,[256+r12]
+DB	102,72,15,126,195
+
 	mov	r10,QWORD[r9*1+r14]
 	mov	rbp,r8
 	mul	rbx
@@ -590,25 +848,11 @@
 	mov	rax,QWORD[rcx]
 	adc	rdx,0
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-
 	imul	rbp,r10
-DB	0x67
 	mov	r11,rdx
 	mov	QWORD[r14],rdi
 
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-	por	xmm0,xmm2
 	lea	r14,[r9*1+r14]
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
 
 	mul	rbp
 	add	r10,rax
@@ -618,7 +862,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	add	r11,QWORD[8+r14]
 	adc	rdx,0
@@ -630,7 +874,7 @@
 	adc	rdx,0
 	add	rdi,r11
 	lea	r15,[32+r9]
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	r13,rdx
 	jmp	NEAR $L$inner4x
@@ -639,7 +883,7 @@
 $L$inner4x:
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	adc	rdx,0
 	add	r10,QWORD[16+r14]
 	lea	r14,[32+r14]
@@ -657,7 +901,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	add	r11,QWORD[((-8))+r14]
 	adc	rdx,0
@@ -691,7 +935,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	add	r11,QWORD[8+r14]
 	adc	rdx,0
@@ -702,7 +946,7 @@
 	mov	rax,QWORD[16+r15*1+rsi]
 	adc	rdx,0
 	add	rdi,r11
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[((-8))+r14],r13
 	mov	r13,rdx
@@ -712,7 +956,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	adc	rdx,0
 	add	r10,QWORD[16+r14]
 	lea	r14,[32+r14]
@@ -731,7 +975,7 @@
 	mul	rbx
 	add	r11,rax
 	mov	rax,rbp
-	mov	rbp,QWORD[((-16))+rcx]
+	mov	rbp,QWORD[((-8))+rcx]
 	adc	rdx,0
 	add	r11,QWORD[((-8))+r14]
 	adc	rdx,0
@@ -746,9 +990,8 @@
 	mov	QWORD[((-24))+r14],r13
 	mov	r13,rdx
 
-DB	102,72,15,126,195
 	mov	QWORD[((-16))+r14],rdi
-	lea	rcx,[r9*2+rcx]
+	lea	rcx,[r9*1+rcx]
 
 	xor	rdi,rdi
 	add	r13,r10
@@ -759,16 +1002,23 @@
 
 	cmp	r12,QWORD[((16+8))+rsp]
 	jb	NEAR $L$outer4x
+	xor	rax,rax
 	sub	rbp,r13
 	adc	r15,r15
 	or	rdi,r15
-	xor	rdi,1
+	sub	rax,rdi
 	lea	rbx,[r9*1+r14]
-	lea	rbp,[rdi*8+rcx]
+	mov	r12,QWORD[rcx]
+	lea	rbp,[rcx]
 	mov	rcx,r9
 	sar	rcx,3+2
 	mov	rdi,QWORD[((56+8))+rsp]
-	jmp	NEAR $L$sqr4x_sub
+	dec	r12
+	xor	r10,r10
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+	jmp	NEAR $L$sqr4x_sub_entry
 
 global	bn_power5
 
@@ -793,12 +1043,9 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	mov	r10d,r9d
+
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10d,[r9*2+r9]
 	neg	r9
 	mov	r8,QWORD[r8]
 
@@ -808,19 +1055,20 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$pwr_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$pwr_sp_done
 
 ALIGN	32
 $L$pwr_sp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -848,10 +1096,15 @@
 DB	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 DB	102,72,15,126,209
 DB	102,72,15,126,226
@@ -1397,9 +1650,9 @@
 	mov	QWORD[((-16))+rdi],rbx
 	mov	QWORD[((-8))+rdi],r8
 DB	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xor	rax,rax
-	lea	rcx,[r9*2+rbp]
+	lea	rcx,[rbp*1+r9]
 	lea	rdx,[((48+8))+r9*2+rsp]
 	mov	QWORD[((0+8))+rsp],rcx
 	lea	rdi,[((48+8))+r9*1+rsp]
@@ -1432,14 +1685,14 @@
 ALIGN	32
 $L$8x_reduce:
 	mul	rbx
-	mov	rax,QWORD[16+rbp]
+	mov	rax,QWORD[8+rbp]
 	neg	r8
 	mov	r8,rdx
 	adc	r8,0
 
 	mul	rbx
 	add	r9,rax
-	mov	rax,QWORD[32+rbp]
+	mov	rax,QWORD[16+rbp]
 	adc	rdx,0
 	add	r8,r9
 	mov	QWORD[((48-8+8))+rcx*8+rsp],rbx
@@ -1448,7 +1701,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[48+rbp]
+	mov	rax,QWORD[24+rbp]
 	adc	rdx,0
 	add	r9,r10
 	mov	rsi,QWORD[((32+8))+rsp]
@@ -1457,7 +1710,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[64+rbp]
+	mov	rax,QWORD[32+rbp]
 	adc	rdx,0
 	imul	rsi,r8
 	add	r10,r11
@@ -1466,7 +1719,7 @@
 
 	mul	rbx
 	add	r12,rax
-	mov	rax,QWORD[80+rbp]
+	mov	rax,QWORD[40+rbp]
 	adc	rdx,0
 	add	r11,r12
 	mov	r12,rdx
@@ -1474,7 +1727,7 @@
 
 	mul	rbx
 	add	r13,rax
-	mov	rax,QWORD[96+rbp]
+	mov	rax,QWORD[48+rbp]
 	adc	rdx,0
 	add	r12,r13
 	mov	r13,rdx
@@ -1482,7 +1735,7 @@
 
 	mul	rbx
 	add	r14,rax
-	mov	rax,QWORD[112+rbp]
+	mov	rax,QWORD[56+rbp]
 	adc	rdx,0
 	add	r13,r14
 	mov	r14,rdx
@@ -1500,7 +1753,7 @@
 	dec	ecx
 	jnz	NEAR $L$8x_reduce
 
-	lea	rbp,[128+rbp]
+	lea	rbp,[64+rbp]
 	xor	rax,rax
 	mov	rdx,QWORD[((8+8))+rsp]
 	cmp	rbp,QWORD[((0+8))+rsp]
@@ -1526,14 +1779,14 @@
 $L$8x_tail:
 	mul	rbx
 	add	r8,rax
-	mov	rax,QWORD[16+rbp]
+	mov	rax,QWORD[8+rbp]
 	mov	QWORD[rdi],r8
 	mov	r8,rdx
 	adc	r8,0
 
 	mul	rbx
 	add	r9,rax
-	mov	rax,QWORD[32+rbp]
+	mov	rax,QWORD[16+rbp]
 	adc	rdx,0
 	add	r8,r9
 	lea	rdi,[8+rdi]
@@ -1542,7 +1795,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[48+rbp]
+	mov	rax,QWORD[24+rbp]
 	adc	rdx,0
 	add	r9,r10
 	mov	r10,rdx
@@ -1550,7 +1803,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[64+rbp]
+	mov	rax,QWORD[32+rbp]
 	adc	rdx,0
 	add	r10,r11
 	mov	r11,rdx
@@ -1558,7 +1811,7 @@
 
 	mul	rbx
 	add	r12,rax
-	mov	rax,QWORD[80+rbp]
+	mov	rax,QWORD[40+rbp]
 	adc	rdx,0
 	add	r11,r12
 	mov	r12,rdx
@@ -1566,7 +1819,7 @@
 
 	mul	rbx
 	add	r13,rax
-	mov	rax,QWORD[96+rbp]
+	mov	rax,QWORD[48+rbp]
 	adc	rdx,0
 	add	r12,r13
 	mov	r13,rdx
@@ -1574,7 +1827,7 @@
 
 	mul	rbx
 	add	r14,rax
-	mov	rax,QWORD[112+rbp]
+	mov	rax,QWORD[56+rbp]
 	adc	rdx,0
 	add	r13,r14
 	mov	r14,rdx
@@ -1592,7 +1845,7 @@
 	dec	ecx
 	jnz	NEAR $L$8x_tail
 
-	lea	rbp,[128+rbp]
+	lea	rbp,[64+rbp]
 	mov	rdx,QWORD[((8+8))+rsp]
 	cmp	rbp,QWORD[((0+8))+rsp]
 	jae	NEAR $L$8x_tail_done
@@ -1638,7 +1891,7 @@
 	adc	r14,QWORD[48+rdi]
 	adc	r15,QWORD[56+rdi]
 	adc	rax,0
-	mov	rcx,QWORD[((-16))+rbp]
+	mov	rcx,QWORD[((-8))+rbp]
 	xor	rsi,rsi
 
 DB	102,72,15,126,213
@@ -1656,40 +1909,58 @@
 
 	cmp	rdi,rdx
 	jb	NEAR $L$8x_reduction_loop
+	DB	0F3h,0C3h		;repret
 
-	sub	rcx,r15
-	lea	rbx,[r9*1+rdi]
-	adc	rsi,rsi
-	mov	rcx,r9
-	or	rax,rsi
-DB	102,72,15,126,207
-	xor	rax,1
-DB	102,72,15,126,206
-	lea	rbp,[rax*8+rbp]
-	sar	rcx,3+2
-	jmp	NEAR $L$sqr4x_sub
 
 ALIGN	32
+__bn_post4x_internal:
+	mov	r12,QWORD[rbp]
+	lea	rbx,[r9*1+rdi]
+	mov	rcx,r9
+DB	102,72,15,126,207
+	neg	rax
+DB	102,72,15,126,206
+	sar	rcx,3+2
+	dec	r12
+	xor	r10,r10
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+	jmp	NEAR $L$sqr4x_sub_entry
+
+ALIGN	16
 $L$sqr4x_sub:
-DB	0x66
-	mov	r12,QWORD[rbx]
-	mov	r13,QWORD[8+rbx]
-	sbb	r12,QWORD[rbp]
-	mov	r14,QWORD[16+rbx]
-	sbb	r13,QWORD[16+rbp]
-	mov	r15,QWORD[24+rbx]
-	lea	rbx,[32+rbx]
-	sbb	r14,QWORD[32+rbp]
+	mov	r12,QWORD[rbp]
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+$L$sqr4x_sub_entry:
+	lea	rbp,[32+rbp]
+	not	r12
+	not	r13
+	not	r14
+	not	r15
+	and	r12,rax
+	and	r13,rax
+	and	r14,rax
+	and	r15,rax
+
+	neg	r10
+	adc	r12,QWORD[rbx]
+	adc	r13,QWORD[8+rbx]
+	adc	r14,QWORD[16+rbx]
+	adc	r15,QWORD[24+rbx]
 	mov	QWORD[rdi],r12
-	sbb	r15,QWORD[48+rbp]
-	lea	rbp,[64+rbp]
+	lea	rbx,[32+rbx]
 	mov	QWORD[8+rdi],r13
+	sbb	r10,r10
 	mov	QWORD[16+rdi],r14
 	mov	QWORD[24+rdi],r15
 	lea	rdi,[32+rdi]
 
 	inc	rcx
 	jnz	NEAR $L$sqr4x_sub
+
 	mov	r10,r9
 	neg	r9
 	DB	0F3h,0C3h		;repret
@@ -1727,13 +1998,9 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-DB	0x67
-	mov	r10d,r9d
+
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10,[r9*2+r9]
 	neg	r9
 	mov	r8,QWORD[r8]
 
@@ -1743,19 +2010,20 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$from_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$from_sp_done
 
 ALIGN	32
 $L$from_sp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -1806,7 +2074,8 @@
 DB	0x67
 	mov	rbp,rcx
 DB	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	xmm0,xmm0
 	lea	rax,[48+rsp]
@@ -1856,55 +2125,171 @@
 
 global	bn_gather5
 
-ALIGN	16
+ALIGN	32
 bn_gather5:
 $L$SEH_begin_bn_gather5:
 
-DB	0x48,0x83,0xec,0x28
-DB	0x0f,0x29,0x34,0x24
-DB	0x0f,0x29,0x7c,0x24,0x10
-	mov	r11d,r9d
-	shr	r9d,3
-	and	r11,7
-	not	r9d
-	lea	rax,[$L$magic_masks]
-	and	r9d,3
-	lea	r8,[128+r11*8+r8]
-	movq	xmm4,QWORD[r9*8+rax]
-	movq	xmm5,QWORD[8+r9*8+rax]
-	movq	xmm6,QWORD[16+r9*8+rax]
-	movq	xmm7,QWORD[24+r9*8+rax]
-	jmp	NEAR $L$gather
-ALIGN	16
-$L$gather:
-	movq	xmm0,QWORD[(((-128)))+r8]
-	movq	xmm1,QWORD[((-64))+r8]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[r8]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[64+r8]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-DB	0x67,0x67
-	por	xmm0,xmm2
-	lea	r8,[256+r8]
-	por	xmm0,xmm3
+DB	0x4c,0x8d,0x14,0x24
+DB	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	lea	rax,[$L$inc]
+	and	rsp,-16
 
+	movd	xmm5,r9d
+	movdqa	xmm0,XMMWORD[rax]
+	movdqa	xmm1,XMMWORD[16+rax]
+	lea	r11,[128+r8]
+	lea	rax,[128+rsp]
+
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[(-128)+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[(-112)+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[(-96)+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[(-80)+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[(-64)+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[(-48)+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[(-32)+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[(-16)+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[16+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[32+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[48+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[64+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[80+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[96+rax],xmm2
+	movdqa	xmm2,xmm4
+	movdqa	XMMWORD[112+rax],xmm3
+	jmp	NEAR $L$gather
+
+ALIGN	32
+$L$gather:
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r11]
+	movdqa	xmm1,XMMWORD[((-112))+r11]
+	movdqa	xmm2,XMMWORD[((-96))+r11]
+	pand	xmm0,XMMWORD[((-128))+rax]
+	movdqa	xmm3,XMMWORD[((-80))+r11]
+	pand	xmm1,XMMWORD[((-112))+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r11]
+	movdqa	xmm1,XMMWORD[((-48))+r11]
+	movdqa	xmm2,XMMWORD[((-32))+r11]
+	pand	xmm0,XMMWORD[((-64))+rax]
+	movdqa	xmm3,XMMWORD[((-16))+r11]
+	pand	xmm1,XMMWORD[((-48))+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r11]
+	movdqa	xmm1,XMMWORD[16+r11]
+	movdqa	xmm2,XMMWORD[32+r11]
+	pand	xmm0,XMMWORD[rax]
+	movdqa	xmm3,XMMWORD[48+r11]
+	pand	xmm1,XMMWORD[16+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r11]
+	movdqa	xmm1,XMMWORD[80+r11]
+	movdqa	xmm2,XMMWORD[96+r11]
+	pand	xmm0,XMMWORD[64+rax]
+	movdqa	xmm3,XMMWORD[112+r11]
+	pand	xmm1,XMMWORD[80+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	lea	r11,[256+r11]
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
 	movq	QWORD[rcx],xmm0
 	lea	rcx,[8+rcx]
 	sub	edx,1
 	jnz	NEAR $L$gather
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	xmm7,XMMWORD[16+rsp]
-	lea	rsp,[40+rsp]
+
+	lea	rsp,[r10]
 	DB	0F3h,0C3h		;repret
 $L$SEH_end_bn_gather5:
 
 ALIGN	64
-$L$magic_masks:
-	DD	0,0,0,0,0,0,-1,-1
-	DD	0,0,0,0,0,0,0,0
+$L$inc:
+	DD	0,0,1,1
+	DD	2,2,2,2
 DB	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
 DB	112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115
 DB	99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111
@@ -1946,19 +2331,16 @@
 
 	lea	r10,[$L$mul_epilogue]
 	cmp	rbx,r10
-	jb	NEAR $L$body_40
+	ja	NEAR $L$body_40
 
 	mov	r10,QWORD[192+r8]
 	mov	rax,QWORD[8+r10*8+rax]
+
 	jmp	NEAR $L$body_proceed
 
 $L$body_40:
 	mov	rax,QWORD[40+rax]
 $L$body_proceed:
-
-	movaps	xmm0,XMMWORD[((-88))+rax]
-	movaps	xmm1,XMMWORD[((-72))+rax]
-
 	mov	rbx,QWORD[((-8))+rax]
 	mov	rbp,QWORD[((-16))+rax]
 	mov	r12,QWORD[((-24))+rax]
@@ -1971,8 +2353,6 @@
 	mov	QWORD[224+r8],r13
 	mov	QWORD[232+r8],r14
 	mov	QWORD[240+r8],r15
-	movups	XMMWORD[512+r8],xmm0
-	movups	XMMWORD[528+r8],xmm1
 
 $L$common_seh_tail:
 	mov	rdi,QWORD[8+rax]
@@ -2058,8 +2438,7 @@
 	DD	$L$from_body wrt ..imagebase,$L$from_epilogue wrt ..imagebase
 ALIGN	8
 $L$SEH_info_bn_gather5:
-DB	0x01,0x0d,0x05,0x00
-DB	0x0d,0x78,0x01,0x00
-DB	0x08,0x68,0x00,0x00
-DB	0x04,0x42,0x00,0x00
+DB	0x01,0x0b,0x03,0x0a
+DB	0x0b,0x01,0x21,0x00
+DB	0x04,0xa3,0x00,0x00
 ALIGN	8
diff --git a/win-x86_64/crypto/chacha/chacha-x86_64.asm b/win-x86_64/crypto/chacha/chacha-x86_64.asm
new file mode 100644
index 0000000..0ecbe95
--- /dev/null
+++ b/win-x86_64/crypto/chacha/chacha-x86_64.asm
@@ -0,0 +1,1689 @@
+default	rel
+%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
+section	.text code align=64
+
+
+EXTERN	OPENSSL_ia32cap_P
+
+ALIGN	64
+$L$zero:
+	DD	0,0,0,0
+$L$one:
+	DD	1,0,0,0
+$L$inc:
+	DD	0,1,2,3
+$L$four:
+	DD	4,4,4,4
+$L$incy:
+	DD	0,2,4,6,1,3,5,7
+$L$eight:
+	DD	8,8,8,8,8,8,8,8
+$L$rot16:
+DB	0x2,0x3,0x0,0x1,0x6,0x7,0x4,0x5,0xa,0xb,0x8,0x9,0xe,0xf,0xc,0xd
+$L$rot24:
+DB	0x3,0x0,0x1,0x2,0x7,0x4,0x5,0x6,0xb,0x8,0x9,0xa,0xf,0xc,0xd,0xe
+$L$sigma:
+DB	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107
+DB	0
+DB	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+DB	95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32
+DB	98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115
+DB	108,46,111,114,103,62,0
+global	ChaCha20_ctr32
+
+ALIGN	64
+ChaCha20_ctr32:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_ctr32:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+	cmp	rdx,0
+	je	NEAR $L$no_data
+	mov	r10,QWORD[((OPENSSL_ia32cap_P+4))]
+	test	r10d,512
+	jnz	NEAR $L$ChaCha20_ssse3
+
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	sub	rsp,64+24
+
+
+	movdqu	xmm1,XMMWORD[rcx]
+	movdqu	xmm2,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	movdqa	xmm4,XMMWORD[$L$one]
+
+
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	mov	rbp,rdx
+	jmp	NEAR $L$oop_outer
+
+ALIGN	32
+$L$oop_outer:
+	mov	eax,0x61707865
+	mov	ebx,0x3320646e
+	mov	ecx,0x79622d32
+	mov	edx,0x6b206574
+	mov	r8d,DWORD[16+rsp]
+	mov	r9d,DWORD[20+rsp]
+	mov	r10d,DWORD[24+rsp]
+	mov	r11d,DWORD[28+rsp]
+	movd	r12d,xmm3
+	mov	r13d,DWORD[52+rsp]
+	mov	r14d,DWORD[56+rsp]
+	mov	r15d,DWORD[60+rsp]
+
+	mov	QWORD[((64+0))+rsp],rbp
+	mov	ebp,10
+	mov	QWORD[((64+8))+rsp],rsi
+DB	102,72,15,126,214
+	mov	QWORD[((64+16))+rsp],rdi
+	mov	rdi,rsi
+	shr	rdi,32
+	jmp	NEAR $L$oop
+
+ALIGN	32
+$L$oop:
+	add	eax,r8d
+	xor	r12d,eax
+	rol	r12d,16
+	add	ebx,r9d
+	xor	r13d,ebx
+	rol	r13d,16
+	add	esi,r12d
+	xor	r8d,esi
+	rol	r8d,12
+	add	edi,r13d
+	xor	r9d,edi
+	rol	r9d,12
+	add	eax,r8d
+	xor	r12d,eax
+	rol	r12d,8
+	add	ebx,r9d
+	xor	r13d,ebx
+	rol	r13d,8
+	add	esi,r12d
+	xor	r8d,esi
+	rol	r8d,7
+	add	edi,r13d
+	xor	r9d,edi
+	rol	r9d,7
+	mov	DWORD[32+rsp],esi
+	mov	DWORD[36+rsp],edi
+	mov	esi,DWORD[40+rsp]
+	mov	edi,DWORD[44+rsp]
+	add	ecx,r10d
+	xor	r14d,ecx
+	rol	r14d,16
+	add	edx,r11d
+	xor	r15d,edx
+	rol	r15d,16
+	add	esi,r14d
+	xor	r10d,esi
+	rol	r10d,12
+	add	edi,r15d
+	xor	r11d,edi
+	rol	r11d,12
+	add	ecx,r10d
+	xor	r14d,ecx
+	rol	r14d,8
+	add	edx,r11d
+	xor	r15d,edx
+	rol	r15d,8
+	add	esi,r14d
+	xor	r10d,esi
+	rol	r10d,7
+	add	edi,r15d
+	xor	r11d,edi
+	rol	r11d,7
+	add	eax,r9d
+	xor	r15d,eax
+	rol	r15d,16
+	add	ebx,r10d
+	xor	r12d,ebx
+	rol	r12d,16
+	add	esi,r15d
+	xor	r9d,esi
+	rol	r9d,12
+	add	edi,r12d
+	xor	r10d,edi
+	rol	r10d,12
+	add	eax,r9d
+	xor	r15d,eax
+	rol	r15d,8
+	add	ebx,r10d
+	xor	r12d,ebx
+	rol	r12d,8
+	add	esi,r15d
+	xor	r9d,esi
+	rol	r9d,7
+	add	edi,r12d
+	xor	r10d,edi
+	rol	r10d,7
+	mov	DWORD[40+rsp],esi
+	mov	DWORD[44+rsp],edi
+	mov	esi,DWORD[32+rsp]
+	mov	edi,DWORD[36+rsp]
+	add	ecx,r11d
+	xor	r13d,ecx
+	rol	r13d,16
+	add	edx,r8d
+	xor	r14d,edx
+	rol	r14d,16
+	add	esi,r13d
+	xor	r11d,esi
+	rol	r11d,12
+	add	edi,r14d
+	xor	r8d,edi
+	rol	r8d,12
+	add	ecx,r11d
+	xor	r13d,ecx
+	rol	r13d,8
+	add	edx,r8d
+	xor	r14d,edx
+	rol	r14d,8
+	add	esi,r13d
+	xor	r11d,esi
+	rol	r11d,7
+	add	edi,r14d
+	xor	r8d,edi
+	rol	r8d,7
+	dec	ebp
+	jnz	NEAR $L$oop
+	mov	DWORD[36+rsp],edi
+	mov	DWORD[32+rsp],esi
+	mov	rbp,QWORD[64+rsp]
+	movdqa	xmm1,xmm2
+	mov	rsi,QWORD[((64+8))+rsp]
+	paddd	xmm3,xmm4
+	mov	rdi,QWORD[((64+16))+rsp]
+
+	add	eax,0x61707865
+	add	ebx,0x3320646e
+	add	ecx,0x79622d32
+	add	edx,0x6b206574
+	add	r8d,DWORD[16+rsp]
+	add	r9d,DWORD[20+rsp]
+	add	r10d,DWORD[24+rsp]
+	add	r11d,DWORD[28+rsp]
+	add	r12d,DWORD[48+rsp]
+	add	r13d,DWORD[52+rsp]
+	add	r14d,DWORD[56+rsp]
+	add	r15d,DWORD[60+rsp]
+	paddd	xmm1,XMMWORD[32+rsp]
+
+	cmp	rbp,64
+	jb	NEAR $L$tail
+
+	xor	eax,DWORD[rsi]
+	xor	ebx,DWORD[4+rsi]
+	xor	ecx,DWORD[8+rsi]
+	xor	edx,DWORD[12+rsi]
+	xor	r8d,DWORD[16+rsi]
+	xor	r9d,DWORD[20+rsi]
+	xor	r10d,DWORD[24+rsi]
+	xor	r11d,DWORD[28+rsi]
+	movdqu	xmm0,XMMWORD[32+rsi]
+	xor	r12d,DWORD[48+rsi]
+	xor	r13d,DWORD[52+rsi]
+	xor	r14d,DWORD[56+rsi]
+	xor	r15d,DWORD[60+rsi]
+	lea	rsi,[64+rsi]
+	pxor	xmm0,xmm1
+
+	movdqa	XMMWORD[32+rsp],xmm2
+	movd	DWORD[48+rsp],xmm3
+
+	mov	DWORD[rdi],eax
+	mov	DWORD[4+rdi],ebx
+	mov	DWORD[8+rdi],ecx
+	mov	DWORD[12+rdi],edx
+	mov	DWORD[16+rdi],r8d
+	mov	DWORD[20+rdi],r9d
+	mov	DWORD[24+rdi],r10d
+	mov	DWORD[28+rdi],r11d
+	movdqu	XMMWORD[32+rdi],xmm0
+	mov	DWORD[48+rdi],r12d
+	mov	DWORD[52+rdi],r13d
+	mov	DWORD[56+rdi],r14d
+	mov	DWORD[60+rdi],r15d
+	lea	rdi,[64+rdi]
+
+	sub	rbp,64
+	jnz	NEAR $L$oop_outer
+
+	jmp	NEAR $L$done
+
+ALIGN	16
+$L$tail:
+	mov	DWORD[rsp],eax
+	mov	DWORD[4+rsp],ebx
+	xor	rbx,rbx
+	mov	DWORD[8+rsp],ecx
+	mov	DWORD[12+rsp],edx
+	mov	DWORD[16+rsp],r8d
+	mov	DWORD[20+rsp],r9d
+	mov	DWORD[24+rsp],r10d
+	mov	DWORD[28+rsp],r11d
+	movdqa	XMMWORD[32+rsp],xmm1
+	mov	DWORD[48+rsp],r12d
+	mov	DWORD[52+rsp],r13d
+	mov	DWORD[56+rsp],r14d
+	mov	DWORD[60+rsp],r15d
+
+$L$oop_tail:
+	movzx	eax,BYTE[rbx*1+rsi]
+	movzx	edx,BYTE[rbx*1+rsp]
+	lea	rbx,[1+rbx]
+	xor	eax,edx
+	mov	BYTE[((-1))+rbx*1+rdi],al
+	dec	rbp
+	jnz	NEAR $L$oop_tail
+
+$L$done:
+	add	rsp,64+24
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbp
+	pop	rbx
+$L$no_data:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_ctr32:
+
+ALIGN	32
+ChaCha20_ssse3:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_ssse3:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_ssse3:
+	cmp	rdx,128
+	ja	NEAR $L$ChaCha20_4x
+
+$L$do_sse3_after_all:
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+
+	sub	rsp,64+72
+	movaps	XMMWORD[(64+32)+rsp],xmm6
+	movaps	XMMWORD[(64+48)+rsp],xmm7
+	movdqa	xmm0,XMMWORD[$L$sigma]
+	movdqu	xmm1,XMMWORD[rcx]
+	movdqu	xmm2,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	movdqa	xmm6,XMMWORD[$L$rot16]
+	movdqa	xmm7,XMMWORD[$L$rot24]
+
+	movdqa	XMMWORD[rsp],xmm0
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	mov	ebp,10
+	jmp	NEAR $L$oop_ssse3
+
+ALIGN	32
+$L$oop_outer_ssse3:
+	movdqa	xmm3,XMMWORD[$L$one]
+	movdqa	xmm0,XMMWORD[rsp]
+	movdqa	xmm1,XMMWORD[16+rsp]
+	movdqa	xmm2,XMMWORD[32+rsp]
+	paddd	xmm3,XMMWORD[48+rsp]
+	mov	ebp,10
+	movdqa	XMMWORD[48+rsp],xmm3
+	jmp	NEAR $L$oop_ssse3
+
+ALIGN	32
+$L$oop_ssse3:
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,57
+	pshufd	xmm3,xmm3,147
+	nop
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,147
+	pshufd	xmm3,xmm3,57
+	dec	ebp
+	jnz	NEAR $L$oop_ssse3
+	paddd	xmm0,XMMWORD[rsp]
+	paddd	xmm1,XMMWORD[16+rsp]
+	paddd	xmm2,XMMWORD[32+rsp]
+	paddd	xmm3,XMMWORD[48+rsp]
+
+	cmp	rdx,64
+	jb	NEAR $L$tail_ssse3
+
+	movdqu	xmm4,XMMWORD[rsi]
+	movdqu	xmm5,XMMWORD[16+rsi]
+	pxor	xmm0,xmm4
+	movdqu	xmm4,XMMWORD[32+rsi]
+	pxor	xmm1,xmm5
+	movdqu	xmm5,XMMWORD[48+rsi]
+	lea	rsi,[64+rsi]
+	pxor	xmm2,xmm4
+	pxor	xmm3,xmm5
+
+	movdqu	XMMWORD[rdi],xmm0
+	movdqu	XMMWORD[16+rdi],xmm1
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm3
+	lea	rdi,[64+rdi]
+
+	sub	rdx,64
+	jnz	NEAR $L$oop_outer_ssse3
+
+	jmp	NEAR $L$done_ssse3
+
+ALIGN	16
+$L$tail_ssse3:
+	movdqa	XMMWORD[rsp],xmm0
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	xor	rbx,rbx
+
+$L$oop_tail_ssse3:
+	movzx	eax,BYTE[rbx*1+rsi]
+	movzx	ecx,BYTE[rbx*1+rsp]
+	lea	rbx,[1+rbx]
+	xor	eax,ecx
+	mov	BYTE[((-1))+rbx*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail_ssse3
+
+$L$done_ssse3:
+	movaps	xmm6,XMMWORD[((64+32))+rsp]
+	movaps	xmm7,XMMWORD[((64+48))+rsp]
+	add	rsp,64+72
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbp
+	pop	rbx
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_ssse3:
+
+ALIGN	32
+ChaCha20_4x:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_4x:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_4x:
+	mov	r11,r10
+	shr	r10,32
+	test	r10,32
+	jnz	NEAR $L$ChaCha20_8x
+	cmp	rdx,192
+	ja	NEAR $L$proceed4x
+
+	and	r11,71303168
+	cmp	r11,4194304
+	je	NEAR $L$do_sse3_after_all
+
+$L$proceed4x:
+	lea	r11,[((-120))+rsp]
+	sub	rsp,0x148+160
+	movaps	XMMWORD[(-48)+r11],xmm6
+	movaps	XMMWORD[(-32)+r11],xmm7
+	movaps	XMMWORD[(-16)+r11],xmm8
+	movaps	XMMWORD[r11],xmm9
+	movaps	XMMWORD[16+r11],xmm10
+	movaps	XMMWORD[32+r11],xmm11
+	movaps	XMMWORD[48+r11],xmm12
+	movaps	XMMWORD[64+r11],xmm13
+	movaps	XMMWORD[80+r11],xmm14
+	movaps	XMMWORD[96+r11],xmm15
+	movdqa	xmm11,XMMWORD[$L$sigma]
+	movdqu	xmm15,XMMWORD[rcx]
+	movdqu	xmm7,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	lea	rcx,[256+rsp]
+	lea	r10,[$L$rot16]
+	lea	r11,[$L$rot24]
+
+	pshufd	xmm8,xmm11,0x00
+	pshufd	xmm9,xmm11,0x55
+	movdqa	XMMWORD[64+rsp],xmm8
+	pshufd	xmm10,xmm11,0xaa
+	movdqa	XMMWORD[80+rsp],xmm9
+	pshufd	xmm11,xmm11,0xff
+	movdqa	XMMWORD[96+rsp],xmm10
+	movdqa	XMMWORD[112+rsp],xmm11
+
+	pshufd	xmm12,xmm15,0x00
+	pshufd	xmm13,xmm15,0x55
+	movdqa	XMMWORD[(128-256)+rcx],xmm12
+	pshufd	xmm14,xmm15,0xaa
+	movdqa	XMMWORD[(144-256)+rcx],xmm13
+	pshufd	xmm15,xmm15,0xff
+	movdqa	XMMWORD[(160-256)+rcx],xmm14
+	movdqa	XMMWORD[(176-256)+rcx],xmm15
+
+	pshufd	xmm4,xmm7,0x00
+	pshufd	xmm5,xmm7,0x55
+	movdqa	XMMWORD[(192-256)+rcx],xmm4
+	pshufd	xmm6,xmm7,0xaa
+	movdqa	XMMWORD[(208-256)+rcx],xmm5
+	pshufd	xmm7,xmm7,0xff
+	movdqa	XMMWORD[(224-256)+rcx],xmm6
+	movdqa	XMMWORD[(240-256)+rcx],xmm7
+
+	pshufd	xmm0,xmm3,0x00
+	pshufd	xmm1,xmm3,0x55
+	paddd	xmm0,XMMWORD[$L$inc]
+	pshufd	xmm2,xmm3,0xaa
+	movdqa	XMMWORD[(272-256)+rcx],xmm1
+	pshufd	xmm3,xmm3,0xff
+	movdqa	XMMWORD[(288-256)+rcx],xmm2
+	movdqa	XMMWORD[(304-256)+rcx],xmm3
+
+	jmp	NEAR $L$oop_enter4x
+
+ALIGN	32
+$L$oop_outer4x:
+	movdqa	xmm8,XMMWORD[64+rsp]
+	movdqa	xmm9,XMMWORD[80+rsp]
+	movdqa	xmm10,XMMWORD[96+rsp]
+	movdqa	xmm11,XMMWORD[112+rsp]
+	movdqa	xmm12,XMMWORD[((128-256))+rcx]
+	movdqa	xmm13,XMMWORD[((144-256))+rcx]
+	movdqa	xmm14,XMMWORD[((160-256))+rcx]
+	movdqa	xmm15,XMMWORD[((176-256))+rcx]
+	movdqa	xmm4,XMMWORD[((192-256))+rcx]
+	movdqa	xmm5,XMMWORD[((208-256))+rcx]
+	movdqa	xmm6,XMMWORD[((224-256))+rcx]
+	movdqa	xmm7,XMMWORD[((240-256))+rcx]
+	movdqa	xmm0,XMMWORD[((256-256))+rcx]
+	movdqa	xmm1,XMMWORD[((272-256))+rcx]
+	movdqa	xmm2,XMMWORD[((288-256))+rcx]
+	movdqa	xmm3,XMMWORD[((304-256))+rcx]
+	paddd	xmm0,XMMWORD[$L$four]
+
+$L$oop_enter4x:
+	movdqa	XMMWORD[32+rsp],xmm6
+	movdqa	XMMWORD[48+rsp],xmm7
+	movdqa	xmm7,XMMWORD[r10]
+	mov	eax,10
+	movdqa	XMMWORD[(256-256)+rcx],xmm0
+	jmp	NEAR $L$oop4x
+
+ALIGN	32
+$L$oop4x:
+	paddd	xmm8,xmm12
+	paddd	xmm9,xmm13
+	pxor	xmm0,xmm8
+	pxor	xmm1,xmm9
+DB	102,15,56,0,199
+DB	102,15,56,0,207
+	paddd	xmm4,xmm0
+	paddd	xmm5,xmm1
+	pxor	xmm12,xmm4
+	pxor	xmm13,xmm5
+	movdqa	xmm6,xmm12
+	pslld	xmm12,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm13
+	pslld	xmm13,12
+	por	xmm12,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm13,xmm7
+	paddd	xmm8,xmm12
+	paddd	xmm9,xmm13
+	pxor	xmm0,xmm8
+	pxor	xmm1,xmm9
+DB	102,15,56,0,198
+DB	102,15,56,0,206
+	paddd	xmm4,xmm0
+	paddd	xmm5,xmm1
+	pxor	xmm12,xmm4
+	pxor	xmm13,xmm5
+	movdqa	xmm7,xmm12
+	pslld	xmm12,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm13
+	pslld	xmm13,7
+	por	xmm12,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm13,xmm6
+	movdqa	XMMWORD[rsp],xmm4
+	movdqa	XMMWORD[16+rsp],xmm5
+	movdqa	xmm4,XMMWORD[32+rsp]
+	movdqa	xmm5,XMMWORD[48+rsp]
+	paddd	xmm10,xmm14
+	paddd	xmm11,xmm15
+	pxor	xmm2,xmm10
+	pxor	xmm3,xmm11
+DB	102,15,56,0,215
+DB	102,15,56,0,223
+	paddd	xmm4,xmm2
+	paddd	xmm5,xmm3
+	pxor	xmm14,xmm4
+	pxor	xmm15,xmm5
+	movdqa	xmm6,xmm14
+	pslld	xmm14,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm15
+	pslld	xmm15,12
+	por	xmm14,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm15,xmm7
+	paddd	xmm10,xmm14
+	paddd	xmm11,xmm15
+	pxor	xmm2,xmm10
+	pxor	xmm3,xmm11
+DB	102,15,56,0,214
+DB	102,15,56,0,222
+	paddd	xmm4,xmm2
+	paddd	xmm5,xmm3
+	pxor	xmm14,xmm4
+	pxor	xmm15,xmm5
+	movdqa	xmm7,xmm14
+	pslld	xmm14,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm15
+	pslld	xmm15,7
+	por	xmm14,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm15,xmm6
+	paddd	xmm8,xmm13
+	paddd	xmm9,xmm14
+	pxor	xmm3,xmm8
+	pxor	xmm0,xmm9
+DB	102,15,56,0,223
+DB	102,15,56,0,199
+	paddd	xmm4,xmm3
+	paddd	xmm5,xmm0
+	pxor	xmm13,xmm4
+	pxor	xmm14,xmm5
+	movdqa	xmm6,xmm13
+	pslld	xmm13,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm14
+	pslld	xmm14,12
+	por	xmm13,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm14,xmm7
+	paddd	xmm8,xmm13
+	paddd	xmm9,xmm14
+	pxor	xmm3,xmm8
+	pxor	xmm0,xmm9
+DB	102,15,56,0,222
+DB	102,15,56,0,198
+	paddd	xmm4,xmm3
+	paddd	xmm5,xmm0
+	pxor	xmm13,xmm4
+	pxor	xmm14,xmm5
+	movdqa	xmm7,xmm13
+	pslld	xmm13,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm14
+	pslld	xmm14,7
+	por	xmm13,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm14,xmm6
+	movdqa	XMMWORD[32+rsp],xmm4
+	movdqa	XMMWORD[48+rsp],xmm5
+	movdqa	xmm4,XMMWORD[rsp]
+	movdqa	xmm5,XMMWORD[16+rsp]
+	paddd	xmm10,xmm15
+	paddd	xmm11,xmm12
+	pxor	xmm1,xmm10
+	pxor	xmm2,xmm11
+DB	102,15,56,0,207
+DB	102,15,56,0,215
+	paddd	xmm4,xmm1
+	paddd	xmm5,xmm2
+	pxor	xmm15,xmm4
+	pxor	xmm12,xmm5
+	movdqa	xmm6,xmm15
+	pslld	xmm15,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm12
+	pslld	xmm12,12
+	por	xmm15,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm12,xmm7
+	paddd	xmm10,xmm15
+	paddd	xmm11,xmm12
+	pxor	xmm1,xmm10
+	pxor	xmm2,xmm11
+DB	102,15,56,0,206
+DB	102,15,56,0,214
+	paddd	xmm4,xmm1
+	paddd	xmm5,xmm2
+	pxor	xmm15,xmm4
+	pxor	xmm12,xmm5
+	movdqa	xmm7,xmm15
+	pslld	xmm15,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm12
+	pslld	xmm12,7
+	por	xmm15,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm12,xmm6
+	dec	eax
+	jnz	NEAR $L$oop4x
+
+	paddd	xmm8,XMMWORD[64+rsp]
+	paddd	xmm9,XMMWORD[80+rsp]
+	paddd	xmm10,XMMWORD[96+rsp]
+	paddd	xmm11,XMMWORD[112+rsp]
+
+	movdqa	xmm6,xmm8
+	punpckldq	xmm8,xmm9
+	movdqa	xmm7,xmm10
+	punpckldq	xmm10,xmm11
+	punpckhdq	xmm6,xmm9
+	punpckhdq	xmm7,xmm11
+	movdqa	xmm9,xmm8
+	punpcklqdq	xmm8,xmm10
+	movdqa	xmm11,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm9,xmm10
+	punpckhqdq	xmm11,xmm7
+	paddd	xmm12,XMMWORD[((128-256))+rcx]
+	paddd	xmm13,XMMWORD[((144-256))+rcx]
+	paddd	xmm14,XMMWORD[((160-256))+rcx]
+	paddd	xmm15,XMMWORD[((176-256))+rcx]
+
+	movdqa	XMMWORD[rsp],xmm8
+	movdqa	XMMWORD[16+rsp],xmm9
+	movdqa	xmm8,XMMWORD[32+rsp]
+	movdqa	xmm9,XMMWORD[48+rsp]
+
+	movdqa	xmm10,xmm12
+	punpckldq	xmm12,xmm13
+	movdqa	xmm7,xmm14
+	punpckldq	xmm14,xmm15
+	punpckhdq	xmm10,xmm13
+	punpckhdq	xmm7,xmm15
+	movdqa	xmm13,xmm12
+	punpcklqdq	xmm12,xmm14
+	movdqa	xmm15,xmm10
+	punpcklqdq	xmm10,xmm7
+	punpckhqdq	xmm13,xmm14
+	punpckhqdq	xmm15,xmm7
+	paddd	xmm4,XMMWORD[((192-256))+rcx]
+	paddd	xmm5,XMMWORD[((208-256))+rcx]
+	paddd	xmm8,XMMWORD[((224-256))+rcx]
+	paddd	xmm9,XMMWORD[((240-256))+rcx]
+
+	movdqa	XMMWORD[32+rsp],xmm6
+	movdqa	XMMWORD[48+rsp],xmm11
+
+	movdqa	xmm14,xmm4
+	punpckldq	xmm4,xmm5
+	movdqa	xmm7,xmm8
+	punpckldq	xmm8,xmm9
+	punpckhdq	xmm14,xmm5
+	punpckhdq	xmm7,xmm9
+	movdqa	xmm5,xmm4
+	punpcklqdq	xmm4,xmm8
+	movdqa	xmm9,xmm14
+	punpcklqdq	xmm14,xmm7
+	punpckhqdq	xmm5,xmm8
+	punpckhqdq	xmm9,xmm7
+	paddd	xmm0,XMMWORD[((256-256))+rcx]
+	paddd	xmm1,XMMWORD[((272-256))+rcx]
+	paddd	xmm2,XMMWORD[((288-256))+rcx]
+	paddd	xmm3,XMMWORD[((304-256))+rcx]
+
+	movdqa	xmm8,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm8,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm8
+	punpcklqdq	xmm8,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	cmp	rdx,64*4
+	jb	NEAR $L$tail4x
+
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[32+rsp]
+	pxor	xmm11,xmm10
+	pxor	xmm2,xmm14
+	pxor	xmm7,xmm8
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[48+rsp]
+	pxor	xmm11,xmm15
+	pxor	xmm2,xmm9
+	pxor	xmm7,xmm3
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+
+	sub	rdx,64*4
+	jnz	NEAR $L$oop_outer4x
+
+	jmp	NEAR $L$done4x
+
+$L$tail4x:
+	cmp	rdx,192
+	jae	NEAR $L$192_or_more4x
+	cmp	rdx,128
+	jae	NEAR $L$128_or_more4x
+	cmp	rdx,64
+	jae	NEAR $L$64_or_more4x
+
+
+	xor	r10,r10
+
+	movdqa	XMMWORD[16+rsp],xmm12
+	movdqa	XMMWORD[32+rsp],xmm4
+	movdqa	XMMWORD[48+rsp],xmm0
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$64_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[16+rsp]
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm13
+	lea	rdi,[64+rdi]
+	movdqa	XMMWORD[32+rsp],xmm5
+	sub	rdx,64
+	movdqa	XMMWORD[48+rsp],xmm1
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$128_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	XMMWORD[112+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[32+rsp]
+	lea	rsi,[128+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm10
+	lea	rdi,[128+rdi]
+	movdqa	XMMWORD[32+rsp],xmm14
+	sub	rdx,128
+	movdqa	XMMWORD[48+rsp],xmm8
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$192_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[32+rsp]
+	pxor	xmm11,xmm10
+	pxor	xmm2,xmm14
+	pxor	xmm7,xmm8
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[48+rsp]
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm15
+	lea	rdi,[64+rdi]
+	movdqa	XMMWORD[32+rsp],xmm9
+	sub	rdx,192
+	movdqa	XMMWORD[48+rsp],xmm3
+
+$L$oop_tail4x:
+	movzx	eax,BYTE[r10*1+rsi]
+	movzx	ecx,BYTE[r10*1+rsp]
+	lea	r10,[1+r10]
+	xor	eax,ecx
+	mov	BYTE[((-1))+r10*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail4x
+
+$L$done4x:
+	lea	r11,[((320+48))+rsp]
+	movaps	xmm6,XMMWORD[((-48))+r11]
+	movaps	xmm7,XMMWORD[((-32))+r11]
+	movaps	xmm8,XMMWORD[((-16))+r11]
+	movaps	xmm9,XMMWORD[r11]
+	movaps	xmm10,XMMWORD[16+r11]
+	movaps	xmm11,XMMWORD[32+r11]
+	movaps	xmm12,XMMWORD[48+r11]
+	movaps	xmm13,XMMWORD[64+r11]
+	movaps	xmm14,XMMWORD[80+r11]
+	movaps	xmm15,XMMWORD[96+r11]
+	add	rsp,0x148+160
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_4x:
+
+ALIGN	32
+ChaCha20_8x:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_8x:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_8x:
+	mov	r10,rsp
+	sub	rsp,0x280+176
+	and	rsp,-32
+	lea	r11,[((656+48))+rsp]
+	movaps	XMMWORD[(-48)+r11],xmm6
+	movaps	XMMWORD[(-32)+r11],xmm7
+	movaps	XMMWORD[(-16)+r11],xmm8
+	movaps	XMMWORD[r11],xmm9
+	movaps	XMMWORD[16+r11],xmm10
+	movaps	XMMWORD[32+r11],xmm11
+	movaps	XMMWORD[48+r11],xmm12
+	movaps	XMMWORD[64+r11],xmm13
+	movaps	XMMWORD[80+r11],xmm14
+	movaps	XMMWORD[96+r11],xmm15
+	vzeroupper
+	mov	QWORD[640+rsp],r10
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	ymm11,YMMWORD[$L$sigma]
+	vbroadcasti128	ymm3,YMMWORD[rcx]
+	vbroadcasti128	ymm15,YMMWORD[16+rcx]
+	vbroadcasti128	ymm7,YMMWORD[r8]
+	lea	rcx,[256+rsp]
+	lea	rax,[512+rsp]
+	lea	r10,[$L$rot16]
+	lea	r11,[$L$rot24]
+
+	vpshufd	ymm8,ymm11,0x00
+	vpshufd	ymm9,ymm11,0x55
+	vmovdqa	YMMWORD[(128-256)+rcx],ymm8
+	vpshufd	ymm10,ymm11,0xaa
+	vmovdqa	YMMWORD[(160-256)+rcx],ymm9
+	vpshufd	ymm11,ymm11,0xff
+	vmovdqa	YMMWORD[(192-256)+rcx],ymm10
+	vmovdqa	YMMWORD[(224-256)+rcx],ymm11
+
+	vpshufd	ymm0,ymm3,0x00
+	vpshufd	ymm1,ymm3,0x55
+	vmovdqa	YMMWORD[(256-256)+rcx],ymm0
+	vpshufd	ymm2,ymm3,0xaa
+	vmovdqa	YMMWORD[(288-256)+rcx],ymm1
+	vpshufd	ymm3,ymm3,0xff
+	vmovdqa	YMMWORD[(320-256)+rcx],ymm2
+	vmovdqa	YMMWORD[(352-256)+rcx],ymm3
+
+	vpshufd	ymm12,ymm15,0x00
+	vpshufd	ymm13,ymm15,0x55
+	vmovdqa	YMMWORD[(384-512)+rax],ymm12
+	vpshufd	ymm14,ymm15,0xaa
+	vmovdqa	YMMWORD[(416-512)+rax],ymm13
+	vpshufd	ymm15,ymm15,0xff
+	vmovdqa	YMMWORD[(448-512)+rax],ymm14
+	vmovdqa	YMMWORD[(480-512)+rax],ymm15
+
+	vpshufd	ymm4,ymm7,0x00
+	vpshufd	ymm5,ymm7,0x55
+	vpaddd	ymm4,ymm4,YMMWORD[$L$incy]
+	vpshufd	ymm6,ymm7,0xaa
+	vmovdqa	YMMWORD[(544-512)+rax],ymm5
+	vpshufd	ymm7,ymm7,0xff
+	vmovdqa	YMMWORD[(576-512)+rax],ymm6
+	vmovdqa	YMMWORD[(608-512)+rax],ymm7
+
+	jmp	NEAR $L$oop_enter8x
+
+ALIGN	32
+$L$oop_outer8x:
+	vmovdqa	ymm8,YMMWORD[((128-256))+rcx]
+	vmovdqa	ymm9,YMMWORD[((160-256))+rcx]
+	vmovdqa	ymm10,YMMWORD[((192-256))+rcx]
+	vmovdqa	ymm11,YMMWORD[((224-256))+rcx]
+	vmovdqa	ymm0,YMMWORD[((256-256))+rcx]
+	vmovdqa	ymm1,YMMWORD[((288-256))+rcx]
+	vmovdqa	ymm2,YMMWORD[((320-256))+rcx]
+	vmovdqa	ymm3,YMMWORD[((352-256))+rcx]
+	vmovdqa	ymm12,YMMWORD[((384-512))+rax]
+	vmovdqa	ymm13,YMMWORD[((416-512))+rax]
+	vmovdqa	ymm14,YMMWORD[((448-512))+rax]
+	vmovdqa	ymm15,YMMWORD[((480-512))+rax]
+	vmovdqa	ymm4,YMMWORD[((512-512))+rax]
+	vmovdqa	ymm5,YMMWORD[((544-512))+rax]
+	vmovdqa	ymm6,YMMWORD[((576-512))+rax]
+	vmovdqa	ymm7,YMMWORD[((608-512))+rax]
+	vpaddd	ymm4,ymm4,YMMWORD[$L$eight]
+
+$L$oop_enter8x:
+	vmovdqa	YMMWORD[64+rsp],ymm14
+	vmovdqa	YMMWORD[96+rsp],ymm15
+	vbroadcasti128	ymm15,YMMWORD[r10]
+	vmovdqa	YMMWORD[(512-512)+rax],ymm4
+	mov	eax,10
+	jmp	NEAR $L$oop8x
+
+ALIGN	32
+$L$oop8x:
+	vpaddd	ymm8,ymm8,ymm0
+	vpxor	ymm4,ymm8,ymm4
+	vpshufb	ymm4,ymm4,ymm15
+	vpaddd	ymm9,ymm9,ymm1
+	vpxor	ymm5,ymm9,ymm5
+	vpshufb	ymm5,ymm5,ymm15
+	vpaddd	ymm12,ymm12,ymm4
+	vpxor	ymm0,ymm12,ymm0
+	vpslld	ymm14,ymm0,12
+	vpsrld	ymm0,ymm0,20
+	vpor	ymm0,ymm14,ymm0
+	vbroadcasti128	ymm14,YMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm5
+	vpxor	ymm1,ymm13,ymm1
+	vpslld	ymm15,ymm1,12
+	vpsrld	ymm1,ymm1,20
+	vpor	ymm1,ymm15,ymm1
+	vpaddd	ymm8,ymm8,ymm0
+	vpxor	ymm4,ymm8,ymm4
+	vpshufb	ymm4,ymm4,ymm14
+	vpaddd	ymm9,ymm9,ymm1
+	vpxor	ymm5,ymm9,ymm5
+	vpshufb	ymm5,ymm5,ymm14
+	vpaddd	ymm12,ymm12,ymm4
+	vpxor	ymm0,ymm12,ymm0
+	vpslld	ymm15,ymm0,7
+	vpsrld	ymm0,ymm0,25
+	vpor	ymm0,ymm15,ymm0
+	vbroadcasti128	ymm15,YMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm5
+	vpxor	ymm1,ymm13,ymm1
+	vpslld	ymm14,ymm1,7
+	vpsrld	ymm1,ymm1,25
+	vpor	ymm1,ymm14,ymm1
+	vmovdqa	YMMWORD[rsp],ymm12
+	vmovdqa	YMMWORD[32+rsp],ymm13
+	vmovdqa	ymm12,YMMWORD[64+rsp]
+	vmovdqa	ymm13,YMMWORD[96+rsp]
+	vpaddd	ymm10,ymm10,ymm2
+	vpxor	ymm6,ymm10,ymm6
+	vpshufb	ymm6,ymm6,ymm15
+	vpaddd	ymm11,ymm11,ymm3
+	vpxor	ymm7,ymm11,ymm7
+	vpshufb	ymm7,ymm7,ymm15
+	vpaddd	ymm12,ymm12,ymm6
+	vpxor	ymm2,ymm12,ymm2
+	vpslld	ymm14,ymm2,12
+	vpsrld	ymm2,ymm2,20
+	vpor	ymm2,ymm14,ymm2
+	vbroadcasti128	ymm14,YMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm7
+	vpxor	ymm3,ymm13,ymm3
+	vpslld	ymm15,ymm3,12
+	vpsrld	ymm3,ymm3,20
+	vpor	ymm3,ymm15,ymm3
+	vpaddd	ymm10,ymm10,ymm2
+	vpxor	ymm6,ymm10,ymm6
+	vpshufb	ymm6,ymm6,ymm14
+	vpaddd	ymm11,ymm11,ymm3
+	vpxor	ymm7,ymm11,ymm7
+	vpshufb	ymm7,ymm7,ymm14
+	vpaddd	ymm12,ymm12,ymm6
+	vpxor	ymm2,ymm12,ymm2
+	vpslld	ymm15,ymm2,7
+	vpsrld	ymm2,ymm2,25
+	vpor	ymm2,ymm15,ymm2
+	vbroadcasti128	ymm15,YMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm7
+	vpxor	ymm3,ymm13,ymm3
+	vpslld	ymm14,ymm3,7
+	vpsrld	ymm3,ymm3,25
+	vpor	ymm3,ymm14,ymm3
+	vpaddd	ymm8,ymm8,ymm1
+	vpxor	ymm7,ymm8,ymm7
+	vpshufb	ymm7,ymm7,ymm15
+	vpaddd	ymm9,ymm9,ymm2
+	vpxor	ymm4,ymm9,ymm4
+	vpshufb	ymm4,ymm4,ymm15
+	vpaddd	ymm12,ymm12,ymm7
+	vpxor	ymm1,ymm12,ymm1
+	vpslld	ymm14,ymm1,12
+	vpsrld	ymm1,ymm1,20
+	vpor	ymm1,ymm14,ymm1
+	vbroadcasti128	ymm14,YMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm4
+	vpxor	ymm2,ymm13,ymm2
+	vpslld	ymm15,ymm2,12
+	vpsrld	ymm2,ymm2,20
+	vpor	ymm2,ymm15,ymm2
+	vpaddd	ymm8,ymm8,ymm1
+	vpxor	ymm7,ymm8,ymm7
+	vpshufb	ymm7,ymm7,ymm14
+	vpaddd	ymm9,ymm9,ymm2
+	vpxor	ymm4,ymm9,ymm4
+	vpshufb	ymm4,ymm4,ymm14
+	vpaddd	ymm12,ymm12,ymm7
+	vpxor	ymm1,ymm12,ymm1
+	vpslld	ymm15,ymm1,7
+	vpsrld	ymm1,ymm1,25
+	vpor	ymm1,ymm15,ymm1
+	vbroadcasti128	ymm15,YMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm4
+	vpxor	ymm2,ymm13,ymm2
+	vpslld	ymm14,ymm2,7
+	vpsrld	ymm2,ymm2,25
+	vpor	ymm2,ymm14,ymm2
+	vmovdqa	YMMWORD[64+rsp],ymm12
+	vmovdqa	YMMWORD[96+rsp],ymm13
+	vmovdqa	ymm12,YMMWORD[rsp]
+	vmovdqa	ymm13,YMMWORD[32+rsp]
+	vpaddd	ymm10,ymm10,ymm3
+	vpxor	ymm5,ymm10,ymm5
+	vpshufb	ymm5,ymm5,ymm15
+	vpaddd	ymm11,ymm11,ymm0
+	vpxor	ymm6,ymm11,ymm6
+	vpshufb	ymm6,ymm6,ymm15
+	vpaddd	ymm12,ymm12,ymm5
+	vpxor	ymm3,ymm12,ymm3
+	vpslld	ymm14,ymm3,12
+	vpsrld	ymm3,ymm3,20
+	vpor	ymm3,ymm14,ymm3
+	vbroadcasti128	ymm14,YMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm6
+	vpxor	ymm0,ymm13,ymm0
+	vpslld	ymm15,ymm0,12
+	vpsrld	ymm0,ymm0,20
+	vpor	ymm0,ymm15,ymm0
+	vpaddd	ymm10,ymm10,ymm3
+	vpxor	ymm5,ymm10,ymm5
+	vpshufb	ymm5,ymm5,ymm14
+	vpaddd	ymm11,ymm11,ymm0
+	vpxor	ymm6,ymm11,ymm6
+	vpshufb	ymm6,ymm6,ymm14
+	vpaddd	ymm12,ymm12,ymm5
+	vpxor	ymm3,ymm12,ymm3
+	vpslld	ymm15,ymm3,7
+	vpsrld	ymm3,ymm3,25
+	vpor	ymm3,ymm15,ymm3
+	vbroadcasti128	ymm15,YMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm6
+	vpxor	ymm0,ymm13,ymm0
+	vpslld	ymm14,ymm0,7
+	vpsrld	ymm0,ymm0,25
+	vpor	ymm0,ymm14,ymm0
+	dec	eax
+	jnz	NEAR $L$oop8x
+
+	lea	rax,[512+rsp]
+	vpaddd	ymm8,ymm8,YMMWORD[((128-256))+rcx]
+	vpaddd	ymm9,ymm9,YMMWORD[((160-256))+rcx]
+	vpaddd	ymm10,ymm10,YMMWORD[((192-256))+rcx]
+	vpaddd	ymm11,ymm11,YMMWORD[((224-256))+rcx]
+
+	vpunpckldq	ymm14,ymm8,ymm9
+	vpunpckldq	ymm15,ymm10,ymm11
+	vpunpckhdq	ymm8,ymm8,ymm9
+	vpunpckhdq	ymm10,ymm10,ymm11
+	vpunpcklqdq	ymm9,ymm14,ymm15
+	vpunpckhqdq	ymm14,ymm14,ymm15
+	vpunpcklqdq	ymm11,ymm8,ymm10
+	vpunpckhqdq	ymm8,ymm8,ymm10
+	vpaddd	ymm0,ymm0,YMMWORD[((256-256))+rcx]
+	vpaddd	ymm1,ymm1,YMMWORD[((288-256))+rcx]
+	vpaddd	ymm2,ymm2,YMMWORD[((320-256))+rcx]
+	vpaddd	ymm3,ymm3,YMMWORD[((352-256))+rcx]
+
+	vpunpckldq	ymm10,ymm0,ymm1
+	vpunpckldq	ymm15,ymm2,ymm3
+	vpunpckhdq	ymm0,ymm0,ymm1
+	vpunpckhdq	ymm2,ymm2,ymm3
+	vpunpcklqdq	ymm1,ymm10,ymm15
+	vpunpckhqdq	ymm10,ymm10,ymm15
+	vpunpcklqdq	ymm3,ymm0,ymm2
+	vpunpckhqdq	ymm0,ymm0,ymm2
+	vperm2i128	ymm15,ymm9,ymm1,0x20
+	vperm2i128	ymm1,ymm9,ymm1,0x31
+	vperm2i128	ymm9,ymm14,ymm10,0x20
+	vperm2i128	ymm10,ymm14,ymm10,0x31
+	vperm2i128	ymm14,ymm11,ymm3,0x20
+	vperm2i128	ymm3,ymm11,ymm3,0x31
+	vperm2i128	ymm11,ymm8,ymm0,0x20
+	vperm2i128	ymm0,ymm8,ymm0,0x31
+	vmovdqa	YMMWORD[rsp],ymm15
+	vmovdqa	YMMWORD[32+rsp],ymm9
+	vmovdqa	ymm15,YMMWORD[64+rsp]
+	vmovdqa	ymm9,YMMWORD[96+rsp]
+
+	vpaddd	ymm12,ymm12,YMMWORD[((384-512))+rax]
+	vpaddd	ymm13,ymm13,YMMWORD[((416-512))+rax]
+	vpaddd	ymm15,ymm15,YMMWORD[((448-512))+rax]
+	vpaddd	ymm9,ymm9,YMMWORD[((480-512))+rax]
+
+	vpunpckldq	ymm2,ymm12,ymm13
+	vpunpckldq	ymm8,ymm15,ymm9
+	vpunpckhdq	ymm12,ymm12,ymm13
+	vpunpckhdq	ymm15,ymm15,ymm9
+	vpunpcklqdq	ymm13,ymm2,ymm8
+	vpunpckhqdq	ymm2,ymm2,ymm8
+	vpunpcklqdq	ymm9,ymm12,ymm15
+	vpunpckhqdq	ymm12,ymm12,ymm15
+	vpaddd	ymm4,ymm4,YMMWORD[((512-512))+rax]
+	vpaddd	ymm5,ymm5,YMMWORD[((544-512))+rax]
+	vpaddd	ymm6,ymm6,YMMWORD[((576-512))+rax]
+	vpaddd	ymm7,ymm7,YMMWORD[((608-512))+rax]
+
+	vpunpckldq	ymm15,ymm4,ymm5
+	vpunpckldq	ymm8,ymm6,ymm7
+	vpunpckhdq	ymm4,ymm4,ymm5
+	vpunpckhdq	ymm6,ymm6,ymm7
+	vpunpcklqdq	ymm5,ymm15,ymm8
+	vpunpckhqdq	ymm15,ymm15,ymm8
+	vpunpcklqdq	ymm7,ymm4,ymm6
+	vpunpckhqdq	ymm4,ymm4,ymm6
+	vperm2i128	ymm8,ymm13,ymm5,0x20
+	vperm2i128	ymm5,ymm13,ymm5,0x31
+	vperm2i128	ymm13,ymm2,ymm15,0x20
+	vperm2i128	ymm15,ymm2,ymm15,0x31
+	vperm2i128	ymm2,ymm9,ymm7,0x20
+	vperm2i128	ymm7,ymm9,ymm7,0x31
+	vperm2i128	ymm9,ymm12,ymm4,0x20
+	vperm2i128	ymm4,ymm12,ymm4,0x31
+	vmovdqa	ymm6,YMMWORD[rsp]
+	vmovdqa	ymm12,YMMWORD[32+rsp]
+
+	cmp	rdx,64*8
+	jb	NEAR $L$tail8x
+
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm12,ymm12,YMMWORD[rsi]
+	vpxor	ymm13,ymm13,YMMWORD[32+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[64+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm12
+	vmovdqu	YMMWORD[32+rdi],ymm13
+	vmovdqu	YMMWORD[64+rdi],ymm10
+	vmovdqu	YMMWORD[96+rdi],ymm15
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm14,ymm14,YMMWORD[rsi]
+	vpxor	ymm2,ymm2,YMMWORD[32+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[64+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm14
+	vmovdqu	YMMWORD[32+rdi],ymm2
+	vmovdqu	YMMWORD[64+rdi],ymm3
+	vmovdqu	YMMWORD[96+rdi],ymm7
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm11,ymm11,YMMWORD[rsi]
+	vpxor	ymm9,ymm9,YMMWORD[32+rsi]
+	vpxor	ymm0,ymm0,YMMWORD[64+rsi]
+	vpxor	ymm4,ymm4,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm11
+	vmovdqu	YMMWORD[32+rdi],ymm9
+	vmovdqu	YMMWORD[64+rdi],ymm0
+	vmovdqu	YMMWORD[96+rdi],ymm4
+	lea	rdi,[128+rdi]
+
+	sub	rdx,64*8
+	jnz	NEAR $L$oop_outer8x
+
+	jmp	NEAR $L$done8x
+
+$L$tail8x:
+	cmp	rdx,448
+	jae	NEAR $L$448_or_more8x
+	cmp	rdx,384
+	jae	NEAR $L$384_or_more8x
+	cmp	rdx,320
+	jae	NEAR $L$320_or_more8x
+	cmp	rdx,256
+	jae	NEAR $L$256_or_more8x
+	cmp	rdx,192
+	jae	NEAR $L$192_or_more8x
+	cmp	rdx,128
+	jae	NEAR $L$128_or_more8x
+	cmp	rdx,64
+	jae	NEAR $L$64_or_more8x
+
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm6
+	vmovdqa	YMMWORD[32+rsp],ymm8
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$64_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	je	NEAR $L$done8x
+
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm1
+	lea	rdi,[64+rdi]
+	sub	rdx,64
+	vmovdqa	YMMWORD[32+rsp],ymm5
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$128_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	je	NEAR $L$done8x
+
+	lea	rsi,[128+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm12
+	lea	rdi,[128+rdi]
+	sub	rdx,128
+	vmovdqa	YMMWORD[32+rsp],ymm13
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$192_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	je	NEAR $L$done8x
+
+	lea	rsi,[192+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm10
+	lea	rdi,[192+rdi]
+	sub	rdx,192
+	vmovdqa	YMMWORD[32+rsp],ymm15
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$256_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	je	NEAR $L$done8x
+
+	lea	rsi,[256+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm14
+	lea	rdi,[256+rdi]
+	sub	rdx,256
+	vmovdqa	YMMWORD[32+rsp],ymm2
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$320_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	je	NEAR $L$done8x
+
+	lea	rsi,[320+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm3
+	lea	rdi,[320+rdi]
+	sub	rdx,320
+	vmovdqa	YMMWORD[32+rsp],ymm7
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$384_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[320+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[352+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	vmovdqu	YMMWORD[320+rdi],ymm3
+	vmovdqu	YMMWORD[352+rdi],ymm7
+	je	NEAR $L$done8x
+
+	lea	rsi,[384+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm11
+	lea	rdi,[384+rdi]
+	sub	rdx,384
+	vmovdqa	YMMWORD[32+rsp],ymm9
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$448_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[320+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[352+rsi]
+	vpxor	ymm11,ymm11,YMMWORD[384+rsi]
+	vpxor	ymm9,ymm9,YMMWORD[416+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	vmovdqu	YMMWORD[320+rdi],ymm3
+	vmovdqu	YMMWORD[352+rdi],ymm7
+	vmovdqu	YMMWORD[384+rdi],ymm11
+	vmovdqu	YMMWORD[416+rdi],ymm9
+	je	NEAR $L$done8x
+
+	lea	rsi,[448+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm0
+	lea	rdi,[448+rdi]
+	sub	rdx,448
+	vmovdqa	YMMWORD[32+rsp],ymm4
+
+$L$oop_tail8x:
+	movzx	eax,BYTE[r10*1+rsi]
+	movzx	ecx,BYTE[r10*1+rsp]
+	lea	r10,[1+r10]
+	xor	eax,ecx
+	mov	BYTE[((-1))+r10*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail8x
+
+$L$done8x:
+	vzeroall
+	lea	r11,[((656+48))+rsp]
+	movaps	xmm6,XMMWORD[((-48))+r11]
+	movaps	xmm7,XMMWORD[((-32))+r11]
+	movaps	xmm8,XMMWORD[((-16))+r11]
+	movaps	xmm9,XMMWORD[r11]
+	movaps	xmm10,XMMWORD[16+r11]
+	movaps	xmm11,XMMWORD[32+r11]
+	movaps	xmm12,XMMWORD[48+r11]
+	movaps	xmm13,XMMWORD[64+r11]
+	movaps	xmm14,XMMWORD[80+r11]
+	movaps	xmm15,XMMWORD[96+r11]
+	mov	rsp,QWORD[640+rsp]
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_8x:
diff --git a/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
index 45ba686..a2e4075 100644
--- a/win-x86_64/crypto/ec/p256-x86_64-asm.asm
+++ b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -1009,6 +1009,7 @@
 	push	r15
 	sub	rsp,32*5+8
 
+$L$point_double_shortcutq:
 	movdqu	xmm0,XMMWORD[rsi]
 	mov	rbx,rsi
 	movdqu	xmm1,XMMWORD[16+rsi]
@@ -1282,6 +1283,7 @@
 	mov	r14,QWORD[((64+8))+rbx]
 	mov	r15,QWORD[((64+16))+rbx]
 	mov	r8,QWORD[((64+24))+rbx]
+DB	102,72,15,110,203
 
 	lea	rsi,[((64-0))+rbx]
 	lea	rdi,[32+rsp]
@@ -1373,7 +1375,7 @@
 	test	r8,r8
 	jnz	NEAR $L$add_proceedq
 	test	r9,r9
-	jz	NEAR $L$add_proceedq
+	jz	NEAR $L$add_doubleq
 
 DB	102,72,15,126,199
 	pxor	xmm0,xmm0
@@ -1386,6 +1388,13 @@
 	jmp	NEAR $L$add_doneq
 
 ALIGN	32
+$L$add_doubleq:
+DB	102,72,15,126,206
+DB	102,72,15,126,199
+	add	rsp,416
+	jmp	NEAR $L$point_double_shortcutq
+
+ALIGN	32
 $L$add_proceedq:
 	mov	rax,QWORD[((0+64))+rsp]
 	mov	r14,QWORD[((8+64))+rsp]