Revert "Revert "external/boringssl: sync with upstream.""

This reverts commit a04d78d392463df4e69a64360c952ffa5abd22f7.

Underlying issue was fixed.

Change-Id: I49685b653d16e728eb38e79e02b2c33ddeefed88
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index d63fc86..f3dd323 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-af0e32cb84f0c9cc65b9233a3414d2562642b342
+d98dc1311e20193ac188e359e91aeaaf5cc3a7e2
diff --git a/UPDATING b/UPDATING
new file mode 100644
index 0000000..17af66d
--- /dev/null
+++ b/UPDATING
@@ -0,0 +1,8 @@
+rm -Rf src
+git clone https://boringssl.googlesource.com/boringssl src
+cd src
+git show -s --pretty=%H > ../BORINGSSL_REVISION
+cd ..
+rm -Rf src/.git
+rm -Rf linux-aarch64/ linux-arm/ linux-x86/ linux-x86_64/ mac-x86/ mac-x86_64/ win-x86_64/ win-x86/
+python src/util/generate_build_files.py android
diff --git a/crypto-sources.mk b/crypto-sources.mk
index 7d9319c..a5b8ba3 100644
--- a/crypto-sources.mk
+++ b/crypto-sources.mk
@@ -1,7 +1,8 @@
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/sources.mk
 include $(LOCAL_PATH)/sources.mk
 
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter
+LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter -DBORINGSSL_ANDROID_SYSTEM
+LOCAL_ASFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter
 # Do not add in the architecture-specific files if we don't want to build assembly
 ifeq ($(LOCAL_IS_HOST_MODULE),true)
 LOCAL_SRC_FILES_linux_x86 := $(linux_x86_sources)
diff --git a/err_data.c b/err_data.c
index f884a72..258a5c3 100644
--- a/err_data.c
+++ b/err_data.c
@@ -49,1542 +49,183 @@
 OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28);
 OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29);
 OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 31, library_values_changed_31);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 32, library_values_changed_32);
+OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31);
+OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32);
 OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
 
-const uint32_t kOpenSSLFunctionValues[] = {
-    0xc32054b,
-    0xc328556,
-    0xc330561,
-    0xc33856e,
-    0xc340578,
-    0xc348582,
-    0xc350589,
-    0xc358595,
-    0xc36059c,
-    0xc3685b2,
-    0xc3705d1,
-    0xc3785e2,
-    0xc3805f2,
-    0xc38860c,
-    0xc390621,
-    0xc398630,
-    0xc3a0649,
-    0xc3a865d,
-    0xc3b0669,
-    0xc3b8670,
-    0xc3c0678,
-    0xc3c8690,
-    0xc3d0698,
-    0xc3d86a0,
-    0xc3e06ab,
-    0xc3e85c7,
-    0xc3f0686,
-    0x1032193d,
-    0x10329954,
-    0x1033196d,
-    0x10339983,
-    0x10341993,
-    0x103499a6,
-    0x103519b4,
-    0x103599c3,
-    0x103619e3,
-    0x10369a02,
-    0x10371a1f,
-    0x10379a3c,
-    0x10381a51,
-    0x10389a73,
-    0x10391a92,
-    0x10399ab1,
-    0x103a1ac8,
-    0x103a9adf,
-    0x103b1ae8,
-    0x103b9af3,
-    0x103c1b0d,
-    0x103c9b15,
-    0x103d1b1d,
-    0x103d9b24,
-    0x103e1b37,
-    0x103e9b49,
-    0x103f1b5c,
-    0x103f9b65,
-    0x14320a4e,
-    0x14328a5c,
-    0x14330a68,
-    0x14338a75,
-    0x18361224,
-    0x18371252,
-    0x18379263,
-    0x18381279,
-    0x1839129c,
-    0x183992b1,
-    0x183a12c3,
-    0x183c1307,
-    0x183c9315,
-    0x183d1328,
-    0x183d9338,
-    0x183e935e,
-    0x183f1371,
-    0x183f9380,
-    0x184093aa,
-    0x18411416,
-    0x18419427,
-    0x1842143a,
-    0x1842944c,
-    0x1843145e,
-    0x1843946f,
-    0x18441480,
-    0x18449491,
-    0x184514a2,
-    0x184594af,
-    0x184614d1,
-    0x184694e4,
-    0x184714f8,
-    0x18479505,
-    0x18481514,
-    0x18489523,
-    0x18491534,
-    0x18499550,
-    0x184a155e,
-    0x184a956f,
-    0x184b1580,
-    0x184b958e,
-    0x184c159e,
-    0x184c95c4,
-    0x184d15d3,
-    0x184d95e3,
-    0x184e15f3,
-    0x184e9602,
-    0x184f1541,
-    0x184f91b3,
-    0x18501156,
-    0x1850916e,
-    0x18511190,
-    0x185191a2,
-    0x185211d4,
-    0x185291ed,
-    0x185311fe,
-    0x18539214,
-    0x18541239,
-    0x1854928a,
-    0x185512d3,
-    0x185592e8,
-    0x185612f5,
-    0x1856934d,
-    0x18571390,
-    0x1857939d,
-    0x185813b9,
-    0x185893ca,
-    0x185913da,
-    0x185993ea,
-    0x185a13f9,
-    0x185a9408,
-    0x185b14bd,
-    0x1c3206b8,
-    0x1c3286c4,
-    0x1c3306cf,
-    0x1c3386db,
-    0x20321616,
-    0x20329621,
-    0x20331629,
-    0x20339635,
-    0x24321641,
-    0x2432964f,
-    0x24331661,
-    0x24339670,
-    0x24341683,
-    0x24349696,
-    0x243516ad,
-    0x243596c5,
-    0x243616d3,
-    0x243696eb,
-    0x243716f4,
-    0x24379706,
-    0x2438171a,
-    0x24389727,
-    0x2439173d,
-    0x24399755,
-    0x243a176d,
-    0x243a9777,
-    0x243b178c,
-    0x243b979a,
-    0x243c17b2,
-    0x243c97c9,
-    0x243d17d4,
-    0x243d97e2,
-    0x28320aae,
-    0x28328abd,
-    0x28330ac8,
-    0x28338acd,
-    0x28340ad8,
-    0x2c322b47,
-    0x2c32ab53,
-    0x2c332b66,
-    0x2c33ab77,
-    0x2c342b90,
-    0x2c34abb8,
-    0x2c352bcf,
-    0x2c35abec,
-    0x2c362c09,
-    0x2c36ac26,
-    0x2c372c3f,
-    0x2c37ac58,
-    0x2c382c6e,
-    0x2c38ac7c,
-    0x2c392c8e,
-    0x2c39acab,
-    0x2c3a2cc8,
-    0x2c3aacd6,
-    0x2c3b2cf4,
-    0x2c3bad12,
-    0x2c3c2d2d,
-    0x2c3cad41,
-    0x2c3d2d53,
-    0x2c3dad63,
-    0x2c3e2d71,
-    0x2c3ead81,
-    0x2c3f2d91,
-    0x2c3fadac,
-    0x2c402dbd,
-    0x2c40add8,
-    0x2c412dec,
-    0x2c41adff,
-    0x2c422e1e,
-    0x2c42ae32,
-    0x2c432e45,
-    0x2c43ae54,
-    0x2c442e63,
-    0x2c44ae7a,
-    0x2c452e95,
-    0x2c45aead,
-    0x2c462ec1,
-    0x2c46aed4,
-    0x2c472ee5,
-    0x2c47aef6,
-    0x2c482f07,
-    0x2c48af18,
-    0x2c492f27,
-    0x2c49af34,
-    0x2c4a2f41,
-    0x2c4aaf4e,
-    0x2c4b2f57,
-    0x2c4baf6b,
-    0x2c4c2f7a,
-    0x2c4caf88,
-    0x2c4d2faa,
-    0x2c4dafbb,
-    0x2c4e2fcc,
-    0x2c4eaf97,
-    0x2c4f2ba9,
-    0x30320000,
-    0x30328018,
-    0x3033002c,
-    0x30338042,
-    0x3034005b,
-    0x3034806c,
-    0x3035007f,
-    0x3035808f,
-    0x3036009d,
-    0x303680b3,
-    0x303700c3,
-    0x303780d8,
-    0x303800e6,
-    0x303880f7,
-    0x30390103,
-    0x3039810c,
-    0x303a011d,
-    0x303a812d,
-    0x303b013a,
-    0x303b8146,
-    0x303c0157,
-    0x303c8165,
-    0x303d0176,
-    0x303d8188,
-    0x303e0199,
-    0x303e81a8,
-    0x303f01b9,
-    0x303f81cd,
-    0x304001df,
-    0x304081ec,
-    0x30410202,
-    0x30418215,
-    0x30420225,
-    0x30428239,
-    0x3043024a,
-    0x3043825a,
-    0x30440265,
-    0x3044826d,
-    0x3045027d,
-    0x30458294,
-    0x304602a1,
-    0x304682b7,
-    0x304702c9,
-    0x304782d5,
-    0x304802e1,
-    0x304882ef,
-    0x30490308,
-    0x30498316,
-    0x304a032b,
-    0x304a8343,
-    0x304b034d,
-    0x304b8361,
-    0x304c0372,
-    0x304c8382,
-    0x304d038f,
-    0x304d83a0,
-    0x304e03b0,
-    0x304e83c2,
-    0x304f03d3,
-    0x304f83e2,
-    0x305003f6,
-    0x30508404,
-    0x30510413,
-    0x3051841c,
-    0x343209d6,
-    0x343289e6,
-    0x343309f1,
-    0x343389fe,
-    0x38320a07,
-    0x38328a1f,
-    0x38330a32,
-    0x38338a3c,
-    0x3c320aeb,
-    0x3c328af9,
-    0x3c330b10,
-    0x3c338b24,
-    0x3c340b56,
-    0x3c348b67,
-    0x3c350b73,
-    0x3c358ba0,
-    0x3c360bb2,
-    0x3c368bdb,
-    0x3c370be8,
-    0x3c378bf5,
-    0x3c380c03,
-    0x3c388c10,
-    0x3c390c1d,
-    0x3c398c41,
-    0x3c3a0c51,
-    0x3c3a8c69,
-    0x3c3b0c7e,
-    0x3c3b8c93,
-    0x3c3c0ca0,
-    0x3c3c8cb3,
-    0x3c3d0cc6,
-    0x3c3d8cea,
-    0x3c3e0d12,
-    0x3c3e8d2b,
-    0x3c3f0d41,
-    0x3c3f8d4e,
-    0x3c400d61,
-    0x3c408d72,
-    0x3c410d83,
-    0x3c418d9c,
-    0x3c420db5,
-    0x3c428dcb,
-    0x3c430de8,
-    0x3c438dfe,
-    0x3c440e82,
-    0x3c448ea9,
-    0x3c450ec7,
-    0x3c458ee1,
-    0x3c460ef9,
-    0x3c468f11,
-    0x3c470f3c,
-    0x3c478f67,
-    0x3c480f88,
-    0x3c488fb1,
-    0x3c490fcc,
-    0x3c498ff5,
-    0x3c4a1002,
-    0x3c4a9019,
-    0x3c4b1030,
-    0x3c4b9059,
-    0x3c4c1069,
-    0x3c4c9075,
-    0x3c4d108d,
-    0x3c4d90a0,
-    0x3c4e10b1,
-    0x3c4e90c2,
-    0x3c4f10e8,
-    0x3c4f8adf,
-    0x3c500e1a,
-    0x3c508e3a,
-    0x3c510e67,
-    0x3c518fe7,
-    0x3c5210d2,
-    0x3c528b87,
-    0x3c530b3f,
-    0x40321ba5,
-    0x40329bbf,
-    0x40331be7,
-    0x40339bff,
-    0x40341c1d,
-    0x40349c64,
-    0x40351c7b,
-    0x40359c97,
-    0x40361cb3,
-    0x40369ccd,
-    0x40371cec,
-    0x40379d0b,
-    0x40381d23,
-    0x40389d40,
-    0x40391d63,
-    0x40399d80,
-    0x403a1db5,
-    0x403a9e0f,
-    0x403b1e24,
-    0x403b9e40,
-    0x403c1e5a,
-    0x403c9e65,
-    0x403d1e88,
-    0x403d9eac,
-    0x403e1ec2,
-    0x403e9ecc,
-    0x403f1ed8,
-    0x403f9ee9,
-    0x40401f01,
-    0x40409f09,
-    0x40411f12,
-    0x40419f1b,
-    0x40421f43,
-    0x40429f57,
-    0x40431f62,
-    0x40439f6e,
-    0x40441fc2,
-    0x40449fce,
-    0x40451fdb,
-    0x40459fee,
-    0x40462006,
-    0x4046a01e,
-    0x40472034,
-    0x4047a04f,
-    0x4048206a,
-    0x4048a07e,
-    0x40492097,
-    0x4049a0b0,
-    0x404a20ca,
-    0x404aa0d4,
-    0x404b1dd7,
-    0x404b9df6,
-    0x404c20e4,
-    0x404ca0f2,
-    0x404d20ff,
-    0x404da113,
-    0x404e212b,
-    0x404ea139,
-    0x404f2163,
-    0x404fa17a,
-    0x4050218c,
-    0x4050a1bd,
-    0x405121ee,
-    0x4051a203,
-    0x40522226,
-    0x4052a246,
-    0x4053225b,
-    0x4053a26b,
-    0x4054a277,
-    0x4055228d,
-    0x4055a2cd,
-    0x405622da,
-    0x4056a2e4,
-    0x405722f2,
-    0x4057a30d,
-    0x40582328,
-    0x4058a347,
-    0x4059235c,
-    0x4059a371,
-    0x405a238e,
-    0x405aa3a2,
-    0x405b23be,
-    0x405ba3d4,
-    0x405c23f1,
-    0x405ca403,
-    0x405d241a,
-    0x405da42b,
-    0x405e2447,
-    0x405ea45b,
-    0x405f246b,
-    0x405fa487,
-    0x4060249c,
-    0x4060a4b2,
-    0x406124cf,
-    0x4061a4e8,
-    0x40622512,
-    0x4062a51b,
-    0x4063252b,
-    0x4063a564,
-    0x4064257a,
-    0x4064a598,
-    0x406525ad,
-    0x4065a5ca,
-    0x406625e1,
-    0x4066a5ff,
-    0x4067261c,
-    0x4067a633,
-    0x40682651,
-    0x4068a668,
-    0x40692680,
-    0x4069a691,
-    0x406a26a4,
-    0x406aa6b7,
-    0x406b26cb,
-    0x406ba6ef,
-    0x406c270a,
-    0x406ca72b,
-    0x406d274f,
-    0x406da76a,
-    0x406e278b,
-    0x406ea7a0,
-    0x406f27b9,
-    0x406fa7c6,
-    0x407027d4,
-    0x4070a7e1,
-    0x407127fe,
-    0x4071a81e,
-    0x40722839,
-    0x4072a852,
-    0x40732869,
-    0x4073a883,
-    0x407428a7,
-    0x4074a8bd,
-    0x407528d1,
-    0x4075a8e6,
-    0x40762900,
-    0x4076a912,
-    0x40772927,
-    0x4077a94d,
-    0x4078296a,
-    0x4078a98d,
-    0x407929b3,
-    0x4079a9d0,
-    0x407a29f3,
-    0x407aaa0f,
-    0x407b2a2b,
-    0x407baa3d,
-    0x407c2a4a,
-    0x407e2a57,
-    0x407eaa6d,
-    0x407f2a85,
-    0x407faa98,
-    0x40802aad,
-    0x4080aac6,
-    0x40812ae4,
-    0x4081ab04,
-    0x40822b0d,
-    0x4082ab29,
-    0x40832b32,
-    0x4083a148,
-    0x408421d7,
-    0x4084a1a7,
-    0x40852553,
-    0x4085a537,
-    0x40861c3c,
-    0x40869c4f,
-    0x40871fa2,
-    0x40879fb1,
-    0x40881bcb,
-    0x40889f2b,
-    0x40891f89,
-    0x4089a4fb,
-    0x408a1b70,
-    0x408a9b81,
-    0x408b1b93,
-    0x408ba214,
-    0x408c1d9e,
-    0x408c9dc5,
-    0x408d22ab,
-    0x4432042a,
-    0x4432843c,
-    0x44330445,
-    0x4433844d,
-    0x4434045a,
-    0x44348475,
-    0x44350490,
-    0x443584b0,
-    0x443604cc,
-    0x443684ed,
-    0x443704f4,
-    0x44378502,
-    0x4438050c,
-    0x44388518,
-    0x44390522,
-    0x4439852d,
-    0x443a0537,
-    0x443a8541,
-    0x443b046a,
-    0x4c3217ea,
-    0x4c3297f9,
-    0x4c331808,
-    0x4c339821,
-    0x4c34183c,
-    0x4c349858,
-    0x4c35186a,
-    0x4c359878,
-    0x4c36188d,
-    0x4c36989e,
-    0x4c3718ac,
-    0x4c3798ba,
-    0x4c3818cc,
-    0x4c3898dc,
-    0x4c3918e6,
-    0x4c3998fe,
-    0x4c3a1916,
-    0x4c3a9929,
-    0x50322fdd,
-    0x5032aff2,
-    0x50333003,
-    0x5033b016,
-    0x50343027,
-    0x5034b03a,
-    0x50353049,
-    0x5035b05e,
-    0x5036306e,
-    0x5036b07d,
-    0x5037308e,
-    0x5037b09e,
-    0x503830af,
-    0x5038b0c2,
-    0x503930d4,
-    0x5039b0ea,
-    0x503a30fc,
-    0x503ab10d,
-    0x503b311e,
-    0x503bb12f,
-    0x503c313a,
-    0x503cb146,
-    0x503d3151,
-    0x503db15c,
-    0x503e3169,
-    0x503eb17e,
-    0x503f318c,
-    0x503fb1a0,
-    0x504031b3,
-    0x5040b1c4,
-    0x504131de,
-    0x5041b1ed,
-    0x504231f6,
-    0x5042b205,
-    0x50433217,
-    0x5043b223,
-    0x5044322b,
-    0x5044b23e,
-    0x5045324f,
-    0x5045b265,
-    0x50463271,
-    0x5046b285,
-    0x50473293,
-    0x5047b2a7,
-    0x504832c1,
-    0x5048b2d5,
-    0x504932eb,
-    0x5049b302,
-    0x504a3314,
-    0x504ab328,
-    0x504b333d,
-    0x504bb354,
-    0x504c3368,
-    0x504cb371,
-    0x504d3379,
-    0x504db388,
-    0x504e3398,
-    0x68321109,
-    0x6832911a,
-    0x6833112a,
-    0x68339138,
-    0x68341145,
-    0x6c3210f8,
-    0x74320a89,
-    0x74328a9b,
-    0x783206e8,
-    0x7832871b,
-    0x7833072d,
-    0x7833873f,
-    0x78340753,
-    0x78348767,
-    0x78350785,
-    0x78358797,
-    0x783607ab,
-    0x78368819,
-    0x7837082b,
-    0x7837883d,
-    0x7838084f,
-    0x78388866,
-    0x7839087d,
-    0x78398894,
-    0x783a08b0,
-    0x783a88cc,
-    0x783b08e8,
-    0x783b88fe,
-    0x783c0914,
-    0x783c892a,
-    0x783d0947,
-    0x783d8956,
-    0x783e0965,
-    0x783e8974,
-    0x783f0990,
-    0x783f899e,
-    0x784009ac,
-    0x784089ba,
-    0x784109c7,
-    0x784186fa,
-    0x784207bf,
-    0x784287dd,
-    0x784307fb,
-    0x80321611,
-};
-
-const size_t kOpenSSLFunctionValuesLen = sizeof(kOpenSSLFunctionValues) / sizeof(kOpenSSLFunctionValues[0]);
-
-const char kOpenSSLFunctionStringData[] =
-    "ASN1_BIT_STRING_set_bit\0"
-    "ASN1_ENUMERATED_set\0"
-    "ASN1_ENUMERATED_to_BN\0"
-    "ASN1_GENERALIZEDTIME_adj\0"
-    "ASN1_INTEGER_set\0"
-    "ASN1_INTEGER_to_BN\0"
-    "ASN1_OBJECT_new\0"
-    "ASN1_PCTX_new\0"
-    "ASN1_STRING_TABLE_add\0"
-    "ASN1_STRING_set\0"
-    "ASN1_STRING_type_new\0"
-    "ASN1_TIME_adj\0"
-    "ASN1_UTCTIME_adj\0"
-    "ASN1_d2i_fp\0"
-    "ASN1_dup\0"
-    "ASN1_generate_v3\0"
-    "ASN1_get_object\0"
-    "ASN1_i2d_bio\0"
-    "ASN1_i2d_fp\0"
-    "ASN1_item_d2i_fp\0"
-    "ASN1_item_dup\0"
-    "ASN1_item_ex_d2i\0"
-    "ASN1_item_i2d_bio\0"
-    "ASN1_item_i2d_fp\0"
-    "ASN1_item_pack\0"
-    "ASN1_item_unpack\0"
-    "ASN1_mbstring_ncopy\0"
-    "ASN1_template_new\0"
-    "BIO_new_NDEF\0"
-    "BN_to_ASN1_ENUMERATED\0"
-    "BN_to_ASN1_INTEGER\0"
-    "a2d_ASN1_OBJECT\0"
-    "a2i_ASN1_ENUMERATED\0"
-    "a2i_ASN1_INTEGER\0"
-    "a2i_ASN1_STRING\0"
-    "append_exp\0"
-    "asn1_cb\0"
-    "asn1_check_tlen\0"
-    "asn1_collate_primitive\0"
-    "asn1_collect\0"
-    "asn1_d2i_ex_primitive\0"
-    "asn1_d2i_read_bio\0"
-    "asn1_do_adb\0"
-    "asn1_ex_c2i\0"
-    "asn1_find_end\0"
-    "asn1_item_ex_combine_new\0"
-    "asn1_str2type\0"
-    "asn1_template_ex_d2i\0"
-    "asn1_template_noexp_d2i\0"
-    "bitstr_cb\0"
-    "c2i_ASN1_BIT_STRING\0"
-    "c2i_ASN1_INTEGER\0"
-    "c2i_ASN1_OBJECT\0"
-    "collect_data\0"
-    "d2i_ASN1_BOOLEAN\0"
-    "d2i_ASN1_OBJECT\0"
-    "d2i_ASN1_UINTEGER\0"
-    "d2i_ASN1_UTCTIME\0"
-    "d2i_ASN1_bytes\0"
-    "d2i_ASN1_type_bytes\0"
-    "i2d_ASN1_TIME\0"
-    "i2d_PrivateKey\0"
-    "long_c2i\0"
-    "parse_tagging\0"
-    "BIO_callback_ctrl\0"
-    "BIO_ctrl\0"
-    "BIO_new\0"
-    "BIO_new_file\0"
-    "BIO_new_mem_buf\0"
-    "BIO_printf\0"
-    "BIO_zero_copy_get_read_buf\0"
-    "BIO_zero_copy_get_read_buf_done\0"
-    "BIO_zero_copy_get_write_buf\0"
-    "BIO_zero_copy_get_write_buf_done\0"
-    "bio_io\0"
-    "bio_make_pair\0"
-    "bio_write\0"
-    "buffer_ctrl\0"
-    "conn_ctrl\0"
-    "conn_state\0"
-    "file_ctrl\0"
-    "file_read\0"
-    "mem_write\0"
-    "BN_CTX_get\0"
-    "BN_CTX_new\0"
-    "BN_CTX_start\0"
-    "BN_bn2dec\0"
-    "BN_bn2hex\0"
-    "BN_div\0"
-    "BN_div_recp\0"
-    "BN_exp\0"
-    "BN_generate_dsa_nonce\0"
-    "BN_generate_prime_ex\0"
-    "BN_lshift\0"
-    "BN_mod_exp2_mont\0"
-    "BN_mod_exp_mont\0"
-    "BN_mod_exp_mont_consttime\0"
-    "BN_mod_exp_mont_word\0"
-    "BN_mod_inverse\0"
-    "BN_mod_inverse_no_branch\0"
-    "BN_mod_lshift_quick\0"
-    "BN_mod_sqrt\0"
-    "BN_new\0"
-    "BN_rand\0"
-    "BN_rand_range\0"
-    "BN_rshift\0"
-    "BN_sqrt\0"
-    "BN_usub\0"
-    "bn_wexpand\0"
-    "mod_exp_recp\0"
-    "BUF_MEM_new\0"
-    "BUF_memdup\0"
-    "BUF_strndup\0"
-    "buf_mem_grow\0"
-    "EVP_AEAD_CTX_init\0"
-    "EVP_AEAD_CTX_init_with_direction\0"
-    "EVP_AEAD_CTX_open\0"
-    "EVP_AEAD_CTX_seal\0"
-    "EVP_CIPHER_CTX_copy\0"
-    "EVP_CIPHER_CTX_ctrl\0"
-    "EVP_CIPHER_CTX_set_key_length\0"
-    "EVP_CipherInit_ex\0"
-    "EVP_DecryptFinal_ex\0"
-    "EVP_EncryptFinal_ex\0"
-    "aead_aes_ctr_hmac_sha256_init\0"
-    "aead_aes_ctr_hmac_sha256_open\0"
-    "aead_aes_ctr_hmac_sha256_seal\0"
-    "aead_aes_gcm_init\0"
-    "aead_aes_gcm_open\0"
-    "aead_aes_gcm_seal\0"
-    "aead_aes_key_wrap_init\0"
-    "aead_aes_key_wrap_open\0"
-    "aead_aes_key_wrap_seal\0"
-    "aead_chacha20_poly1305_init\0"
-    "aead_chacha20_poly1305_open\0"
-    "aead_chacha20_poly1305_seal\0"
-    "aead_rc4_md5_tls_init\0"
-    "aead_rc4_md5_tls_open\0"
-    "aead_rc4_md5_tls_seal\0"
-    "aead_ssl3_ensure_cipher_init\0"
-    "aead_ssl3_init\0"
-    "aead_ssl3_open\0"
-    "aead_ssl3_seal\0"
-    "aead_tls_ensure_cipher_init\0"
-    "aead_tls_init\0"
-    "aead_tls_open\0"
-    "aead_tls_seal\0"
-    "aes_init_key\0"
-    "aesni_init_key\0"
-    "CONF_parse_list\0"
-    "NCONF_load\0"
-    "def_load_bio\0"
-    "str_copy\0"
-    "CRYPTO_get_ex_new_index\0"
-    "CRYPTO_set_ex_data\0"
-    "get_class\0"
-    "get_func_pointers\0"
-    "DH_new_method\0"
-    "compute_key\0"
-    "generate_key\0"
-    "generate_parameters\0"
-    "EVP_DigestInit_ex\0"
-    "EVP_MD_CTX_copy_ex\0"
-    "DSA_new_method\0"
-    "dsa_sig_cb\0"
-    "sign\0"
-    "sign_setup\0"
-    "verify\0"
-    "BN_to_felem\0"
-    "EC_GROUP_copy\0"
-    "EC_GROUP_get_curve_GFp\0"
-    "EC_GROUP_get_degree\0"
-    "EC_GROUP_new_by_curve_name\0"
-    "EC_GROUP_new_curve_GFp\0"
-    "EC_KEY_check_key\0"
-    "EC_KEY_copy\0"
-    "EC_KEY_generate_key\0"
-    "EC_KEY_new_by_curve_name\0"
-    "EC_KEY_new_method\0"
-    "EC_KEY_set_public_key_affine_coordinates\0"
-    "EC_POINT_add\0"
-    "EC_POINT_cmp\0"
-    "EC_POINT_copy\0"
-    "EC_POINT_dbl\0"
-    "EC_POINT_dup\0"
-    "EC_POINT_get_affine_coordinates_GFp\0"
-    "EC_POINT_invert\0"
-    "EC_POINT_is_at_infinity\0"
-    "EC_POINT_is_on_curve\0"
-    "EC_POINT_make_affine\0"
-    "EC_POINT_new\0"
-    "EC_POINT_oct2point\0"
-    "EC_POINT_point2oct\0"
-    "EC_POINT_set_affine_coordinates_GFp\0"
-    "EC_POINT_set_compressed_coordinates_GFp\0"
-    "EC_POINT_set_to_infinity\0"
-    "EC_POINTs_make_affine\0"
-    "compute_wNAF\0"
-    "d2i_ECPKParameters\0"
-    "d2i_ECParameters\0"
-    "d2i_ECPrivateKey\0"
-    "ec_GFp_mont_field_decode\0"
-    "ec_GFp_mont_field_encode\0"
-    "ec_GFp_mont_field_mul\0"
-    "ec_GFp_mont_field_set_to_one\0"
-    "ec_GFp_mont_field_sqr\0"
-    "ec_GFp_mont_group_set_curve\0"
-    "ec_GFp_nistp256_group_set_curve\0"
-    "ec_GFp_nistp256_point_get_affine_coordinates\0"
-    "ec_GFp_nistp256_points_mul\0"
-    "ec_GFp_simple_group_check_discriminant\0"
-    "ec_GFp_simple_group_set_curve\0"
-    "ec_GFp_simple_make_affine\0"
-    "ec_GFp_simple_oct2point\0"
-    "ec_GFp_simple_point2oct\0"
-    "ec_GFp_simple_point_get_affine_coordinates\0"
-    "ec_GFp_simple_point_set_affine_coordinates\0"
-    "ec_GFp_simple_points_make_affine\0"
-    "ec_GFp_simple_set_compressed_coordinates\0"
-    "ec_asn1_group2pkparameters\0"
-    "ec_asn1_pkparameters2group\0"
-    "ec_group_copy\0"
-    "ec_group_new\0"
-    "ec_group_new_curve_GFp\0"
-    "ec_group_new_from_data\0"
-    "ec_point_set_Jprojective_coordinates_GFp\0"
-    "ec_pre_comp_new\0"
-    "ec_wNAF_mul\0"
-    "ec_wNAF_precompute_mult\0"
-    "i2d_ECPKParameters\0"
-    "i2d_ECParameters\0"
-    "i2d_ECPrivateKey\0"
-    "i2o_ECPublicKey\0"
-    "nistp256_pre_comp_new\0"
-    "o2i_ECPublicKey\0"
-    "ECDH_compute_key\0"
-    "ECDSA_do_sign_ex\0"
-    "ECDSA_do_verify\0"
-    "ECDSA_sign_ex\0"
-    "digest_to_bn\0"
-    "ecdsa_sign_setup\0"
-    "EVP_DigestSignAlgorithm\0"
-    "EVP_DigestVerifyInitFromAlgorithm\0"
-    "EVP_PKEY_CTX_ctrl\0"
-    "EVP_PKEY_CTX_dup\0"
-    "EVP_PKEY_CTX_get0_rsa_oaep_label\0"
-    "EVP_PKEY_copy_parameters\0"
-    "EVP_PKEY_decrypt\0"
-    "EVP_PKEY_decrypt_init\0"
-    "EVP_PKEY_derive\0"
-    "EVP_PKEY_derive_init\0"
-    "EVP_PKEY_derive_set_peer\0"
-    "EVP_PKEY_encrypt\0"
-    "EVP_PKEY_encrypt_init\0"
-    "EVP_PKEY_get1_DH\0"
-    "EVP_PKEY_get1_DSA\0"
-    "EVP_PKEY_get1_EC_KEY\0"
-    "EVP_PKEY_get1_RSA\0"
-    "EVP_PKEY_keygen\0"
-    "EVP_PKEY_keygen_init\0"
-    "EVP_PKEY_new\0"
-    "EVP_PKEY_set_type\0"
-    "EVP_PKEY_sign\0"
-    "EVP_PKEY_sign_init\0"
-    "EVP_PKEY_verify\0"
-    "EVP_PKEY_verify_init\0"
-    "check_padding_md\0"
-    "d2i_AutoPrivateKey\0"
-    "d2i_PrivateKey\0"
-    "do_EC_KEY_print\0"
-    "do_dsa_print\0"
-    "do_rsa_print\0"
-    "do_sigver_init\0"
-    "dsa_param_decode\0"
-    "dsa_priv_decode\0"
-    "dsa_priv_encode\0"
-    "dsa_pub_decode\0"
-    "dsa_pub_encode\0"
-    "dsa_sig_print\0"
-    "eckey_param2type\0"
-    "eckey_param_decode\0"
-    "eckey_priv_decode\0"
-    "eckey_priv_encode\0"
-    "eckey_pub_decode\0"
-    "eckey_pub_encode\0"
-    "eckey_type2param\0"
-    "evp_pkey_ctx_new\0"
-    "hmac_signctx\0"
-    "i2d_PublicKey\0"
-    "old_dsa_priv_decode\0"
-    "old_ec_priv_decode\0"
-    "old_rsa_priv_decode\0"
-    "pkey_ec_ctrl\0"
-    "pkey_ec_derive\0"
-    "pkey_ec_keygen\0"
-    "pkey_ec_paramgen\0"
-    "pkey_ec_sign\0"
-    "pkey_hmac_ctrl\0"
-    "pkey_rsa_ctrl\0"
-    "pkey_rsa_decrypt\0"
-    "pkey_rsa_encrypt\0"
-    "pkey_rsa_sign\0"
-    "rsa_algor_to_md\0"
-    "rsa_digest_verify_init_from_algorithm\0"
-    "rsa_mgf1_to_md\0"
-    "rsa_priv_decode\0"
-    "rsa_priv_encode\0"
-    "rsa_pss_to_ctx\0"
-    "rsa_pub_decode\0"
-    "HKDF\0"
-    "OBJ_create\0"
-    "OBJ_dup\0"
-    "OBJ_nid2obj\0"
-    "OBJ_txt2obj\0"
-    "PEM_ASN1_read\0"
-    "PEM_ASN1_read_bio\0"
-    "PEM_ASN1_write\0"
-    "PEM_ASN1_write_bio\0"
-    "PEM_X509_INFO_read\0"
-    "PEM_X509_INFO_read_bio\0"
-    "PEM_X509_INFO_write_bio\0"
-    "PEM_do_header\0"
-    "PEM_get_EVP_CIPHER_INFO\0"
-    "PEM_read\0"
-    "PEM_read_DHparams\0"
-    "PEM_read_PrivateKey\0"
-    "PEM_read_bio\0"
-    "PEM_read_bio_DHparams\0"
-    "PEM_read_bio_Parameters\0"
-    "PEM_read_bio_PrivateKey\0"
-    "PEM_write\0"
-    "PEM_write_PrivateKey\0"
-    "PEM_write_bio\0"
-    "d2i_PKCS8PrivateKey_bio\0"
-    "d2i_PKCS8PrivateKey_fp\0"
-    "do_pk8pkey\0"
-    "do_pk8pkey_fp\0"
-    "load_iv\0"
-    "EVP_PKCS82PKEY\0"
-    "EVP_PKEY2PKCS8\0"
-    "PKCS12_get_key_and_certs\0"
-    "PKCS12_handle_content_info\0"
-    "PKCS12_handle_content_infos\0"
-    "PKCS5_pbe2_set_iv\0"
-    "PKCS5_pbe_set\0"
-    "PKCS5_pbe_set0_algor\0"
-    "PKCS5_pbkdf2_set\0"
-    "PKCS8_decrypt\0"
-    "PKCS8_encrypt\0"
-    "PKCS8_encrypt_pbe\0"
-    "pbe_cipher_init\0"
-    "pbe_crypt\0"
-    "pkcs12_item_decrypt_d2i\0"
-    "pkcs12_item_i2d_encrypt\0"
-    "pkcs12_key_gen_raw\0"
-    "pkcs12_pbe_keyivgen\0"
-    "BN_BLINDING_convert_ex\0"
-    "BN_BLINDING_create_param\0"
-    "BN_BLINDING_invert_ex\0"
-    "BN_BLINDING_new\0"
-    "BN_BLINDING_update\0"
-    "RSA_check_key\0"
-    "RSA_new_method\0"
-    "RSA_padding_add_PKCS1_OAEP_mgf1\0"
-    "RSA_padding_add_PKCS1_PSS_mgf1\0"
-    "RSA_padding_add_PKCS1_type_1\0"
-    "RSA_padding_add_PKCS1_type_2\0"
-    "RSA_padding_add_none\0"
-    "RSA_padding_check_PKCS1_OAEP_mgf1\0"
-    "RSA_padding_check_PKCS1_type_1\0"
-    "RSA_padding_check_PKCS1_type_2\0"
-    "RSA_padding_check_none\0"
-    "RSA_recover_crt_params\0"
-    "RSA_sign\0"
-    "RSA_verify\0"
-    "RSA_verify_PKCS1_PSS_mgf1\0"
-    "decrypt\0"
-    "encrypt\0"
-    "keygen\0"
-    "pkcs1_prefixed_msg\0"
-    "private_transform\0"
-    "rsa_setup_blinding\0"
-    "sign_raw\0"
-    "verify_raw\0"
-    "SSL_AEAD_CTX_new\0"
-    "SSL_AEAD_CTX_open\0"
-    "SSL_AEAD_CTX_seal\0"
-    "SSL_CTX_check_private_key\0"
-    "SSL_CTX_new\0"
-    "SSL_CTX_set1_tls_channel_id\0"
-    "SSL_CTX_set_cipher_list\0"
-    "SSL_CTX_set_cipher_list_tls11\0"
-    "SSL_CTX_set_session_id_context\0"
-    "SSL_CTX_set_tmp_dh\0"
-    "SSL_CTX_set_tmp_ecdh\0"
-    "SSL_CTX_use_PrivateKey\0"
-    "SSL_CTX_use_PrivateKey_ASN1\0"
-    "SSL_CTX_use_PrivateKey_file\0"
-    "SSL_CTX_use_RSAPrivateKey\0"
-    "SSL_CTX_use_RSAPrivateKey_ASN1\0"
-    "SSL_CTX_use_RSAPrivateKey_file\0"
-    "SSL_CTX_use_certificate\0"
-    "SSL_CTX_use_certificate_ASN1\0"
-    "SSL_CTX_use_certificate_chain_file\0"
-    "SSL_CTX_use_certificate_file\0"
-    "SSL_CTX_use_psk_identity_hint\0"
-    "SSL_SESSION_from_bytes\0"
-    "SSL_SESSION_new\0"
-    "SSL_SESSION_parse\0"
-    "SSL_SESSION_parse_octet_string\0"
-    "SSL_SESSION_parse_string\0"
-    "SSL_SESSION_print_fp\0"
-    "SSL_SESSION_set1_id_context\0"
-    "SSL_SESSION_to_bytes_full\0"
-    "SSL_accept\0"
-    "SSL_add_dir_cert_subjects_to_stack\0"
-    "SSL_add_file_cert_subjects_to_stack\0"
-    "SSL_check_private_key\0"
-    "SSL_clear\0"
-    "SSL_connect\0"
-    "SSL_do_handshake\0"
-    "SSL_load_client_CA_file\0"
-    "SSL_new\0"
-    "SSL_peek\0"
-    "SSL_read\0"
-    "SSL_renegotiate\0"
-    "SSL_set1_tls_channel_id\0"
-    "SSL_set_cipher_list\0"
-    "SSL_set_fd\0"
-    "SSL_set_rfd\0"
-    "SSL_set_session_id_context\0"
-    "SSL_set_tlsext_host_name\0"
-    "SSL_set_tmp_dh\0"
-    "SSL_set_tmp_ecdh\0"
-    "SSL_set_wfd\0"
-    "SSL_shutdown\0"
-    "SSL_use_PrivateKey\0"
-    "SSL_use_PrivateKey_ASN1\0"
-    "SSL_use_PrivateKey_file\0"
-    "SSL_use_RSAPrivateKey\0"
-    "SSL_use_RSAPrivateKey_ASN1\0"
-    "SSL_use_RSAPrivateKey_file\0"
-    "SSL_use_certificate\0"
-    "SSL_use_certificate_ASN1\0"
-    "SSL_use_certificate_file\0"
-    "SSL_use_psk_identity_hint\0"
-    "SSL_write\0"
-    "d2i_SSL_SESSION\0"
-    "do_ssl3_write\0"
-    "dtls1_accept\0"
-    "dtls1_buffer_record\0"
-    "dtls1_check_timeout_num\0"
-    "dtls1_connect\0"
-    "dtls1_do_write\0"
-    "dtls1_get_buffered_message\0"
-    "dtls1_get_hello_verify\0"
-    "dtls1_get_message\0"
-    "dtls1_get_message_fragment\0"
-    "dtls1_hm_fragment_new\0"
-    "dtls1_preprocess_fragment\0"
-    "dtls1_process_fragment\0"
-    "dtls1_process_record\0"
-    "dtls1_read_bytes\0"
-    "dtls1_seal_record\0"
-    "dtls1_send_hello_verify_request\0"
-    "dtls1_write_app_data\0"
-    "i2d_SSL_SESSION\0"
-    "ssl3_accept\0"
-    "ssl3_cert_verify_hash\0"
-    "ssl3_check_cert_and_algorithm\0"
-    "ssl3_check_certificate_for_cipher\0"
-    "ssl3_connect\0"
-    "ssl3_ctrl\0"
-    "ssl3_ctx_ctrl\0"
-    "ssl3_digest_cached_records\0"
-    "ssl3_do_change_cipher_spec\0"
-    "ssl3_expect_change_cipher_spec\0"
-    "ssl3_get_cert_status\0"
-    "ssl3_get_cert_verify\0"
-    "ssl3_get_certificate_request\0"
-    "ssl3_get_channel_id\0"
-    "ssl3_get_client_certificate\0"
-    "ssl3_get_client_hello\0"
-    "ssl3_get_client_key_exchange\0"
-    "ssl3_get_finished\0"
-    "ssl3_get_initial_bytes\0"
-    "ssl3_get_message\0"
-    "ssl3_get_new_session_ticket\0"
-    "ssl3_get_next_proto\0"
-    "ssl3_get_record\0"
-    "ssl3_get_server_certificate\0"
-    "ssl3_get_server_done\0"
-    "ssl3_get_server_hello\0"
-    "ssl3_get_server_key_exchange\0"
-    "ssl3_get_v2_client_hello\0"
-    "ssl3_handshake_mac\0"
-    "ssl3_output_cert_chain\0"
-    "ssl3_prf\0"
-    "ssl3_read_bytes\0"
-    "ssl3_read_n\0"
-    "ssl3_record_sequence_update\0"
-    "ssl3_seal_record\0"
-    "ssl3_send_cert_verify\0"
-    "ssl3_send_certificate_request\0"
-    "ssl3_send_channel_id\0"
-    "ssl3_send_client_certificate\0"
-    "ssl3_send_client_hello\0"
-    "ssl3_send_client_key_exchange\0"
-    "ssl3_send_server_certificate\0"
-    "ssl3_send_server_hello\0"
-    "ssl3_send_server_key_exchange\0"
-    "ssl3_setup_read_buffer\0"
-    "ssl3_setup_write_buffer\0"
-    "ssl3_write_bytes\0"
-    "ssl3_write_pending\0"
-    "ssl_add_cert_chain\0"
-    "ssl_add_cert_to_buf\0"
-    "ssl_add_clienthello_renegotiate_ext\0"
-    "ssl_add_clienthello_tlsext\0"
-    "ssl_add_clienthello_use_srtp_ext\0"
-    "ssl_add_serverhello_renegotiate_ext\0"
-    "ssl_add_serverhello_tlsext\0"
-    "ssl_add_serverhello_use_srtp_ext\0"
-    "ssl_build_cert_chain\0"
-    "ssl_bytes_to_cipher_list\0"
-    "ssl_cert_dup\0"
-    "ssl_cert_inst\0"
-    "ssl_cert_new\0"
-    "ssl_check_serverhello_tlsext\0"
-    "ssl_check_srvr_ecc_cert_and_alg\0"
-    "ssl_cipher_process_rulestr\0"
-    "ssl_cipher_strength_sort\0"
-    "ssl_create_cipher_list\0"
-    "ssl_ctx_log_master_secret\0"
-    "ssl_ctx_log_rsa_client_key_exchange\0"
-    "ssl_ctx_make_profiles\0"
-    "ssl_get_new_session\0"
-    "ssl_get_prev_session\0"
-    "ssl_get_server_cert_index\0"
-    "ssl_get_sign_pkey\0"
-    "ssl_init_wbio_buffer\0"
-    "ssl_parse_clienthello_renegotiate_ext\0"
-    "ssl_parse_clienthello_tlsext\0"
-    "ssl_parse_clienthello_use_srtp_ext\0"
-    "ssl_parse_serverhello_renegotiate_ext\0"
-    "ssl_parse_serverhello_tlsext\0"
-    "ssl_parse_serverhello_use_srtp_ext\0"
-    "ssl_scan_clienthello_tlsext\0"
-    "ssl_scan_serverhello_tlsext\0"
-    "ssl_sess_cert_new\0"
-    "ssl_set_cert\0"
-    "ssl_set_pkey\0"
-    "ssl_verify_cert_chain\0"
-    "tls12_check_peer_sigalg\0"
-    "tls1_aead_ctx_init\0"
-    "tls1_cert_verify_mac\0"
-    "tls1_change_cipher_state\0"
-    "tls1_change_cipher_state_aead\0"
-    "tls1_check_duplicate_extensions\0"
-    "tls1_enc\0"
-    "tls1_export_keying_material\0"
-    "tls1_prf\0"
-    "tls1_setup_key_block\0"
-    "ASN1_digest\0"
-    "ASN1_item_sign_ctx\0"
-    "ASN1_item_verify\0"
-    "NETSCAPE_SPKI_b64_decode\0"
-    "NETSCAPE_SPKI_b64_encode\0"
-    "PKCS7_get_CRLs\0"
-    "PKCS7_get_certificates\0"
-    "X509_ATTRIBUTE_create_by_NID\0"
-    "X509_ATTRIBUTE_create_by_OBJ\0"
-    "X509_ATTRIBUTE_create_by_txt\0"
-    "X509_ATTRIBUTE_get0_data\0"
-    "X509_ATTRIBUTE_set1_data\0"
-    "X509_CRL_add0_revoked\0"
-    "X509_CRL_diff\0"
-    "X509_CRL_print_fp\0"
-    "X509_EXTENSION_create_by_NID\0"
-    "X509_EXTENSION_create_by_OBJ\0"
-    "X509_INFO_new\0"
-    "X509_NAME_ENTRY_create_by_NID\0"
-    "X509_NAME_ENTRY_create_by_txt\0"
-    "X509_NAME_ENTRY_set_object\0"
-    "X509_NAME_add_entry\0"
-    "X509_NAME_oneline\0"
-    "X509_NAME_print\0"
-    "X509_PKEY_new\0"
-    "X509_PUBKEY_get\0"
-    "X509_PUBKEY_set\0"
-    "X509_REQ_check_private_key\0"
-    "X509_REQ_to_X509\0"
-    "X509_STORE_CTX_get1_issuer\0"
-    "X509_STORE_CTX_init\0"
-    "X509_STORE_CTX_new\0"
-    "X509_STORE_CTX_purpose_inherit\0"
-    "X509_STORE_add_cert\0"
-    "X509_STORE_add_crl\0"
-    "X509_TRUST_add\0"
-    "X509_TRUST_set\0"
-    "X509_check_private_key\0"
-    "X509_get_pubkey_parameters\0"
-    "X509_load_cert_crl_file\0"
-    "X509_load_cert_file\0"
-    "X509_load_crl_file\0"
-    "X509_print_ex_fp\0"
-    "X509_to_X509_REQ\0"
-    "X509_verify_cert\0"
-    "X509at_add1_attr\0"
-    "X509v3_add_ext\0"
-    "add_cert_dir\0"
-    "by_file_ctrl\0"
-    "check_policy\0"
-    "dir_ctrl\0"
-    "get_cert_by_subject\0"
-    "i2d_DSA_PUBKEY\0"
-    "i2d_EC_PUBKEY\0"
-    "i2d_RSA_PUBKEY\0"
-    "pkcs7_parse_header\0"
-    "x509_name_encode\0"
-    "x509_name_ex_d2i\0"
-    "x509_name_ex_new\0"
-    "SXNET_add_id_INTEGER\0"
-    "SXNET_add_id_asc\0"
-    "SXNET_add_id_ulong\0"
-    "SXNET_get_id_asc\0"
-    "SXNET_get_id_ulong\0"
-    "X509V3_EXT_add\0"
-    "X509V3_EXT_add_alias\0"
-    "X509V3_EXT_free\0"
-    "X509V3_EXT_i2d\0"
-    "X509V3_EXT_nconf\0"
-    "X509V3_add1_i2d\0"
-    "X509V3_add_value\0"
-    "X509V3_get_section\0"
-    "X509V3_get_string\0"
-    "X509V3_get_value_bool\0"
-    "X509V3_parse_list\0"
-    "X509_PURPOSE_add\0"
-    "X509_PURPOSE_set\0"
-    "a2i_GENERAL_NAME\0"
-    "copy_email\0"
-    "copy_issuer\0"
-    "do_dirname\0"
-    "do_ext_i2d\0"
-    "do_ext_nconf\0"
-    "gnames_from_sectname\0"
-    "hex_to_string\0"
-    "i2s_ASN1_ENUMERATED\0"
-    "i2s_ASN1_IA5STRING\0"
-    "i2s_ASN1_INTEGER\0"
-    "i2v_AUTHORITY_INFO_ACCESS\0"
-    "notice_section\0"
-    "nref_nos\0"
-    "policy_section\0"
-    "process_pci_value\0"
-    "r2i_certpol\0"
-    "r2i_pci\0"
-    "s2i_ASN1_IA5STRING\0"
-    "s2i_ASN1_INTEGER\0"
-    "s2i_ASN1_OCTET_STRING\0"
-    "s2i_skey_id\0"
-    "set_dist_point_name\0"
-    "string_to_hex\0"
-    "v2i_ASN1_BIT_STRING\0"
-    "v2i_AUTHORITY_INFO_ACCESS\0"
-    "v2i_AUTHORITY_KEYID\0"
-    "v2i_BASIC_CONSTRAINTS\0"
-    "v2i_EXTENDED_KEY_USAGE\0"
-    "v2i_GENERAL_NAMES\0"
-    "v2i_GENERAL_NAME_ex\0"
-    "v2i_NAME_CONSTRAINTS\0"
-    "v2i_POLICY_CONSTRAINTS\0"
-    "v2i_POLICY_MAPPINGS\0"
-    "v2i_crld\0"
-    "v2i_idp\0"
-    "v2i_issuer_alt\0"
-    "v2i_subject_alt\0"
-    "v3_generic_extension\0"
-    "";
-
 const uint32_t kOpenSSLReasonValues[] = {
     0xc3207ba,
-    0xc3287c7,
-    0xc3307d6,
-    0xc3387e6,
-    0xc3407f5,
-    0xc34880e,
-    0xc35081a,
-    0xc358837,
-    0xc360849,
-    0xc368857,
-    0xc370867,
-    0xc378874,
-    0xc380884,
-    0xc38888f,
-    0xc3908a5,
-    0xc3988b4,
-    0xc3a08c8,
-    0x1032146b,
-    0x10329477,
-    0x10331490,
-    0x103394a3,
-    0x10340dd4,
-    0x103494b6,
-    0x103514cb,
-    0x103594de,
-    0x103614f7,
-    0x1036950c,
-    0x1037152a,
-    0x10379539,
-    0x10381555,
-    0x10389570,
-    0x1039157f,
-    0x1039959b,
-    0x103a15b6,
-    0x103a95cd,
-    0x103b15de,
-    0x103b95f2,
-    0x103c1611,
-    0x103c9620,
-    0x103d1637,
-    0x103d964a,
-    0x103e0b5f,
-    0x103e965d,
-    0x103f1670,
-    0x103f968a,
-    0x1040169a,
-    0x104096ae,
-    0x104116c4,
-    0x104196dc,
-    0x104216f1,
-    0x10429705,
-    0x10431717,
+    0xc3287d4,
+    0xc3307e3,
+    0xc3387f3,
+    0xc340802,
+    0xc34881b,
+    0xc350827,
+    0xc358844,
+    0xc360856,
+    0xc368864,
+    0xc370874,
+    0xc378881,
+    0xc380891,
+    0xc38889c,
+    0xc3908b2,
+    0xc3988c1,
+    0xc3a08d5,
+    0xc3a87c7,
+    0xc3b00b0,
+    0x10321478,
+    0x10329484,
+    0x1033149d,
+    0x103394b0,
+    0x10340de1,
+    0x103494cf,
+    0x103514e4,
+    0x10359516,
+    0x1036152f,
+    0x10369544,
+    0x10371562,
+    0x10379571,
+    0x1038158d,
+    0x103895a8,
+    0x103915b7,
+    0x103995d3,
+    0x103a15ee,
+    0x103a9605,
+    0x103b1616,
+    0x103b962a,
+    0x103c1649,
+    0x103c9658,
+    0x103d166f,
+    0x103d9682,
+    0x103e0b6c,
+    0x103e96b3,
+    0x103f16c6,
+    0x103f96e0,
+    0x104016f0,
+    0x10409704,
+    0x1041171a,
+    0x10419732,
+    0x10421747,
+    0x1042975b,
+    0x1043176d,
     0x104385d0,
-    0x104408b4,
-    0x1044972c,
-    0x10451743,
-    0x10459758,
-    0x10461766,
-    0x14320b42,
-    0x14328b50,
-    0x14330b5f,
-    0x14338b71,
+    0x104408c1,
+    0x10449782,
+    0x10451799,
+    0x104597ae,
+    0x104617bc,
+    0x10469695,
+    0x104714f7,
+    0x104787c7,
+    0x104800b0,
+    0x104894c3,
+    0x14320b4f,
+    0x14328b5d,
+    0x14330b6c,
+    0x14338b7e,
     0x18320083,
-    0x18328e3a,
-    0x18340e68,
-    0x18348e7c,
-    0x18358eb3,
-    0x18368ee0,
-    0x18370ef3,
-    0x18378f07,
-    0x18380f2b,
-    0x18388f39,
-    0x18390f4f,
-    0x18398f63,
-    0x183a0f73,
-    0x183b0f83,
-    0x183b8f98,
-    0x183c8fc3,
-    0x183d0fd7,
-    0x183d8fe7,
-    0x183e0b8e,
-    0x183e8ff4,
-    0x183f1006,
-    0x183f9011,
-    0x18401021,
-    0x18409032,
-    0x18411043,
-    0x18419055,
-    0x1842107e,
-    0x184290b0,
-    0x184310bf,
-    0x18451128,
-    0x1845913e,
-    0x18461159,
-    0x18468ecb,
-    0x184709cc,
+    0x18328e47,
+    0x18340e75,
+    0x18348e89,
+    0x18358ec0,
+    0x18368eed,
+    0x18370f00,
+    0x18378f14,
+    0x18380f38,
+    0x18388f46,
+    0x18390f5c,
+    0x18398f70,
+    0x183a0f80,
+    0x183b0f90,
+    0x183b8fa5,
+    0x183c8fd0,
+    0x183d0fe4,
+    0x183d8ff4,
+    0x183e0b9b,
+    0x183e9001,
+    0x183f1013,
+    0x183f901e,
+    0x1840102e,
+    0x1840903f,
+    0x18411050,
+    0x18419062,
+    0x1842108b,
+    0x184290bd,
+    0x184310cc,
+    0x18451135,
+    0x1845914b,
+    0x18461166,
+    0x18468ed8,
+    0x184709d9,
     0x18478094,
-    0x18480faf,
-    0x184890f4,
-    0x18490e50,
-    0x18498e91,
-    0x184a118f,
-    0x184a910c,
-    0x184b10d3,
-    0x184b8e2a,
-    0x184c1097,
+    0x18480fbc,
+    0x18489101,
+    0x18490e5d,
+    0x18498e9e,
+    0x184a119c,
+    0x184a9119,
+    0x184b10e0,
+    0x184b8e37,
+    0x184c10a4,
     0x184c866b,
-    0x184d1174,
-    0x203211b6,
-    0x243211c2,
-    0x243288fa,
-    0x243311d4,
-    0x243391e1,
-    0x243411ee,
-    0x24349200,
-    0x2435120f,
-    0x2435922c,
-    0x24361239,
-    0x24369247,
-    0x24371255,
-    0x24379263,
-    0x2438126c,
-    0x24389279,
-    0x2439128c,
-    0x28320b82,
-    0x28328b8e,
-    0x28330b5f,
-    0x28338ba1,
-    0x2c322ab3,
-    0x2c32aac1,
-    0x2c332ad3,
-    0x2c33aae5,
-    0x2c342af9,
-    0x2c34ab0b,
-    0x2c352b26,
-    0x2c35ab38,
-    0x2c362b4b,
+    0x184d1181,
+    0x203211c3,
+    0x243211cf,
+    0x24328907,
+    0x243311e1,
+    0x243391ee,
+    0x243411fb,
+    0x2434920d,
+    0x2435121c,
+    0x24359239,
+    0x24361246,
+    0x24369254,
+    0x24371262,
+    0x24379270,
+    0x24381279,
+    0x24389286,
+    0x24391299,
+    0x28320b8f,
+    0x28328b9b,
+    0x28330b6c,
+    0x28338bae,
+    0x2c322bfd,
+    0x2c32ac0b,
+    0x2c332c1d,
+    0x2c33ac2f,
+    0x2c342c43,
+    0x2c34ac55,
+    0x2c352c70,
+    0x2c35ac82,
+    0x2c362c95,
     0x2c3682f3,
-    0x2c372b58,
-    0x2c37ab6a,
-    0x2c382b7d,
-    0x2c38ab8b,
-    0x2c392b9b,
-    0x2c39abad,
-    0x2c3a2bc1,
-    0x2c3aabd2,
-    0x2c3b134c,
-    0x2c3babe3,
-    0x2c3c2bf7,
-    0x2c3cac0d,
-    0x2c3d2c26,
-    0x2c3dac54,
-    0x2c3e2c62,
-    0x2c3eac7a,
-    0x2c3f2c92,
-    0x2c3fac9f,
-    0x2c402cc2,
-    0x2c40ace1,
-    0x2c4111b6,
-    0x2c41acf2,
-    0x2c422d05,
-    0x2c429128,
-    0x2c432d16,
+    0x2c372ca2,
+    0x2c37acb4,
+    0x2c382cc7,
+    0x2c38acd5,
+    0x2c392ce5,
+    0x2c39acf7,
+    0x2c3a2d0b,
+    0x2c3aad1c,
+    0x2c3b1359,
+    0x2c3bad2d,
+    0x2c3c2d41,
+    0x2c3cad57,
+    0x2c3d2d70,
+    0x2c3dad9e,
+    0x2c3e2dac,
+    0x2c3eadc4,
+    0x2c3f2ddc,
+    0x2c3fade9,
+    0x2c402e0c,
+    0x2c40ae2b,
+    0x2c4111c3,
+    0x2c41ae3c,
+    0x2c422e4f,
+    0x2c429135,
+    0x2c432e60,
     0x2c4386a2,
-    0x2c442c43,
+    0x2c442d8d,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -1673,248 +314,257 @@
     0x305c8687,
     0x305d0698,
     0x305d86a2,
-    0x34320abc,
-    0x34328ad0,
-    0x34330aed,
-    0x34338b00,
-    0x34340b0f,
-    0x34348b2c,
+    0x34320ac9,
+    0x34328add,
+    0x34330afa,
+    0x34338b0d,
+    0x34340b1c,
+    0x34348b39,
     0x3c320083,
-    0x3c328bcb,
-    0x3c330be4,
-    0x3c338bff,
-    0x3c340c1c,
-    0x3c348c37,
-    0x3c350c52,
-    0x3c358c67,
-    0x3c360c80,
-    0x3c368c98,
-    0x3c370ca9,
-    0x3c378cb7,
-    0x3c380cc4,
-    0x3c388cd8,
-    0x3c390b8e,
-    0x3c398cec,
-    0x3c3a0d00,
-    0x3c3a8874,
-    0x3c3b0d10,
-    0x3c3b8d2b,
-    0x3c3c0d3d,
-    0x3c3c8d53,
-    0x3c3d0d5d,
-    0x3c3d8d71,
-    0x3c3e0d7f,
-    0x3c3e8da4,
-    0x3c3f0bb7,
-    0x3c3f8d8d,
-    0x4032177d,
-    0x40329793,
-    0x403317c1,
-    0x403397cb,
-    0x403417e2,
-    0x40349800,
-    0x40351810,
-    0x40359822,
-    0x4036182f,
-    0x4036983b,
-    0x40371850,
-    0x40379865,
-    0x40381877,
-    0x40389882,
-    0x40391894,
-    0x40398dd4,
-    0x403a18a4,
-    0x403a98b7,
-    0x403b18d8,
-    0x403b98e9,
-    0x403c18f9,
+    0x3c328bd8,
+    0x3c330bf1,
+    0x3c338c0c,
+    0x3c340c29,
+    0x3c348c44,
+    0x3c350c5f,
+    0x3c358c74,
+    0x3c360c8d,
+    0x3c368ca5,
+    0x3c370cb6,
+    0x3c378cc4,
+    0x3c380cd1,
+    0x3c388ce5,
+    0x3c390b9b,
+    0x3c398cf9,
+    0x3c3a0d0d,
+    0x3c3a8881,
+    0x3c3b0d1d,
+    0x3c3b8d38,
+    0x3c3c0d4a,
+    0x3c3c8d60,
+    0x3c3d0d6a,
+    0x3c3d8d7e,
+    0x3c3e0d8c,
+    0x3c3e8db1,
+    0x3c3f0bc4,
+    0x3c3f8d9a,
+    0x403217d3,
+    0x403297e9,
+    0x40331817,
+    0x40339821,
+    0x40341838,
+    0x40349856,
+    0x40351866,
+    0x40359878,
+    0x40361885,
+    0x40369891,
+    0x403718a6,
+    0x403798bb,
+    0x403818cd,
+    0x403898d8,
+    0x403918ea,
+    0x40398de1,
+    0x403a18fa,
+    0x403a990d,
+    0x403b192e,
+    0x403b993f,
+    0x403c194f,
     0x403c8064,
-    0x403d1905,
-    0x403d9921,
-    0x403e1937,
-    0x403e9946,
-    0x403f1959,
-    0x403f9973,
-    0x40401981,
-    0x40409996,
-    0x404119aa,
-    0x404199c7,
-    0x404219e0,
-    0x404299fb,
-    0x40431a14,
-    0x40439a27,
-    0x40441a3b,
-    0x40449a53,
-    0x40451a63,
-    0x40459a71,
-    0x40461a8f,
+    0x403d195b,
+    0x403d9977,
+    0x403e198d,
+    0x403e999c,
+    0x403f19af,
+    0x403f99c9,
+    0x404019d7,
+    0x404099ec,
+    0x40411a00,
+    0x40419a1d,
+    0x40421a36,
+    0x40429a51,
+    0x40431a6a,
+    0x40439a7d,
+    0x40441a91,
+    0x40449aa9,
+    0x40451af4,
+    0x40459b02,
+    0x40461b20,
     0x40468094,
-    0x40471aa4,
-    0x40479ab6,
-    0x40481ada,
-    0x40489afa,
-    0x40491b0e,
-    0x40499b23,
-    0x404a1b3c,
-    0x404a9b76,
-    0x404b1b90,
-    0x404b9bae,
-    0x404c1bc9,
-    0x404c9be3,
-    0x404d1bfa,
-    0x404d9c22,
-    0x404e1c39,
-    0x404e9c55,
-    0x404f1c71,
-    0x404f9c92,
-    0x40501cb4,
-    0x40509cd0,
-    0x40511ce4,
-    0x40519cf1,
-    0x40521d08,
-    0x40529d18,
-    0x40531d28,
-    0x40539d3c,
-    0x40541d57,
-    0x40549d67,
-    0x40551d7e,
-    0x40559d8d,
-    0x40561da8,
-    0x40569dc0,
-    0x40571ddc,
-    0x40579df5,
-    0x40581e08,
-    0x40589e1d,
-    0x40591e40,
-    0x40599e4e,
-    0x405a1e5b,
-    0x405a9e74,
-    0x405b1e8c,
-    0x405b9e9f,
-    0x405c1eb4,
-    0x405c9ec6,
-    0x405d1edb,
-    0x405d9eeb,
-    0x405e1f04,
-    0x405e9f18,
-    0x405f1f28,
-    0x405f9f40,
-    0x40601f51,
-    0x40609f64,
-    0x40611f75,
-    0x40619f93,
-    0x40621fa4,
-    0x40629fb1,
-    0x40631fc8,
-    0x4063a009,
-    0x40642020,
-    0x4064a02d,
-    0x4065203b,
-    0x4065a05d,
-    0x40662085,
-    0x4066a09a,
-    0x406720b1,
-    0x4067a0c2,
-    0x406820d3,
-    0x4068a0e4,
-    0x406920f9,
-    0x4069a110,
-    0x406a2121,
-    0x406aa13a,
-    0x406b2155,
-    0x406ba16c,
-    0x406c21d9,
-    0x406ca1fa,
-    0x406d220d,
-    0x406da22e,
-    0x406e2249,
-    0x406ea264,
-    0x406f2285,
-    0x406fa2ab,
-    0x407022cb,
-    0x4070a2e7,
-    0x40712474,
-    0x4071a497,
-    0x407224ad,
-    0x4072a4cc,
-    0x407324e4,
-    0x4073a504,
-    0x4074272e,
-    0x4074a753,
-    0x4075276e,
-    0x4075a78d,
-    0x407627bc,
-    0x4076a7e4,
-    0x407727fd,
-    0x4077a81c,
-    0x40782841,
-    0x4078a858,
-    0x4079286b,
-    0x4079a888,
+    0x40471b35,
+    0x40479b47,
+    0x40481b6b,
+    0x40489b8b,
+    0x40491b9f,
+    0x40499bb4,
+    0x404a1bcd,
+    0x404a9c07,
+    0x404b1c38,
+    0x404b9c6e,
+    0x404c1c89,
+    0x404c9ca3,
+    0x404d1cba,
+    0x404d9ce2,
+    0x404e1cf9,
+    0x404e9d15,
+    0x404f1d31,
+    0x404f9d52,
+    0x40501d74,
+    0x40509d90,
+    0x40511da4,
+    0x40519db1,
+    0x40521dc8,
+    0x40529dd8,
+    0x40531de8,
+    0x40539dfc,
+    0x40541e17,
+    0x40549e27,
+    0x40551e3e,
+    0x40559e4d,
+    0x40561e7a,
+    0x40569e92,
+    0x40571eae,
+    0x40579ec7,
+    0x40581eda,
+    0x40589eef,
+    0x40591f12,
+    0x40599f3d,
+    0x405a1f4a,
+    0x405a9f63,
+    0x405b1f7b,
+    0x405b9f8e,
+    0x405c1fa3,
+    0x405c9fb5,
+    0x405d1fca,
+    0x405d9fda,
+    0x405e1ff3,
+    0x405ea007,
+    0x405f2017,
+    0x405fa02f,
+    0x40602040,
+    0x4060a053,
+    0x40612064,
+    0x4061a082,
+    0x40622093,
+    0x4062a0a0,
+    0x406320b7,
+    0x4063a0f8,
+    0x4064210f,
+    0x4064a11c,
+    0x4065212a,
+    0x4065a14c,
+    0x40662174,
+    0x4066a189,
+    0x406721a0,
+    0x4067a1b1,
+    0x406821c2,
+    0x4068a1d3,
+    0x406921e8,
+    0x4069a1ff,
+    0x406a2210,
+    0x406aa229,
+    0x406b2244,
+    0x406ba25b,
+    0x406c22c8,
+    0x406ca2e9,
+    0x406d22fc,
+    0x406da31d,
+    0x406e2338,
+    0x406ea381,
+    0x406f23a2,
+    0x406fa3c8,
+    0x407023e8,
+    0x4070a404,
+    0x40712591,
+    0x4071a5b4,
+    0x407225ca,
+    0x4072a5e9,
+    0x40732601,
+    0x4073a621,
+    0x4074284b,
+    0x4074a870,
+    0x4075288b,
+    0x4075a8aa,
+    0x407628d9,
+    0x4076a901,
+    0x40772932,
+    0x4077a951,
+    0x4078298b,
+    0x4078a9a2,
+    0x407929b5,
+    0x4079a9d2,
     0x407a0782,
-    0x407aa89a,
-    0x407b28ad,
-    0x407ba8c6,
-    0x407c28de,
-    0x407c90b0,
-    0x407d28f2,
-    0x407da90c,
-    0x407e291d,
-    0x407ea931,
-    0x407f293f,
-    0x407fa95a,
-    0x40801279,
-    0x4080a97f,
-    0x408129a1,
-    0x4081a9bc,
-    0x408229d1,
-    0x4082a9e9,
-    0x40832a01,
-    0x4083aa18,
-    0x40842a2e,
-    0x4084aa3a,
-    0x40852a4d,
-    0x4085aa62,
-    0x40862a74,
-    0x4086aa89,
-    0x40872a92,
-    0x40879c10,
+    0x407aa9e4,
+    0x407b29f7,
+    0x407baa10,
+    0x407c2a28,
+    0x407c90bd,
+    0x407d2a3c,
+    0x407daa56,
+    0x407e2a67,
+    0x407eaa7b,
+    0x407f2a89,
+    0x407faaa4,
+    0x40801286,
+    0x4080aac9,
+    0x40812aeb,
+    0x4081ab06,
+    0x40822b1b,
+    0x4082ab33,
+    0x40832b4b,
+    0x4083ab62,
+    0x40842b78,
+    0x4084ab84,
+    0x40852b97,
+    0x4085abac,
+    0x40862bbe,
+    0x4086abd3,
+    0x40872bdc,
+    0x40879cd0,
     0x40880083,
-    0x40889fe8,
-    0x40890a0a,
-    0x4089a184,
-    0x408a1b5f,
-    0x408aa1ae,
-    0x41f4239f,
-    0x41f92431,
-    0x41fe2324,
-    0x41fea555,
-    0x41ff2646,
-    0x420323b8,
-    0x420823da,
-    0x4208a416,
-    0x42092308,
-    0x4209a450,
-    0x420a235f,
-    0x420aa33f,
-    0x420b237f,
-    0x420ba3f8,
-    0x420c2662,
-    0x420ca522,
-    0x420d253c,
-    0x420da573,
-    0x4212258d,
-    0x42172629,
-    0x4217a5cf,
-    0x421c25f1,
-    0x421f25ac,
-    0x42212679,
-    0x4226260c,
-    0x422b2712,
-    0x422ba6db,
-    0x422c26fa,
-    0x422ca6b5,
-    0x422d2694,
+    0x4088a0d7,
+    0x40890a17,
+    0x4089a273,
+    0x408a1bf0,
+    0x408aa29d,
+    0x408b291a,
+    0x408ba976,
+    0x408c2353,
+    0x408c9c21,
+    0x408d1c56,
+    0x408d9e68,
+    0x408e1ab9,
+    0x408e9add,
+    0x408f1f20,
+    0x41f424bc,
+    0x41f9254e,
+    0x41fe2441,
+    0x41fea672,
+    0x41ff2763,
+    0x420324d5,
+    0x420824f7,
+    0x4208a533,
+    0x42092425,
+    0x4209a56d,
+    0x420a247c,
+    0x420aa45c,
+    0x420b249c,
+    0x420ba515,
+    0x420c277f,
+    0x420ca63f,
+    0x420d2659,
+    0x420da690,
+    0x421226aa,
+    0x42172746,
+    0x4217a6ec,
+    0x421c270e,
+    0x421f26c9,
+    0x42212796,
+    0x42262729,
+    0x422b282f,
+    0x422ba7f8,
+    0x422c2817,
+    0x422ca7d2,
+    0x422d27b1,
     0x443206ad,
     0x443286bc,
     0x443306c8,
@@ -1932,130 +582,131 @@
     0x44390782,
     0x44398790,
     0x443a07a3,
-    0x4c3212a3,
-    0x4c3292b3,
-    0x4c3312c6,
-    0x4c3392e6,
+    0x4c3212b0,
+    0x4c3292c0,
+    0x4c3312d3,
+    0x4c3392f3,
     0x4c340094,
     0x4c3480b0,
-    0x4c3512f2,
-    0x4c359300,
-    0x4c36131c,
-    0x4c36932f,
-    0x4c37133e,
-    0x4c37934c,
-    0x4c381361,
-    0x4c38936d,
-    0x4c39138d,
-    0x4c3993b7,
-    0x4c3a13d0,
-    0x4c3a93e9,
+    0x4c3512ff,
+    0x4c35930d,
+    0x4c361329,
+    0x4c36933c,
+    0x4c37134b,
+    0x4c379359,
+    0x4c38136e,
+    0x4c38937a,
+    0x4c39139a,
+    0x4c3993c4,
+    0x4c3a13dd,
+    0x4c3a93f6,
     0x4c3b05d0,
-    0x4c3b9402,
-    0x4c3c1414,
-    0x4c3c9423,
-    0x4c3d10b0,
-    0x4c3d943c,
-    0x4c3e1449,
-    0x50322d28,
-    0x5032ad37,
-    0x50332d42,
-    0x5033ad52,
-    0x50342d6b,
-    0x5034ad85,
-    0x50352d93,
-    0x5035ada9,
-    0x50362dbb,
-    0x5036add1,
-    0x50372dea,
-    0x5037adfd,
-    0x50382e15,
-    0x5038ae26,
-    0x50392e3b,
-    0x5039ae4f,
-    0x503a2e6f,
-    0x503aae85,
-    0x503b2e9d,
-    0x503baeaf,
-    0x503c2ecb,
-    0x503caee2,
-    0x503d2efb,
-    0x503daf11,
-    0x503e2f1e,
-    0x503eaf34,
-    0x503f2f46,
+    0x4c3b940f,
+    0x4c3c1421,
+    0x4c3c9430,
+    0x4c3d10bd,
+    0x4c3d9449,
+    0x4c3e1456,
+    0x50322e72,
+    0x5032ae81,
+    0x50332e8c,
+    0x5033ae9c,
+    0x50342eb5,
+    0x5034aecf,
+    0x50352edd,
+    0x5035aef3,
+    0x50362f05,
+    0x5036af1b,
+    0x50372f34,
+    0x5037af47,
+    0x50382f5f,
+    0x5038af70,
+    0x50392f85,
+    0x5039af99,
+    0x503a2fb9,
+    0x503aafcf,
+    0x503b2fe7,
+    0x503baff9,
+    0x503c3015,
+    0x503cb02c,
+    0x503d3045,
+    0x503db05b,
+    0x503e3068,
+    0x503eb07e,
+    0x503f3090,
     0x503f8348,
-    0x50402f59,
-    0x5040af69,
-    0x50412f83,
-    0x5041af92,
-    0x50422fac,
-    0x5042afc9,
-    0x50432fd9,
-    0x5043afe9,
-    0x50442ff8,
+    0x504030a3,
+    0x5040b0b3,
+    0x504130cd,
+    0x5041b0dc,
+    0x504230f6,
+    0x5042b113,
+    0x50433123,
+    0x5043b133,
+    0x50443142,
     0x50448414,
-    0x5045300c,
-    0x5045b02a,
-    0x5046303d,
-    0x5046b053,
-    0x50473065,
-    0x5047b07a,
-    0x504830a0,
-    0x5048b0ae,
-    0x504930c1,
-    0x5049b0d6,
-    0x504a30ec,
-    0x504ab0fc,
-    0x504b311c,
-    0x504bb12f,
-    0x504c3152,
-    0x504cb180,
-    0x504d3192,
-    0x504db1af,
-    0x504e31ca,
-    0x504eb1e6,
-    0x504f31f8,
-    0x504fb20f,
-    0x5050321e,
+    0x50453156,
+    0x5045b174,
+    0x50463187,
+    0x5046b19d,
+    0x504731af,
+    0x5047b1c4,
+    0x504831ea,
+    0x5048b1f8,
+    0x5049320b,
+    0x5049b220,
+    0x504a3236,
+    0x504ab246,
+    0x504b3266,
+    0x504bb279,
+    0x504c329c,
+    0x504cb2ca,
+    0x504d32dc,
+    0x504db2f9,
+    0x504e3314,
+    0x504eb330,
+    0x504f3342,
+    0x504fb359,
+    0x50503368,
     0x50508687,
-    0x50513231,
-    0x58320e12,
-    0x68320dd4,
-    0x68328b8e,
-    0x68330ba1,
-    0x68338de2,
-    0x68340df2,
-    0x6c320db0,
-    0x6c328b71,
-    0x6c330dbb,
-    0x74320980,
-    0x783208e5,
-    0x783288fa,
-    0x78330906,
+    0x5051337b,
+    0x58320e1f,
+    0x68320de1,
+    0x68328b9b,
+    0x68330bae,
+    0x68338def,
+    0x68340dff,
+    0x683480b0,
+    0x6c320dbd,
+    0x6c328b7e,
+    0x6c330dc8,
+    0x7432098d,
+    0x783208f2,
+    0x78328907,
+    0x78330913,
     0x78338083,
-    0x78340915,
-    0x7834892a,
-    0x78350949,
-    0x7835896b,
-    0x78360980,
-    0x78368996,
-    0x783709a6,
-    0x783789b9,
-    0x783809cc,
-    0x783889de,
-    0x783909eb,
-    0x78398a0a,
-    0x783a0a1f,
-    0x783a8a2d,
-    0x783b0a37,
-    0x783b8a4b,
-    0x783c0a62,
-    0x783c8a77,
-    0x783d0a8e,
-    0x783d8aa3,
-    0x783e09f9,
-    0x803211a5,
+    0x78340922,
+    0x78348937,
+    0x78350956,
+    0x78358978,
+    0x7836098d,
+    0x783689a3,
+    0x783709b3,
+    0x783789c6,
+    0x783809d9,
+    0x783889eb,
+    0x783909f8,
+    0x78398a17,
+    0x783a0a2c,
+    0x783a8a3a,
+    0x783b0a44,
+    0x783b8a58,
+    0x783c0a6f,
+    0x783c8a84,
+    0x783d0a9b,
+    0x783d8ab0,
+    0x783e0a06,
+    0x7c3211b2,
 };
 
 const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -2167,6 +818,7 @@
     "UNSUPPORTED_METHOD\0"
     "WRITE_TO_READ_ONLY_BIO\0"
     "ARG2_LT_ARG3\0"
+    "BAD_ENCODING\0"
     "BAD_RECIPROCAL\0"
     "BIGNUM_TOO_LONG\0"
     "BITS_TOO_SMALL\0"
@@ -2333,8 +985,10 @@
     "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"
     "CRT_PARAMS_ALREADY_GIVEN\0"
     "CRT_VALUES_INCORRECT\0"
     "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\0"
@@ -2352,6 +1006,7 @@
     "INVALID_MESSAGE_LENGTH\0"
     "KEY_SIZE_TOO_SMALL\0"
     "LAST_OCTET_INVALID\0"
+    "MUST_HAVE_AT_LEAST_TWO_PRIMES\0"
     "NO_PUBLIC_EXPONENT\0"
     "NULL_BEFORE_BLOCK_MISSING\0"
     "N_NOT_EQUAL_P_Q\0"
@@ -2402,6 +1057,8 @@
     "CONNECTION_REJECTED\0"
     "CONNECTION_TYPE_NOT_SET\0"
     "COOKIE_MISMATCH\0"
+    "CUSTOM_EXTENSION_CONTENTS_TOO_LARGE\0"
+    "CUSTOM_EXTENSION_ERROR\0"
     "D2I_ECDSA_SIG\0"
     "DATA_BETWEEN_CCS_AND_FINISHED\0"
     "DATA_LENGTH_TOO_LONG\0"
@@ -2414,7 +1071,9 @@
     "EMPTY_SRTP_PROTECTION_PROFILE_LIST\0"
     "EMS_STATE_INCONSISTENT\0"
     "ENCRYPTED_LENGTH_TOO_LONG\0"
+    "ERROR_ADDING_EXTENSION\0"
     "ERROR_IN_RECEIVED_CIPHER_LIST\0"
+    "ERROR_PARSING_EXTENSION\0"
     "EVP_DIGESTSIGNFINAL_FAILED\0"
     "EVP_DIGESTSIGNINIT_FAILED\0"
     "EXCESSIVE_MESSAGE_SIZE\0"
@@ -2437,6 +1096,7 @@
     "LIBRARY_HAS_NO_CIPHERS\0"
     "MISSING_DH_KEY\0"
     "MISSING_ECDSA_SIGNING_CERT\0"
+    "MISSING_EXTENSION\0"
     "MISSING_RSA_CERTIFICATE\0"
     "MISSING_RSA_ENCRYPTING_CERT\0"
     "MISSING_RSA_SIGNING_CERT\0"
@@ -2444,6 +1104,7 @@
     "MISSING_TMP_ECDH_KEY\0"
     "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0"
     "MTU_TOO_SMALL\0"
+    "NEGOTIATED_BOTH_NPN_AND_ALPN\0"
     "NESTED_GROUP\0"
     "NO_CERTIFICATES_RETURNED\0"
     "NO_CERTIFICATE_ASSIGNED\0"
@@ -2489,6 +1150,7 @@
     "SESSION_ID_CONTEXT_UNINITIALIZED\0"
     "SESSION_MAY_NOT_BE_CREATED\0"
     "SIGNATURE_ALGORITHMS_ERROR\0"
+    "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0"
     "SRTP_COULD_NOT_ALLOCATE_PROFILES\0"
     "SRTP_PROTECTION_PROFILE_LIST_TOO_LONG\0"
     "SRTP_UNKNOWN_PROTECTION_PROFILE\0"
@@ -2536,8 +1198,10 @@
     "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
     "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0"
     "TOO_MANY_EMPTY_FRAGMENTS\0"
+    "TOO_MANY_WARNING_ALERTS\0"
     "UNABLE_TO_FIND_ECDH_PARAMETERS\0"
     "UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS\0"
+    "UNEXPECTED_EXTENSION\0"
     "UNEXPECTED_GROUP_CLOSE\0"
     "UNEXPECTED_MESSAGE\0"
     "UNEXPECTED_OPERATOR_IN_GROUP\0"
diff --git a/linux-aarch64/crypto/aes/aesv8-armx.S b/linux-aarch64/crypto/aes/aesv8-armx64.S
similarity index 99%
rename from linux-aarch64/crypto/aes/aesv8-armx.S
rename to linux-aarch64/crypto/aes/aesv8-armx64.S
index 9c63291..fa2abbc 100644
--- a/linux-aarch64/crypto/aes/aesv8-armx.S
+++ b/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
 
 #if __ARM_MAX_ARCH__>=7
 .text
@@ -747,3 +748,4 @@
 	ret
 .size	aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-aarch64/crypto/modes/ghashv8-armx.S b/linux-aarch64/crypto/modes/ghashv8-armx64.S
similarity index 91%
rename from linux-aarch64/crypto/modes/ghashv8-armx.S
rename to linux-aarch64/crypto/modes/ghashv8-armx64.S
index ad19074..8d44667 100644
--- a/linux-aarch64/crypto/modes/ghashv8-armx.S
+++ b/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
 
 .text
 #if !defined(__clang__)
@@ -67,10 +68,10 @@
 #endif
 	ext	v3.16b,v17.16b,v17.16b,#8
 
-	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
+	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
 	eor	v17.16b,v17.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
-	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
+	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
+	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	ext	v17.16b,v0.16b,v2.16b,#8		//Karatsuba post-processing
 	eor	v18.16b,v0.16b,v2.16b
@@ -134,7 +135,7 @@
 #endif
 	ext	v7.16b,v17.16b,v17.16b,#8
 	eor	v3.16b,v3.16b,v0.16b		//I[i]^=Xi
-	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
+	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
 	eor	v17.16b,v17.16b,v7.16b		//Karatsuba pre-processing
 	pmull2	v6.1q,v20.2d,v7.2d
 	b	.Loop_mod2x_v8
@@ -143,14 +144,14 @@
 .Loop_mod2x_v8:
 	ext	v18.16b,v3.16b,v3.16b,#8
 	subs	x3,x3,#32		//is there more data?
-	pmull	v0.1q,v22.1d,v3.1d		//H^2.lo·Xi.lo
+	pmull	v0.1q,v22.1d,v3.1d		//H^2.lo·Xi.lo
 	csel	x12,xzr,x12,lo			//is it time to zero x12?
 
 	pmull	v5.1q,v21.1d,v17.1d
 	eor	v18.16b,v18.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v22.2d,v3.2d		//H^2.hi·Xi.hi
+	pmull2	v2.1q,v22.2d,v3.2d		//H^2.hi·Xi.hi
 	eor	v0.16b,v0.16b,v4.16b		//accumulate
-	pmull2	v1.1q,v21.2d,v18.2d		//(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+	pmull2	v1.1q,v21.2d,v18.2d		//(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
 	ld1	{v16.2d},[x2],x12	//load [rotated] I[i+2]
 
 	eor	v2.16b,v2.16b,v6.16b
@@ -175,7 +176,7 @@
 	ext	v7.16b,v17.16b,v17.16b,#8
 	ext	v3.16b,v16.16b,v16.16b,#8
 	eor	v0.16b,v1.16b,v18.16b
-	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
+	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
 	eor	v3.16b,v3.16b,v2.16b		//accumulate v3.16b early
 
 	ext	v18.16b,v0.16b,v0.16b,#8		//2nd phase of reduction
@@ -196,10 +197,10 @@
 	eor	v3.16b,v3.16b,v0.16b		//inp^=Xi
 	eor	v17.16b,v16.16b,v18.16b		//v17.16b is rotated inp^Xi
 
-	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
+	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
 	eor	v17.16b,v17.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
-	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
+	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
+	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	ext	v17.16b,v0.16b,v2.16b,#8		//Karatsuba post-processing
 	eor	v18.16b,v0.16b,v2.16b
@@ -228,3 +229,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
diff --git a/linux-aarch64/crypto/sha/sha1-armv8.S b/linux-aarch64/crypto/sha/sha1-armv8.S
index ab6aa98..6cf9877 100644
--- a/linux-aarch64/crypto/sha/sha1-armv8.S
+++ b/linux-aarch64/crypto/sha/sha1-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
 
 .text
 
@@ -1211,3 +1212,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
+#endif
\ No newline at end of file
diff --git a/linux-aarch64/crypto/sha/sha256-armv8.S b/linux-aarch64/crypto/sha/sha256-armv8.S
index ec572e9..0fad009 100644
--- a/linux-aarch64/crypto/sha/sha256-armv8.S
+++ b/linux-aarch64/crypto/sha/sha256-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
 
 .text
 
@@ -1141,3 +1142,4 @@
 	ret
 .size	sha256_block_armv8,.-sha256_block_armv8
 .comm	OPENSSL_armcap_P,4,4
+#endif
\ No newline at end of file
diff --git a/linux-aarch64/crypto/sha/sha512-armv8.S b/linux-aarch64/crypto/sha/sha512-armv8.S
index 8fc342a..517c033 100644
--- a/linux-aarch64/crypto/sha/sha512-armv8.S
+++ b/linux-aarch64/crypto/sha/sha512-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
 
 .text
 
@@ -1021,3 +1022,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/aes/aes-armv4.S b/linux-arm/crypto/aes/aes-armv4.S
index 1135020..c4d7065 100644
--- a/linux-arm/crypto/aes/aes-armv4.S
+++ b/linux-arm/crypto/aes/aes-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
 
 @ ====================================================================
 @ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -33,7 +34,7 @@
 
 #if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 #else
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
@@ -1196,3 +1197,4 @@
 .align	2
 
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/aes/aesv8-armx.S b/linux-arm/crypto/aes/aesv8-armx32.S
similarity index 99%
rename from linux-arm/crypto/aes/aesv8-armx.S
rename to linux-arm/crypto/aes/aesv8-armx32.S
index 006300c..6012b0c 100644
--- a/linux-arm/crypto/aes/aesv8-armx.S
+++ b/linux-arm/crypto/aes/aesv8-armx32.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
 
 #if __ARM_MAX_ARCH__>=7
 .text
@@ -752,3 +753,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
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index 204ee3e..85262d5 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
 
 @ ====================================================================
 @ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -48,7 +49,7 @@
 
 #if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 
 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
@@ -2575,3 +2576,4 @@
 .size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
 #endif
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/bn/armv4-mont.S b/linux-arm/crypto/bn/armv4-mont.S
index 81dcbeb..fc671e8 100644
--- a/linux-arm/crypto/bn/armv4-mont.S
+++ b/linux-arm/crypto/bn/armv4-mont.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
 
 .text
 .code	32
@@ -585,3 +586,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index b6c7e9b..f868c2d 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -1,5 +1,6 @@
 #if defined(__arm__)
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
 
 .syntax	unified
 
@@ -537,3 +538,4 @@
 .align	2
 
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/modes/ghashv8-armx.S b/linux-arm/crypto/modes/ghashv8-armx32.S
similarity index 88%
rename from linux-arm/crypto/modes/ghashv8-armx.S
rename to linux-arm/crypto/modes/ghashv8-armx32.S
index 71913fb..9a38ded 100644
--- a/linux-arm/crypto/modes/ghashv8-armx.S
+++ b/linux-arm/crypto/modes/ghashv8-armx32.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
 
 .text
 .fpu	neon
@@ -66,10 +67,10 @@
 #endif
 	vext.8	q3,q9,q9,#8
 
-.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
+.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
 	veor	q9,q9,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
-.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
+.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	vext.8	q9,q0,q2,#8		@ Karatsuba post-processing
 	veor	q10,q0,q2
@@ -134,7 +135,7 @@
 #endif
 	vext.8	q7,q9,q9,#8
 	veor	q3,q3,q0		@ I[i]^=Xi
-.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
+.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
 	veor	q9,q9,q7		@ Karatsuba pre-processing
 .byte	0x8f,0xce,0xa9,0xf2	@ pmull2 q6,q12,q7
 	b	.Loop_mod2x_v8
@@ -143,14 +144,14 @@
 .Loop_mod2x_v8:
 	vext.8	q10,q3,q3,#8
 	subs	r3,r3,#32		@ is there more data?
-.byte	0x86,0x0e,0xac,0xf2	@ pmull q0,q14,q3		@ H^2.lo·Xi.lo
+.byte	0x86,0x0e,0xac,0xf2	@ pmull q0,q14,q3		@ H^2.lo·Xi.lo
 	movlo	r12,#0			@ is it time to zero r12?
 
 .byte	0xa2,0xae,0xaa,0xf2	@ pmull q5,q13,q9
 	veor	q10,q10,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xad,0xf2	@ pmull2 q2,q14,q3		@ H^2.hi·Xi.hi
+.byte	0x87,0x4e,0xad,0xf2	@ pmull2 q2,q14,q3		@ H^2.hi·Xi.hi
 	veor	q0,q0,q4		@ accumulate
-.byte	0xa5,0x2e,0xab,0xf2	@ pmull2 q1,q13,q10		@ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+.byte	0xa5,0x2e,0xab,0xf2	@ pmull2 q1,q13,q10		@ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
 	vld1.64	{q8},[r2],r12	@ load [rotated] I[i+2]
 
 	veor	q2,q2,q6
@@ -175,7 +176,7 @@
 	vext.8	q7,q9,q9,#8
 	vext.8	q3,q8,q8,#8
 	veor	q0,q1,q10
-.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
+.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
 	veor	q3,q3,q2		@ accumulate q3 early
 
 	vext.8	q10,q0,q0,#8		@ 2nd phase of reduction
@@ -196,10 +197,10 @@
 	veor	q3,q3,q0		@ inp^=Xi
 	veor	q9,q8,q10		@ q9 is rotated inp^Xi
 
-.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
+.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
 	veor	q9,q9,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
-.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
+.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	vext.8	q9,q0,q2,#8		@ Karatsuba post-processing
 	veor	q10,q0,q2
@@ -229,3 +230,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
diff --git a/linux-arm/crypto/sha/sha1-armv4-large.S b/linux-arm/crypto/sha/sha1-armv4-large.S
index 52c99bf..66d0ef3 100644
--- a/linux-arm/crypto/sha/sha1-armv4-large.S
+++ b/linux-arm/crypto/sha/sha1-armv4-large.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
 
 .text
 .code	32
@@ -1458,3 +1459,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/sha/sha256-armv4.S b/linux-arm/crypto/sha/sha256-armv4.S
index 114aa43..9fc3e0b 100644
--- a/linux-arm/crypto/sha/sha256-armv4.S
+++ b/linux-arm/crypto/sha/sha256-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
 
 @ ====================================================================
 @ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -37,7 +38,7 @@
 @ Add ARMv8 code path performing at 2.0 cpb on Apple A7.
 
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 #else
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 # define __ARM_MAX_ARCH__ 7
@@ -2814,3 +2815,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-arm/crypto/sha/sha512-armv4.S b/linux-arm/crypto/sha/sha512-armv4.S
index 1a3d467..834ede9 100644
--- a/linux-arm/crypto/sha/sha512-armv4.S
+++ b/linux-arm/crypto/sha/sha512-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
 
 @ ====================================================================
 @ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -46,7 +47,7 @@
 @ was reflected in below two parameters as 0 and 4. Now caller is
 @ expected to maintain native byte order for whole 64-bit values.
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
 #else
@@ -1865,3 +1866,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
+#endif
\ No newline at end of file
diff --git a/linux-x86/crypto/cpu-x86-asm.S b/linux-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index 24a8dd4..0000000
--- a/linux-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,322 +0,0 @@
-#if defined(__i386__)
-.file	"crypto/cpu-x86-asm.S"
-.text
-.globl	OPENSSL_ia32_cpuid
-.hidden	OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,@function
-.align	16
-OPENSSL_ia32_cpuid:
-.L_OPENSSL_ia32_cpuid_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	xorl	%edx,%edx
-	pushfl
-	popl	%eax
-	movl	%eax,%ecx
-	xorl	$2097152,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	xorl	%eax,%ecx
-	xorl	%eax,%eax
-	btl	$21,%ecx
-	jnc	.L000nocpuid
-	movl	20(%esp),%esi
-	movl	%eax,8(%esi)
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%ebp
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%ebp
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%ebp
-	jz	.L001intel
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%esi
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%esi
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%esi
-	jnz	.L001intel
-	movl	$2147483648,%eax
-	.byte	0x0f,0xa2
-	cmpl	$2147483649,%eax
-	jb	.L001intel
-	movl	%eax,%esi
-	movl	$2147483649,%eax
-	.byte	0x0f,0xa2
-	orl	%ecx,%ebp
-	andl	$2049,%ebp
-	cmpl	$2147483656,%esi
-	jb	.L001intel
-	movl	$2147483656,%eax
-	.byte	0x0f,0xa2
-	movzbl	%cl,%esi
-	incl	%esi
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	btl	$28,%edx
-	jnc	.L002generic
-	shrl	$16,%ebx
-	andl	$255,%ebx
-	cmpl	%esi,%ebx
-	ja	.L002generic
-	andl	$4026531839,%edx
-	jmp	.L002generic
-.L001intel:
-	cmpl	$7,%edi
-	jb	.L003cacheinfo
-	movl	20(%esp),%esi
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	movl	%ebx,8(%esi)
-.L003cacheinfo:
-	cmpl	$4,%edi
-	movl	$-1,%edi
-	jb	.L004nocacheinfo
-	movl	$4,%eax
-	movl	$0,%ecx
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	shrl	$14,%edi
-	andl	$4095,%edi
-.L004nocacheinfo:
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	andl	$3220176895,%edx
-	cmpl	$0,%ebp
-	jne	.L005notintel
-	orl	$1073741824,%edx
-.L005notintel:
-	btl	$28,%edx
-	jnc	.L002generic
-	andl	$4026531839,%edx
-	cmpl	$0,%edi
-	je	.L002generic
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	.L002generic
-	andl	$4026531839,%edx
-.L002generic:
-	andl	$2048,%ebp
-	andl	$4294965247,%ecx
-	movl	%edx,%esi
-	orl	%ecx,%ebp
-	btl	$27,%ecx
-	jnc	.L006clear_avx
-	xorl	%ecx,%ecx
-.byte	15,1,208
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	.L007done
-	cmpl	$2,%eax
-	je	.L006clear_avx
-.L008clear_xmm:
-	andl	$4261412861,%ebp
-	andl	$4278190079,%esi
-.L006clear_avx:
-	andl	$4026525695,%ebp
-	movl	20(%esp),%edi
-	andl	$4294967263,8(%edi)
-.L007done:
-	movl	%esi,%eax
-	movl	%ebp,%edx
-.L000nocpuid:
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.size	OPENSSL_ia32_cpuid,.-.L_OPENSSL_ia32_cpuid_begin
-.globl	OPENSSL_rdtsc
-.hidden	OPENSSL_rdtsc
-.type	OPENSSL_rdtsc,@function
-.align	16
-OPENSSL_rdtsc:
-.L_OPENSSL_rdtsc_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	.L009PIC_me_up
-.L009PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L009PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	.L010notsc
-	.byte	0x0f,0x31
-.L010notsc:
-	ret
-.size	OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin
-.globl	OPENSSL_instrument_halt
-.hidden	OPENSSL_instrument_halt
-.type	OPENSSL_instrument_halt,@function
-.align	16
-OPENSSL_instrument_halt:
-.L_OPENSSL_instrument_halt_begin:
-	call	.L011PIC_me_up
-.L011PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L011PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	.L012nohalt
-.long	2421723150
-	andl	$3,%eax
-	jnz	.L012nohalt
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	.L012nohalt
-	.byte	0x0f,0x31
-	pushl	%edx
-	pushl	%eax
-	hlt
-	.byte	0x0f,0x31
-	subl	(%esp),%eax
-	sbbl	4(%esp),%edx
-	addl	$8,%esp
-	ret
-.L012nohalt:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.size	OPENSSL_instrument_halt,.-.L_OPENSSL_instrument_halt_begin
-.globl	OPENSSL_far_spin
-.hidden	OPENSSL_far_spin
-.type	OPENSSL_far_spin,@function
-.align	16
-OPENSSL_far_spin:
-.L_OPENSSL_far_spin_begin:
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	.L013nospin
-	movl	4(%esp),%eax
-	movl	8(%esp),%ecx
-.long	2430111262
-	xorl	%eax,%eax
-	movl	(%ecx),%edx
-	jmp	.L014spin
-.align	16
-.L014spin:
-	incl	%eax
-	cmpl	(%ecx),%edx
-	je	.L014spin
-.long	529567888
-	ret
-.L013nospin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.size	OPENSSL_far_spin,.-.L_OPENSSL_far_spin_begin
-.globl	OPENSSL_wipe_cpu
-.hidden	OPENSSL_wipe_cpu
-.type	OPENSSL_wipe_cpu,@function
-.align	16
-OPENSSL_wipe_cpu:
-.L_OPENSSL_wipe_cpu_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	.L015PIC_me_up
-.L015PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L015PIC_me_up(%ecx),%ecx
-	movl	(%ecx),%ecx
-	btl	$1,(%ecx)
-	jnc	.L016no_x87
-	andl	$83886080,%ecx
-	cmpl	$83886080,%ecx
-	jne	.L017no_sse2
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-.L017no_sse2:
-.long	4007259865,4007259865,4007259865,4007259865,2430851995
-.L016no_x87:
-	leal	4(%esp),%eax
-	ret
-.size	OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin
-.globl	OPENSSL_atomic_add
-.hidden	OPENSSL_atomic_add
-.type	OPENSSL_atomic_add,@function
-.align	16
-OPENSSL_atomic_add:
-.L_OPENSSL_atomic_add_begin:
-	movl	4(%esp),%edx
-	movl	8(%esp),%ecx
-	pushl	%ebx
-	nop
-	movl	(%edx),%eax
-.L018spin:
-	leal	(%eax,%ecx,1),%ebx
-	nop
-.long	447811568
-	jne	.L018spin
-	movl	%ebx,%eax
-	popl	%ebx
-	ret
-.size	OPENSSL_atomic_add,.-.L_OPENSSL_atomic_add_begin
-.globl	OPENSSL_indirect_call
-.hidden	OPENSSL_indirect_call
-.type	OPENSSL_indirect_call,@function
-.align	16
-OPENSSL_indirect_call:
-.L_OPENSSL_indirect_call_begin:
-	pushl	%ebp
-	movl	%esp,%ebp
-	subl	$28,%esp
-	movl	12(%ebp),%ecx
-	movl	%ecx,(%esp)
-	movl	16(%ebp),%edx
-	movl	%edx,4(%esp)
-	movl	20(%ebp),%eax
-	movl	%eax,8(%esp)
-	movl	24(%ebp),%eax
-	movl	%eax,12(%esp)
-	movl	28(%ebp),%eax
-	movl	%eax,16(%esp)
-	movl	32(%ebp),%eax
-	movl	%eax,20(%esp)
-	movl	36(%ebp),%eax
-	movl	%eax,24(%esp)
-	call	*8(%ebp)
-	movl	%ebp,%esp
-	popl	%ebp
-	ret
-.size	OPENSSL_indirect_call,.-.L_OPENSSL_indirect_call_begin
-.globl	OPENSSL_ia32_rdrand
-.hidden	OPENSSL_ia32_rdrand
-.type	OPENSSL_ia32_rdrand,@function
-.align	16
-OPENSSL_ia32_rdrand:
-.L_OPENSSL_ia32_rdrand_begin:
-	movl	$8,%ecx
-.L019loop:
-.byte	15,199,240
-	jc	.L020break
-	loop	.L019loop
-.L020break:
-	cmpl	$0,%eax
-	cmovel	%ecx,%eax
-	ret
-.size	OPENSSL_ia32_rdrand,.-.L_OPENSSL_ia32_rdrand_begin
-.hidden	OPENSSL_ia32cap_P
-#endif
diff --git a/linux-x86_64/crypto/bn/modexp512-x86_64.S b/linux-x86_64/crypto/bn/modexp512-x86_64.S
deleted file mode 100644
index e49a2cb..0000000
--- a/linux-x86_64/crypto/bn/modexp512-x86_64.S
+++ /dev/null
@@ -1,1776 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-.type	MULADD_128x512,@function
-.align	16
-MULADD_128x512:
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,0(%rcx)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	8(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	movq	%r9,8(%rcx)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	.byte	0xf3,0xc3
-.size	MULADD_128x512,.-MULADD_128x512
-.type	mont_reduce,@function
-.align	16
-mont_reduce:
-	leaq	192(%rsp),%rdi
-	movq	32(%rsp),%rsi
-	addq	$576,%rsi
-	leaq	520(%rsp),%rcx
-
-	movq	96(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	movq	(%rcx),%r8
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,0(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	movq	8(%rcx),%r9
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	movq	16(%rcx),%r10
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	movq	24(%rcx),%r11
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	movq	32(%rcx),%r12
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	movq	40(%rcx),%r13
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	movq	48(%rcx),%r14
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	movq	56(%rcx),%r15
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	104(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	movq	%r9,8(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	movq	112(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%r10,16(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%r10
-	movq	120(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,24(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	xorq	%rax,%rax
-
-	addq	64(%rcx),%r8
-	adcq	72(%rcx),%r9
-	adcq	80(%rcx),%r10
-	adcq	88(%rcx),%r11
-	adcq	$0,%rax
-
-
-
-
-	movq	%r8,64(%rdi)
-	movq	%r9,72(%rdi)
-	movq	%r10,%rbp
-	movq	%r11,88(%rdi)
-
-	movq	%rax,384(%rsp)
-
-	movq	0(%rdi),%r8
-	movq	8(%rdi),%r9
-	movq	16(%rdi),%r10
-	movq	24(%rdi),%r11
-
-
-
-
-
-
-
-
-	addq	$80,%rdi
-
-	addq	$64,%rsi
-	leaq	296(%rsp),%rcx
-
-	call	MULADD_128x512
-
-	movq	384(%rsp),%rax
-
-
-	addq	-16(%rdi),%r8
-	adcq	-8(%rdi),%r9
-	movq	%r8,64(%rcx)
-	movq	%r9,72(%rcx)
-
-	adcq	%rax,%rax
-	movq	%rax,384(%rsp)
-
-	leaq	192(%rsp),%rdi
-	addq	$64,%rsi
-
-
-
-
-
-	movq	(%rsi),%r8
-	movq	8(%rsi),%rbx
-
-	movq	(%rcx),%rax
-	mulq	%r8
-	movq	%rax,%rbp
-	movq	%rdx,%r9
-
-	movq	8(%rcx),%rax
-	mulq	%r8
-	addq	%rax,%r9
-
-	movq	(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r9
-
-	movq	%r9,8(%rdi)
-
-
-	subq	$192,%rsi
-
-	movq	(%rcx),%r8
-	movq	8(%rcx),%r9
-
-	call	MULADD_128x512
-
-
-
-
-	movq	0(%rsi),%rax
-	movq	8(%rsi),%rbx
-	movq	16(%rsi),%rdi
-	movq	24(%rsi),%rdx
-
-
-	movq	384(%rsp),%rbp
-
-	addq	64(%rcx),%r8
-	adcq	72(%rcx),%r9
-
-
-	adcq	%rbp,%rbp
-
-
-
-	shlq	$3,%rbp
-	movq	32(%rsp),%rcx
-	addq	%rcx,%rbp
-
-
-	xorq	%rsi,%rsi
-
-	addq	0(%rbp),%r10
-	adcq	64(%rbp),%r11
-	adcq	128(%rbp),%r12
-	adcq	192(%rbp),%r13
-	adcq	256(%rbp),%r14
-	adcq	320(%rbp),%r15
-	adcq	384(%rbp),%r8
-	adcq	448(%rbp),%r9
-
-
-
-	sbbq	$0,%rsi
-
-
-	andq	%rsi,%rax
-	andq	%rsi,%rbx
-	andq	%rsi,%rdi
-	andq	%rsi,%rdx
-
-	movq	$1,%rbp
-	subq	%rax,%r10
-	sbbq	%rbx,%r11
-	sbbq	%rdi,%r12
-	sbbq	%rdx,%r13
-
-
-
-
-	sbbq	$0,%rbp
-
-
-
-	addq	$512,%rcx
-	movq	32(%rcx),%rax
-	movq	40(%rcx),%rbx
-	movq	48(%rcx),%rdi
-	movq	56(%rcx),%rdx
-
-
-
-	andq	%rsi,%rax
-	andq	%rsi,%rbx
-	andq	%rsi,%rdi
-	andq	%rsi,%rdx
-
-
-
-	subq	$1,%rbp
-
-	sbbq	%rax,%r14
-	sbbq	%rbx,%r15
-	sbbq	%rdi,%r8
-	sbbq	%rdx,%r9
-
-
-
-	movq	144(%rsp),%rsi
-	movq	%r10,0(%rsi)
-	movq	%r11,8(%rsi)
-	movq	%r12,16(%rsi)
-	movq	%r13,24(%rsi)
-	movq	%r14,32(%rsi)
-	movq	%r15,40(%rsi)
-	movq	%r8,48(%rsi)
-	movq	%r9,56(%rsi)
-
-	.byte	0xf3,0xc3
-.size	mont_reduce,.-mont_reduce
-.type	mont_mul_a3b,@function
-.align	16
-mont_mul_a3b:
-
-
-
-
-	movq	0(%rdi),%rbp
-
-	movq	%r10,%rax
-	mulq	%rbp
-	movq	%rax,520(%rsp)
-	movq	%rdx,%r10
-	movq	%r11,%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	%r12,%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	%r13,%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	%r14,%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	%r15,%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	%r8,%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	%r9,%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	movq	8(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%r10,528(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%r10
-	movq	16(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,536(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	24(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%r12,544(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	32(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%r13,552(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	40(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%r14,560(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	48(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,568(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	56(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,576(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	%r9,584(%rsp)
-	movq	%r10,592(%rsp)
-	movq	%r11,600(%rsp)
-	movq	%r12,608(%rsp)
-	movq	%r13,616(%rsp)
-	movq	%r14,624(%rsp)
-	movq	%r15,632(%rsp)
-	movq	%r8,640(%rsp)
-
-
-
-
-
-	jmp	mont_reduce
-
-
-.size	mont_mul_a3b,.-mont_mul_a3b
-.type	sqr_reduce,@function
-.align	16
-sqr_reduce:
-	movq	16(%rsp),%rcx
-
-
-
-	movq	%r10,%rbx
-
-	movq	%r11,%rax
-	mulq	%rbx
-	movq	%rax,528(%rsp)
-	movq	%rdx,%r10
-	movq	%r12,%rax
-	mulq	%rbx
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	%r13,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	%r14,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	%r15,%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rsi
-
-	movq	%r10,536(%rsp)
-
-
-
-
-
-	movq	8(%rcx),%rbx
-
-	movq	16(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,544(%rsp)
-
-	movq	%rdx,%r10
-	movq	24(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-	movq	%r12,552(%rsp)
-
-	movq	%rdx,%r10
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%r10,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%r10,%r14
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-
-	movq	%rdx,%r11
-
-
-
-
-	movq	16(%rcx),%rbx
-
-	movq	24(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%r13,560(%rsp)
-
-	movq	%rdx,%r10
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%r10,%r14
-	adcq	$0,%rdx
-	movq	%r14,568(%rsp)
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%r12
-
-
-
-
-
-	movq	24(%rcx),%rbx
-
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,576(%rsp)
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-	movq	%rsi,584(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-
-	movq	%rdx,%r15
-
-
-
-
-	movq	32(%rcx),%rbx
-
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,592(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-	movq	%r12,600(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r11
-
-
-
-
-	movq	40(%rcx),%rbx
-
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,608(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-	movq	%r11,616(%rsp)
-
-	movq	%rdx,%r12
-
-
-
-
-	movq	%r8,%rbx
-
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%r12,624(%rsp)
-
-	movq	%rdx,632(%rsp)
-
-
-	movq	528(%rsp),%r10
-	movq	536(%rsp),%r11
-	movq	544(%rsp),%r12
-	movq	552(%rsp),%r13
-	movq	560(%rsp),%r14
-	movq	568(%rsp),%r15
-
-	movq	24(%rcx),%rax
-	mulq	%rax
-	movq	%rax,%rdi
-	movq	%rdx,%r8
-
-	addq	%r10,%r10
-	adcq	%r11,%r11
-	adcq	%r12,%r12
-	adcq	%r13,%r13
-	adcq	%r14,%r14
-	adcq	%r15,%r15
-	adcq	$0,%r8
-
-	movq	0(%rcx),%rax
-	mulq	%rax
-	movq	%rax,520(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbx,%r10
-	adcq	%rax,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbx
-	movq	%r10,528(%rsp)
-	movq	%r11,536(%rsp)
-
-	movq	16(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbx,%r12
-	adcq	%rax,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbx
-
-	movq	%r12,544(%rsp)
-	movq	%r13,552(%rsp)
-
-	xorq	%rbp,%rbp
-	addq	%rbx,%r14
-	adcq	%rdi,%r15
-	adcq	$0,%rbp
-
-	movq	%r14,560(%rsp)
-	movq	%r15,568(%rsp)
-
-
-
-
-	movq	576(%rsp),%r10
-	movq	584(%rsp),%r11
-	movq	592(%rsp),%r12
-	movq	600(%rsp),%r13
-	movq	608(%rsp),%r14
-	movq	616(%rsp),%r15
-	movq	624(%rsp),%rdi
-	movq	632(%rsp),%rsi
-
-	movq	%r9,%rax
-	mulq	%rax
-	movq	%rax,%r9
-	movq	%rdx,%rbx
-
-	addq	%r10,%r10
-	adcq	%r11,%r11
-	adcq	%r12,%r12
-	adcq	%r13,%r13
-	adcq	%r14,%r14
-	adcq	%r15,%r15
-	adcq	%rdi,%rdi
-	adcq	%rsi,%rsi
-	adcq	$0,%rbx
-
-	addq	%rbp,%r10
-
-	movq	32(%rcx),%rax
-	mulq	%rax
-
-	addq	%r8,%r10
-	adcq	%rax,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbp
-
-	movq	%r10,576(%rsp)
-	movq	%r11,584(%rsp)
-
-	movq	40(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbp,%r12
-	adcq	%rax,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbp
-
-	movq	%r12,592(%rsp)
-	movq	%r13,600(%rsp)
-
-	movq	48(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbp,%r14
-	adcq	%rax,%r15
-	adcq	$0,%rdx
-
-	movq	%r14,608(%rsp)
-	movq	%r15,616(%rsp)
-
-	addq	%rdx,%rdi
-	adcq	%r9,%rsi
-	adcq	$0,%rbx
-
-	movq	%rdi,624(%rsp)
-	movq	%rsi,632(%rsp)
-	movq	%rbx,640(%rsp)
-
-	jmp	mont_reduce
-
-
-.size	sqr_reduce,.-sqr_reduce
-.globl	mod_exp_512
-.hidden mod_exp_512
-.type	mod_exp_512,@function
-mod_exp_512:
-	pushq	%rbp
-	pushq	%rbx
-	pushq	%r12
-	pushq	%r13
-	pushq	%r14
-	pushq	%r15
-
-
-	movq	%rsp,%r8
-	subq	$2688,%rsp
-	andq	$-64,%rsp
-
-
-	movq	%r8,0(%rsp)
-	movq	%rdi,8(%rsp)
-	movq	%rsi,16(%rsp)
-	movq	%rcx,24(%rsp)
-.Lbody:
-
-
-
-	pxor	%xmm4,%xmm4
-	movdqu	0(%rsi),%xmm0
-	movdqu	16(%rsi),%xmm1
-	movdqu	32(%rsi),%xmm2
-	movdqu	48(%rsi),%xmm3
-	movdqa	%xmm4,512(%rsp)
-	movdqa	%xmm4,528(%rsp)
-	movdqa	%xmm4,608(%rsp)
-	movdqa	%xmm4,624(%rsp)
-	movdqa	%xmm0,544(%rsp)
-	movdqa	%xmm1,560(%rsp)
-	movdqa	%xmm2,576(%rsp)
-	movdqa	%xmm3,592(%rsp)
-
-
-	movdqu	0(%rdx),%xmm0
-	movdqu	16(%rdx),%xmm1
-	movdqu	32(%rdx),%xmm2
-	movdqu	48(%rdx),%xmm3
-
-	leaq	384(%rsp),%rbx
-	movq	%rbx,136(%rsp)
-	call	mont_reduce
-
-
-	leaq	448(%rsp),%rcx
-	xorq	%rax,%rax
-	movq	%rax,0(%rcx)
-	movq	%rax,8(%rcx)
-	movq	%rax,24(%rcx)
-	movq	%rax,32(%rcx)
-	movq	%rax,40(%rcx)
-	movq	%rax,48(%rcx)
-	movq	%rax,56(%rcx)
-	movq	%rax,128(%rsp)
-	movq	$1,16(%rcx)
-
-	leaq	640(%rsp),%rbp
-	movq	%rcx,%rsi
-	movq	%rbp,%rdi
-	movq	$8,%rax
-loop_0:
-	movq	(%rcx),%rbx
-	movw	%bx,(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,64(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,128(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,192(%rdi)
-	leaq	8(%rcx),%rcx
-	leaq	256(%rdi),%rdi
-	decq	%rax
-	jnz	loop_0
-	movq	$31,%rax
-	movq	%rax,32(%rsp)
-	movq	%rbp,40(%rsp)
-
-	movq	%rsi,136(%rsp)
-	movq	0(%rsi),%r10
-	movq	8(%rsi),%r11
-	movq	16(%rsi),%r12
-	movq	24(%rsi),%r13
-	movq	32(%rsi),%r14
-	movq	40(%rsi),%r15
-	movq	48(%rsi),%r8
-	movq	56(%rsi),%r9
-init_loop:
-	leaq	384(%rsp),%rdi
-	call	mont_mul_a3b
-	leaq	448(%rsp),%rsi
-	movq	40(%rsp),%rbp
-	addq	$2,%rbp
-	movq	%rbp,40(%rsp)
-	movq	%rsi,%rcx
-	movq	$8,%rax
-loop_1:
-	movq	(%rcx),%rbx
-	movw	%bx,(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,64(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,128(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,192(%rbp)
-	leaq	8(%rcx),%rcx
-	leaq	256(%rbp),%rbp
-	decq	%rax
-	jnz	loop_1
-	movq	32(%rsp),%rax
-	subq	$1,%rax
-	movq	%rax,32(%rsp)
-	jne	init_loop
-
-
-
-	movdqa	%xmm0,64(%rsp)
-	movdqa	%xmm1,80(%rsp)
-	movdqa	%xmm2,96(%rsp)
-	movdqa	%xmm3,112(%rsp)
-
-
-
-
-
-	movl	126(%rsp),%eax
-	movq	%rax,%rdx
-	shrq	$11,%rax
-	andl	$2047,%edx
-	movl	%edx,126(%rsp)
-	leaq	640(%rsp,%rax,2),%rsi
-	movq	8(%rsp),%rdx
-	movq	$4,%rbp
-loop_2:
-	movzwq	192(%rsi),%rbx
-	movzwq	448(%rsi),%rax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	128(%rsi),%bx
-	movw	384(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	64(%rsi),%bx
-	movw	320(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	0(%rsi),%bx
-	movw	256(%rsi),%ax
-	movq	%rbx,0(%rdx)
-	movq	%rax,8(%rdx)
-	leaq	512(%rsi),%rsi
-	leaq	16(%rdx),%rdx
-	subq	$1,%rbp
-	jnz	loop_2
-	movq	$505,48(%rsp)
-
-	movq	8(%rsp),%rcx
-	movq	%rcx,136(%rsp)
-	movq	0(%rcx),%r10
-	movq	8(%rcx),%r11
-	movq	16(%rcx),%r12
-	movq	24(%rcx),%r13
-	movq	32(%rcx),%r14
-	movq	40(%rcx),%r15
-	movq	48(%rcx),%r8
-	movq	56(%rcx),%r9
-	jmp	sqr_2
-
-main_loop_a3b:
-	call	sqr_reduce
-	call	sqr_reduce
-	call	sqr_reduce
-sqr_2:
-	call	sqr_reduce
-	call	sqr_reduce
-
-
-
-	movq	48(%rsp),%rcx
-	movq	%rcx,%rax
-	shrq	$4,%rax
-	movl	64(%rsp,%rax,2),%edx
-	andq	$15,%rcx
-	shrq	%cl,%rdx
-	andq	$31,%rdx
-
-	leaq	640(%rsp,%rdx,2),%rsi
-	leaq	448(%rsp),%rdx
-	movq	%rdx,%rdi
-	movq	$4,%rbp
-loop_3:
-	movzwq	192(%rsi),%rbx
-	movzwq	448(%rsi),%rax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	128(%rsi),%bx
-	movw	384(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	64(%rsi),%bx
-	movw	320(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	0(%rsi),%bx
-	movw	256(%rsi),%ax
-	movq	%rbx,0(%rdx)
-	movq	%rax,8(%rdx)
-	leaq	512(%rsi),%rsi
-	leaq	16(%rdx),%rdx
-	subq	$1,%rbp
-	jnz	loop_3
-	movq	8(%rsp),%rsi
-	call	mont_mul_a3b
-
-
-
-	movq	48(%rsp),%rcx
-	subq	$5,%rcx
-	movq	%rcx,48(%rsp)
-	jge	main_loop_a3b
-
-
-
-end_main_loop_a3b:
-
-
-	movq	8(%rsp),%rdx
-	pxor	%xmm4,%xmm4
-	movdqu	0(%rdx),%xmm0
-	movdqu	16(%rdx),%xmm1
-	movdqu	32(%rdx),%xmm2
-	movdqu	48(%rdx),%xmm3
-	movdqa	%xmm4,576(%rsp)
-	movdqa	%xmm4,592(%rsp)
-	movdqa	%xmm4,608(%rsp)
-	movdqa	%xmm4,624(%rsp)
-	movdqa	%xmm0,512(%rsp)
-	movdqa	%xmm1,528(%rsp)
-	movdqa	%xmm2,544(%rsp)
-	movdqa	%xmm3,560(%rsp)
-	call	mont_reduce
-
-
-
-	movq	8(%rsp),%rax
-	movq	0(%rax),%r8
-	movq	8(%rax),%r9
-	movq	16(%rax),%r10
-	movq	24(%rax),%r11
-	movq	32(%rax),%r12
-	movq	40(%rax),%r13
-	movq	48(%rax),%r14
-	movq	56(%rax),%r15
-
-
-	movq	24(%rsp),%rbx
-	addq	$512,%rbx
-
-	subq	0(%rbx),%r8
-	sbbq	8(%rbx),%r9
-	sbbq	16(%rbx),%r10
-	sbbq	24(%rbx),%r11
-	sbbq	32(%rbx),%r12
-	sbbq	40(%rbx),%r13
-	sbbq	48(%rbx),%r14
-	sbbq	56(%rbx),%r15
-
-
-	movq	0(%rax),%rsi
-	movq	8(%rax),%rdi
-	movq	16(%rax),%rcx
-	movq	24(%rax),%rdx
-	cmovncq	%r8,%rsi
-	cmovncq	%r9,%rdi
-	cmovncq	%r10,%rcx
-	cmovncq	%r11,%rdx
-	movq	%rsi,0(%rax)
-	movq	%rdi,8(%rax)
-	movq	%rcx,16(%rax)
-	movq	%rdx,24(%rax)
-
-	movq	32(%rax),%rsi
-	movq	40(%rax),%rdi
-	movq	48(%rax),%rcx
-	movq	56(%rax),%rdx
-	cmovncq	%r12,%rsi
-	cmovncq	%r13,%rdi
-	cmovncq	%r14,%rcx
-	cmovncq	%r15,%rdx
-	movq	%rsi,32(%rax)
-	movq	%rdi,40(%rax)
-	movq	%rcx,48(%rax)
-	movq	%rdx,56(%rax)
-
-	movq	0(%rsp),%rsi
-	movq	0(%rsi),%r15
-	movq	8(%rsi),%r14
-	movq	16(%rsi),%r13
-	movq	24(%rsi),%r12
-	movq	32(%rsi),%rbx
-	movq	40(%rsi),%rbp
-	leaq	48(%rsi),%rsp
-.Lepilogue:
-	.byte	0xf3,0xc3
-.size	mod_exp_512, . - mod_exp_512
-#endif
diff --git a/linux-x86_64/crypto/cpu-x86_64-asm.S b/linux-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 9eef154..0000000
--- a/linux-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-.globl	OPENSSL_ia32_cpuid
-.hidden OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,@function
-.align	16
-OPENSSL_ia32_cpuid:
-
-
-	movq	%rdi,%rdi
-	movq	%rbx,%r8
-
-	xorl	%eax,%eax
-	movl	%eax,8(%rdi)
-	cpuid
-	movl	%eax,%r11d
-
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%r9d
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%r9d
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%r9d
-	jz	.Lintel
-
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%r10d
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%r10d
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%r10d
-	jnz	.Lintel
-
-
-
-
-	movl	$2147483648,%eax
-	cpuid
-
-
-	cmpl	$2147483649,%eax
-	jb	.Lintel
-	movl	%eax,%r10d
-	movl	$2147483649,%eax
-	cpuid
-
-
-	orl	%ecx,%r9d
-	andl	$2049,%r9d
-
-	cmpl	$2147483656,%r10d
-	jb	.Lintel
-
-	movl	$2147483656,%eax
-	cpuid
-
-	movzbq	%cl,%r10
-	incq	%r10
-
-	movl	$1,%eax
-	cpuid
-
-	btl	$28,%edx
-	jnc	.Lgeneric
-	shrl	$16,%ebx
-	cmpb	%r10b,%bl
-	ja	.Lgeneric
-	andl	$4026531839,%edx
-	jmp	.Lgeneric
-
-.Lintel:
-	cmpl	$4,%r11d
-	movl	$-1,%r10d
-	jb	.Lnocacheinfo
-
-	movl	$4,%eax
-	movl	$0,%ecx
-	cpuid
-	movl	%eax,%r10d
-	shrl	$14,%r10d
-	andl	$4095,%r10d
-
-	cmpl	$7,%r11d
-	jb	.Lnocacheinfo
-
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	cpuid
-	movl	%ebx,8(%rdi)
-
-.Lnocacheinfo:
-	movl	$1,%eax
-	cpuid
-
-	andl	$3220176895,%edx
-	cmpl	$0,%r9d
-	jne	.Lnotintel
-	orl	$1073741824,%edx
-.Lnotintel:
-	btl	$28,%edx
-	jnc	.Lgeneric
-	andl	$4026531839,%edx
-	cmpl	$0,%r10d
-	je	.Lgeneric
-
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	.Lgeneric
-	andl	$4026531839,%edx
-.Lgeneric:
-	andl	$2048,%r9d
-	andl	$4294965247,%ecx
-	orl	%ecx,%r9d
-
-	movl	%edx,%r10d
-	btl	$27,%r9d
-	jnc	.Lclear_avx
-	xorl	%ecx,%ecx
-.byte	0x0f,0x01,0xd0
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	.Ldone
-.Lclear_avx:
-	movl	$4026525695,%eax
-	andl	%eax,%r9d
-	andl	$4294967263,8(%rdi)
-.Ldone:
-	movl	%r9d,4(%rdi)
-	movl	%r10d,0(%rdi)
-	movq	%r8,%rbx
-	.byte	0xf3,0xc3
-.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-#endif
diff --git a/mac-x86/crypto/cpu-x86-asm.S b/mac-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index bfb292c..0000000
--- a/mac-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,309 +0,0 @@
-#if defined(__i386__)
-.file	"crypto/cpu-x86-asm.S"
-.text
-.globl	_OPENSSL_ia32_cpuid
-.private_extern	_OPENSSL_ia32_cpuid
-.align	4
-_OPENSSL_ia32_cpuid:
-L_OPENSSL_ia32_cpuid_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	xorl	%edx,%edx
-	pushfl
-	popl	%eax
-	movl	%eax,%ecx
-	xorl	$2097152,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	xorl	%eax,%ecx
-	xorl	%eax,%eax
-	btl	$21,%ecx
-	jnc	L000nocpuid
-	movl	20(%esp),%esi
-	movl	%eax,8(%esi)
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%ebp
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%ebp
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%ebp
-	jz	L001intel
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%esi
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%esi
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%esi
-	jnz	L001intel
-	movl	$2147483648,%eax
-	.byte	0x0f,0xa2
-	cmpl	$2147483649,%eax
-	jb	L001intel
-	movl	%eax,%esi
-	movl	$2147483649,%eax
-	.byte	0x0f,0xa2
-	orl	%ecx,%ebp
-	andl	$2049,%ebp
-	cmpl	$2147483656,%esi
-	jb	L001intel
-	movl	$2147483656,%eax
-	.byte	0x0f,0xa2
-	movzbl	%cl,%esi
-	incl	%esi
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	btl	$28,%edx
-	jnc	L002generic
-	shrl	$16,%ebx
-	andl	$255,%ebx
-	cmpl	%esi,%ebx
-	ja	L002generic
-	andl	$4026531839,%edx
-	jmp	L002generic
-L001intel:
-	cmpl	$7,%edi
-	jb	L003cacheinfo
-	movl	20(%esp),%esi
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	movl	%ebx,8(%esi)
-L003cacheinfo:
-	cmpl	$4,%edi
-	movl	$-1,%edi
-	jb	L004nocacheinfo
-	movl	$4,%eax
-	movl	$0,%ecx
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	shrl	$14,%edi
-	andl	$4095,%edi
-L004nocacheinfo:
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	andl	$3220176895,%edx
-	cmpl	$0,%ebp
-	jne	L005notintel
-	orl	$1073741824,%edx
-L005notintel:
-	btl	$28,%edx
-	jnc	L002generic
-	andl	$4026531839,%edx
-	cmpl	$0,%edi
-	je	L002generic
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	L002generic
-	andl	$4026531839,%edx
-L002generic:
-	andl	$2048,%ebp
-	andl	$4294965247,%ecx
-	movl	%edx,%esi
-	orl	%ecx,%ebp
-	btl	$27,%ecx
-	jnc	L006clear_avx
-	xorl	%ecx,%ecx
-.byte	15,1,208
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	L007done
-	cmpl	$2,%eax
-	je	L006clear_avx
-L008clear_xmm:
-	andl	$4261412861,%ebp
-	andl	$4278190079,%esi
-L006clear_avx:
-	andl	$4026525695,%ebp
-	movl	20(%esp),%edi
-	andl	$4294967263,8(%edi)
-L007done:
-	movl	%esi,%eax
-	movl	%ebp,%edx
-L000nocpuid:
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.globl	_OPENSSL_rdtsc
-.private_extern	_OPENSSL_rdtsc
-.align	4
-_OPENSSL_rdtsc:
-L_OPENSSL_rdtsc_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	L009PIC_me_up
-L009PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L009PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	L010notsc
-	.byte	0x0f,0x31
-L010notsc:
-	ret
-.globl	_OPENSSL_instrument_halt
-.private_extern	_OPENSSL_instrument_halt
-.align	4
-_OPENSSL_instrument_halt:
-L_OPENSSL_instrument_halt_begin:
-	call	L011PIC_me_up
-L011PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L011PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	L012nohalt
-.long	2421723150
-	andl	$3,%eax
-	jnz	L012nohalt
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	L012nohalt
-	.byte	0x0f,0x31
-	pushl	%edx
-	pushl	%eax
-	hlt
-	.byte	0x0f,0x31
-	subl	(%esp),%eax
-	sbbl	4(%esp),%edx
-	addl	$8,%esp
-	ret
-L012nohalt:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.globl	_OPENSSL_far_spin
-.private_extern	_OPENSSL_far_spin
-.align	4
-_OPENSSL_far_spin:
-L_OPENSSL_far_spin_begin:
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	L013nospin
-	movl	4(%esp),%eax
-	movl	8(%esp),%ecx
-.long	2430111262
-	xorl	%eax,%eax
-	movl	(%ecx),%edx
-	jmp	L014spin
-.align	4,0x90
-L014spin:
-	incl	%eax
-	cmpl	(%ecx),%edx
-	je	L014spin
-.long	529567888
-	ret
-L013nospin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.globl	_OPENSSL_wipe_cpu
-.private_extern	_OPENSSL_wipe_cpu
-.align	4
-_OPENSSL_wipe_cpu:
-L_OPENSSL_wipe_cpu_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	L015PIC_me_up
-L015PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L015PIC_me_up(%ecx),%ecx
-	movl	(%ecx),%ecx
-	btl	$1,(%ecx)
-	jnc	L016no_x87
-	andl	$83886080,%ecx
-	cmpl	$83886080,%ecx
-	jne	L017no_sse2
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-L017no_sse2:
-.long	4007259865,4007259865,4007259865,4007259865,2430851995
-L016no_x87:
-	leal	4(%esp),%eax
-	ret
-.globl	_OPENSSL_atomic_add
-.private_extern	_OPENSSL_atomic_add
-.align	4
-_OPENSSL_atomic_add:
-L_OPENSSL_atomic_add_begin:
-	movl	4(%esp),%edx
-	movl	8(%esp),%ecx
-	pushl	%ebx
-	nop
-	movl	(%edx),%eax
-L018spin:
-	leal	(%eax,%ecx,1),%ebx
-	nop
-.long	447811568
-	jne	L018spin
-	movl	%ebx,%eax
-	popl	%ebx
-	ret
-.globl	_OPENSSL_indirect_call
-.private_extern	_OPENSSL_indirect_call
-.align	4
-_OPENSSL_indirect_call:
-L_OPENSSL_indirect_call_begin:
-	pushl	%ebp
-	movl	%esp,%ebp
-	subl	$28,%esp
-	movl	12(%ebp),%ecx
-	movl	%ecx,(%esp)
-	movl	16(%ebp),%edx
-	movl	%edx,4(%esp)
-	movl	20(%ebp),%eax
-	movl	%eax,8(%esp)
-	movl	24(%ebp),%eax
-	movl	%eax,12(%esp)
-	movl	28(%ebp),%eax
-	movl	%eax,16(%esp)
-	movl	32(%ebp),%eax
-	movl	%eax,20(%esp)
-	movl	36(%ebp),%eax
-	movl	%eax,24(%esp)
-	call	*8(%ebp)
-	movl	%ebp,%esp
-	popl	%ebp
-	ret
-.globl	_OPENSSL_ia32_rdrand
-.private_extern	_OPENSSL_ia32_rdrand
-.align	4
-_OPENSSL_ia32_rdrand:
-L_OPENSSL_ia32_rdrand_begin:
-	movl	$8,%ecx
-L019loop:
-.byte	15,199,240
-	jc	L020break
-	loop	L019loop
-L020break:
-	cmpl	$0,%eax
-	cmovel	%ecx,%eax
-	ret
-.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_64/crypto/bn/modexp512-x86_64.S b/mac-x86_64/crypto/bn/modexp512-x86_64.S
deleted file mode 100644
index beb133e..0000000
--- a/mac-x86_64/crypto/bn/modexp512-x86_64.S
+++ /dev/null
@@ -1,1776 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-
-.p2align	4
-MULADD_128x512:
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,0(%rcx)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	8(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	movq	%r9,8(%rcx)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	.byte	0xf3,0xc3
-
-
-.p2align	4
-mont_reduce:
-	leaq	192(%rsp),%rdi
-	movq	32(%rsp),%rsi
-	addq	$576,%rsi
-	leaq	520(%rsp),%rcx
-
-	movq	96(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	movq	(%rcx),%r8
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,0(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	movq	8(%rcx),%r9
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	movq	16(%rcx),%r10
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	movq	24(%rcx),%r11
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	movq	32(%rcx),%r12
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	movq	40(%rcx),%r13
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	movq	48(%rcx),%r14
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	movq	56(%rcx),%r15
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	104(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	movq	%r9,8(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	movq	112(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%r10,16(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%r10
-	movq	120(%rcx),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,24(%rdi)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	xorq	%rax,%rax
-
-	addq	64(%rcx),%r8
-	adcq	72(%rcx),%r9
-	adcq	80(%rcx),%r10
-	adcq	88(%rcx),%r11
-	adcq	$0,%rax
-
-
-
-
-	movq	%r8,64(%rdi)
-	movq	%r9,72(%rdi)
-	movq	%r10,%rbp
-	movq	%r11,88(%rdi)
-
-	movq	%rax,384(%rsp)
-
-	movq	0(%rdi),%r8
-	movq	8(%rdi),%r9
-	movq	16(%rdi),%r10
-	movq	24(%rdi),%r11
-
-
-
-
-
-
-
-
-	addq	$80,%rdi
-
-	addq	$64,%rsi
-	leaq	296(%rsp),%rcx
-
-	call	MULADD_128x512
-
-	movq	384(%rsp),%rax
-
-
-	addq	-16(%rdi),%r8
-	adcq	-8(%rdi),%r9
-	movq	%r8,64(%rcx)
-	movq	%r9,72(%rcx)
-
-	adcq	%rax,%rax
-	movq	%rax,384(%rsp)
-
-	leaq	192(%rsp),%rdi
-	addq	$64,%rsi
-
-
-
-
-
-	movq	(%rsi),%r8
-	movq	8(%rsi),%rbx
-
-	movq	(%rcx),%rax
-	mulq	%r8
-	movq	%rax,%rbp
-	movq	%rdx,%r9
-
-	movq	8(%rcx),%rax
-	mulq	%r8
-	addq	%rax,%r9
-
-	movq	(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r9
-
-	movq	%r9,8(%rdi)
-
-
-	subq	$192,%rsi
-
-	movq	(%rcx),%r8
-	movq	8(%rcx),%r9
-
-	call	MULADD_128x512
-
-
-
-
-	movq	0(%rsi),%rax
-	movq	8(%rsi),%rbx
-	movq	16(%rsi),%rdi
-	movq	24(%rsi),%rdx
-
-
-	movq	384(%rsp),%rbp
-
-	addq	64(%rcx),%r8
-	adcq	72(%rcx),%r9
-
-
-	adcq	%rbp,%rbp
-
-
-
-	shlq	$3,%rbp
-	movq	32(%rsp),%rcx
-	addq	%rcx,%rbp
-
-
-	xorq	%rsi,%rsi
-
-	addq	0(%rbp),%r10
-	adcq	64(%rbp),%r11
-	adcq	128(%rbp),%r12
-	adcq	192(%rbp),%r13
-	adcq	256(%rbp),%r14
-	adcq	320(%rbp),%r15
-	adcq	384(%rbp),%r8
-	adcq	448(%rbp),%r9
-
-
-
-	sbbq	$0,%rsi
-
-
-	andq	%rsi,%rax
-	andq	%rsi,%rbx
-	andq	%rsi,%rdi
-	andq	%rsi,%rdx
-
-	movq	$1,%rbp
-	subq	%rax,%r10
-	sbbq	%rbx,%r11
-	sbbq	%rdi,%r12
-	sbbq	%rdx,%r13
-
-
-
-
-	sbbq	$0,%rbp
-
-
-
-	addq	$512,%rcx
-	movq	32(%rcx),%rax
-	movq	40(%rcx),%rbx
-	movq	48(%rcx),%rdi
-	movq	56(%rcx),%rdx
-
-
-
-	andq	%rsi,%rax
-	andq	%rsi,%rbx
-	andq	%rsi,%rdi
-	andq	%rsi,%rdx
-
-
-
-	subq	$1,%rbp
-
-	sbbq	%rax,%r14
-	sbbq	%rbx,%r15
-	sbbq	%rdi,%r8
-	sbbq	%rdx,%r9
-
-
-
-	movq	144(%rsp),%rsi
-	movq	%r10,0(%rsi)
-	movq	%r11,8(%rsi)
-	movq	%r12,16(%rsi)
-	movq	%r13,24(%rsi)
-	movq	%r14,32(%rsi)
-	movq	%r15,40(%rsi)
-	movq	%r8,48(%rsi)
-	movq	%r9,56(%rsi)
-
-	.byte	0xf3,0xc3
-
-
-.p2align	4
-mont_mul_a3b:
-
-
-
-
-	movq	0(%rdi),%rbp
-
-	movq	%r10,%rax
-	mulq	%rbp
-	movq	%rax,520(%rsp)
-	movq	%rdx,%r10
-	movq	%r11,%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	%r12,%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	%r13,%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	%r14,%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	%r15,%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	%r8,%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	%r9,%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%r9
-	movq	8(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%r10,528(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%r10
-	movq	16(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,536(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	24(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%r12,544(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	32(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%r13,552(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	40(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%r14,560(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	48(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,568(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	addq	%rbx,%r8
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	56(%rdi),%rbp
-	movq	0(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r8
-	adcq	$0,%rdx
-	movq	%r8,576(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r9
-	adcq	$0,%rdx
-	addq	%rbx,%r9
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	16(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	addq	%rbx,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	24(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%rbx,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	32(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%rbx,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	40(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%rbx,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	48(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%rbx,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%rbx
-
-	movq	56(%rsi),%rax
-	mulq	%rbp
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%rbx,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%r8
-	movq	%r9,584(%rsp)
-	movq	%r10,592(%rsp)
-	movq	%r11,600(%rsp)
-	movq	%r12,608(%rsp)
-	movq	%r13,616(%rsp)
-	movq	%r14,624(%rsp)
-	movq	%r15,632(%rsp)
-	movq	%r8,640(%rsp)
-
-
-
-
-
-	jmp	mont_reduce
-
-
-
-
-.p2align	4
-sqr_reduce:
-	movq	16(%rsp),%rcx
-
-
-
-	movq	%r10,%rbx
-
-	movq	%r11,%rax
-	mulq	%rbx
-	movq	%rax,528(%rsp)
-	movq	%rdx,%r10
-	movq	%r12,%rax
-	mulq	%rbx
-	addq	%rax,%r10
-	adcq	$0,%rdx
-	movq	%rdx,%r11
-	movq	%r13,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%rdx,%r12
-	movq	%r14,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%rdx,%r13
-	movq	%r15,%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%rdx,%r14
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	movq	%rdx,%r15
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%rdx,%rsi
-
-	movq	%r10,536(%rsp)
-
-
-
-
-
-	movq	8(%rcx),%rbx
-
-	movq	16(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,544(%rsp)
-
-	movq	%rdx,%r10
-	movq	24(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-	movq	%r12,552(%rsp)
-
-	movq	%rdx,%r10
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	addq	%r10,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%r10,%r14
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-
-	movq	%rdx,%r11
-
-
-
-
-	movq	16(%rcx),%rbx
-
-	movq	24(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r13
-	adcq	$0,%rdx
-	movq	%r13,560(%rsp)
-
-	movq	%rdx,%r10
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r14
-	adcq	$0,%rdx
-	addq	%r10,%r14
-	adcq	$0,%rdx
-	movq	%r14,568(%rsp)
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%r12
-
-
-
-
-
-	movq	24(%rcx),%rbx
-
-	movq	32(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,576(%rsp)
-
-	movq	%rdx,%r10
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%rsi
-	adcq	$0,%rdx
-	addq	%r10,%rsi
-	adcq	$0,%rdx
-	movq	%rsi,584(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-
-	movq	%rdx,%r15
-
-
-
-
-	movq	32(%rcx),%rbx
-
-	movq	40(%rcx),%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	movq	%r11,592(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	addq	%r10,%r12
-	adcq	$0,%rdx
-	movq	%r12,600(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	addq	%r10,%r15
-	adcq	$0,%rdx
-
-	movq	%rdx,%r11
-
-
-
-
-	movq	40(%rcx),%rbx
-
-	movq	%r8,%rax
-	mulq	%rbx
-	addq	%rax,%r15
-	adcq	$0,%rdx
-	movq	%r15,608(%rsp)
-
-	movq	%rdx,%r10
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r11
-	adcq	$0,%rdx
-	addq	%r10,%r11
-	adcq	$0,%rdx
-	movq	%r11,616(%rsp)
-
-	movq	%rdx,%r12
-
-
-
-
-	movq	%r8,%rbx
-
-	movq	%r9,%rax
-	mulq	%rbx
-	addq	%rax,%r12
-	adcq	$0,%rdx
-	movq	%r12,624(%rsp)
-
-	movq	%rdx,632(%rsp)
-
-
-	movq	528(%rsp),%r10
-	movq	536(%rsp),%r11
-	movq	544(%rsp),%r12
-	movq	552(%rsp),%r13
-	movq	560(%rsp),%r14
-	movq	568(%rsp),%r15
-
-	movq	24(%rcx),%rax
-	mulq	%rax
-	movq	%rax,%rdi
-	movq	%rdx,%r8
-
-	addq	%r10,%r10
-	adcq	%r11,%r11
-	adcq	%r12,%r12
-	adcq	%r13,%r13
-	adcq	%r14,%r14
-	adcq	%r15,%r15
-	adcq	$0,%r8
-
-	movq	0(%rcx),%rax
-	mulq	%rax
-	movq	%rax,520(%rsp)
-	movq	%rdx,%rbx
-
-	movq	8(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbx,%r10
-	adcq	%rax,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbx
-	movq	%r10,528(%rsp)
-	movq	%r11,536(%rsp)
-
-	movq	16(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbx,%r12
-	adcq	%rax,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbx
-
-	movq	%r12,544(%rsp)
-	movq	%r13,552(%rsp)
-
-	xorq	%rbp,%rbp
-	addq	%rbx,%r14
-	adcq	%rdi,%r15
-	adcq	$0,%rbp
-
-	movq	%r14,560(%rsp)
-	movq	%r15,568(%rsp)
-
-
-
-
-	movq	576(%rsp),%r10
-	movq	584(%rsp),%r11
-	movq	592(%rsp),%r12
-	movq	600(%rsp),%r13
-	movq	608(%rsp),%r14
-	movq	616(%rsp),%r15
-	movq	624(%rsp),%rdi
-	movq	632(%rsp),%rsi
-
-	movq	%r9,%rax
-	mulq	%rax
-	movq	%rax,%r9
-	movq	%rdx,%rbx
-
-	addq	%r10,%r10
-	adcq	%r11,%r11
-	adcq	%r12,%r12
-	adcq	%r13,%r13
-	adcq	%r14,%r14
-	adcq	%r15,%r15
-	adcq	%rdi,%rdi
-	adcq	%rsi,%rsi
-	adcq	$0,%rbx
-
-	addq	%rbp,%r10
-
-	movq	32(%rcx),%rax
-	mulq	%rax
-
-	addq	%r8,%r10
-	adcq	%rax,%r11
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbp
-
-	movq	%r10,576(%rsp)
-	movq	%r11,584(%rsp)
-
-	movq	40(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbp,%r12
-	adcq	%rax,%r13
-	adcq	$0,%rdx
-
-	movq	%rdx,%rbp
-
-	movq	%r12,592(%rsp)
-	movq	%r13,600(%rsp)
-
-	movq	48(%rcx),%rax
-	mulq	%rax
-
-	addq	%rbp,%r14
-	adcq	%rax,%r15
-	adcq	$0,%rdx
-
-	movq	%r14,608(%rsp)
-	movq	%r15,616(%rsp)
-
-	addq	%rdx,%rdi
-	adcq	%r9,%rsi
-	adcq	$0,%rbx
-
-	movq	%rdi,624(%rsp)
-	movq	%rsi,632(%rsp)
-	movq	%rbx,640(%rsp)
-
-	jmp	mont_reduce
-
-
-
-.globl	_mod_exp_512
-.private_extern _mod_exp_512
-
-_mod_exp_512:
-	pushq	%rbp
-	pushq	%rbx
-	pushq	%r12
-	pushq	%r13
-	pushq	%r14
-	pushq	%r15
-
-
-	movq	%rsp,%r8
-	subq	$2688,%rsp
-	andq	$-64,%rsp
-
-
-	movq	%r8,0(%rsp)
-	movq	%rdi,8(%rsp)
-	movq	%rsi,16(%rsp)
-	movq	%rcx,24(%rsp)
-L$body:
-
-
-
-	pxor	%xmm4,%xmm4
-	movdqu	0(%rsi),%xmm0
-	movdqu	16(%rsi),%xmm1
-	movdqu	32(%rsi),%xmm2
-	movdqu	48(%rsi),%xmm3
-	movdqa	%xmm4,512(%rsp)
-	movdqa	%xmm4,528(%rsp)
-	movdqa	%xmm4,608(%rsp)
-	movdqa	%xmm4,624(%rsp)
-	movdqa	%xmm0,544(%rsp)
-	movdqa	%xmm1,560(%rsp)
-	movdqa	%xmm2,576(%rsp)
-	movdqa	%xmm3,592(%rsp)
-
-
-	movdqu	0(%rdx),%xmm0
-	movdqu	16(%rdx),%xmm1
-	movdqu	32(%rdx),%xmm2
-	movdqu	48(%rdx),%xmm3
-
-	leaq	384(%rsp),%rbx
-	movq	%rbx,136(%rsp)
-	call	mont_reduce
-
-
-	leaq	448(%rsp),%rcx
-	xorq	%rax,%rax
-	movq	%rax,0(%rcx)
-	movq	%rax,8(%rcx)
-	movq	%rax,24(%rcx)
-	movq	%rax,32(%rcx)
-	movq	%rax,40(%rcx)
-	movq	%rax,48(%rcx)
-	movq	%rax,56(%rcx)
-	movq	%rax,128(%rsp)
-	movq	$1,16(%rcx)
-
-	leaq	640(%rsp),%rbp
-	movq	%rcx,%rsi
-	movq	%rbp,%rdi
-	movq	$8,%rax
-loop_0:
-	movq	(%rcx),%rbx
-	movw	%bx,(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,64(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,128(%rdi)
-	shrq	$16,%rbx
-	movw	%bx,192(%rdi)
-	leaq	8(%rcx),%rcx
-	leaq	256(%rdi),%rdi
-	decq	%rax
-	jnz	loop_0
-	movq	$31,%rax
-	movq	%rax,32(%rsp)
-	movq	%rbp,40(%rsp)
-
-	movq	%rsi,136(%rsp)
-	movq	0(%rsi),%r10
-	movq	8(%rsi),%r11
-	movq	16(%rsi),%r12
-	movq	24(%rsi),%r13
-	movq	32(%rsi),%r14
-	movq	40(%rsi),%r15
-	movq	48(%rsi),%r8
-	movq	56(%rsi),%r9
-init_loop:
-	leaq	384(%rsp),%rdi
-	call	mont_mul_a3b
-	leaq	448(%rsp),%rsi
-	movq	40(%rsp),%rbp
-	addq	$2,%rbp
-	movq	%rbp,40(%rsp)
-	movq	%rsi,%rcx
-	movq	$8,%rax
-loop_1:
-	movq	(%rcx),%rbx
-	movw	%bx,(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,64(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,128(%rbp)
-	shrq	$16,%rbx
-	movw	%bx,192(%rbp)
-	leaq	8(%rcx),%rcx
-	leaq	256(%rbp),%rbp
-	decq	%rax
-	jnz	loop_1
-	movq	32(%rsp),%rax
-	subq	$1,%rax
-	movq	%rax,32(%rsp)
-	jne	init_loop
-
-
-
-	movdqa	%xmm0,64(%rsp)
-	movdqa	%xmm1,80(%rsp)
-	movdqa	%xmm2,96(%rsp)
-	movdqa	%xmm3,112(%rsp)
-
-
-
-
-
-	movl	126(%rsp),%eax
-	movq	%rax,%rdx
-	shrq	$11,%rax
-	andl	$2047,%edx
-	movl	%edx,126(%rsp)
-	leaq	640(%rsp,%rax,2),%rsi
-	movq	8(%rsp),%rdx
-	movq	$4,%rbp
-loop_2:
-	movzwq	192(%rsi),%rbx
-	movzwq	448(%rsi),%rax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	128(%rsi),%bx
-	movw	384(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	64(%rsi),%bx
-	movw	320(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	0(%rsi),%bx
-	movw	256(%rsi),%ax
-	movq	%rbx,0(%rdx)
-	movq	%rax,8(%rdx)
-	leaq	512(%rsi),%rsi
-	leaq	16(%rdx),%rdx
-	subq	$1,%rbp
-	jnz	loop_2
-	movq	$505,48(%rsp)
-
-	movq	8(%rsp),%rcx
-	movq	%rcx,136(%rsp)
-	movq	0(%rcx),%r10
-	movq	8(%rcx),%r11
-	movq	16(%rcx),%r12
-	movq	24(%rcx),%r13
-	movq	32(%rcx),%r14
-	movq	40(%rcx),%r15
-	movq	48(%rcx),%r8
-	movq	56(%rcx),%r9
-	jmp	sqr_2
-
-main_loop_a3b:
-	call	sqr_reduce
-	call	sqr_reduce
-	call	sqr_reduce
-sqr_2:
-	call	sqr_reduce
-	call	sqr_reduce
-
-
-
-	movq	48(%rsp),%rcx
-	movq	%rcx,%rax
-	shrq	$4,%rax
-	movl	64(%rsp,%rax,2),%edx
-	andq	$15,%rcx
-	shrq	%cl,%rdx
-	andq	$31,%rdx
-
-	leaq	640(%rsp,%rdx,2),%rsi
-	leaq	448(%rsp),%rdx
-	movq	%rdx,%rdi
-	movq	$4,%rbp
-loop_3:
-	movzwq	192(%rsi),%rbx
-	movzwq	448(%rsi),%rax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	128(%rsi),%bx
-	movw	384(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	64(%rsi),%bx
-	movw	320(%rsi),%ax
-	shlq	$16,%rbx
-	shlq	$16,%rax
-	movw	0(%rsi),%bx
-	movw	256(%rsi),%ax
-	movq	%rbx,0(%rdx)
-	movq	%rax,8(%rdx)
-	leaq	512(%rsi),%rsi
-	leaq	16(%rdx),%rdx
-	subq	$1,%rbp
-	jnz	loop_3
-	movq	8(%rsp),%rsi
-	call	mont_mul_a3b
-
-
-
-	movq	48(%rsp),%rcx
-	subq	$5,%rcx
-	movq	%rcx,48(%rsp)
-	jge	main_loop_a3b
-
-
-
-end_main_loop_a3b:
-
-
-	movq	8(%rsp),%rdx
-	pxor	%xmm4,%xmm4
-	movdqu	0(%rdx),%xmm0
-	movdqu	16(%rdx),%xmm1
-	movdqu	32(%rdx),%xmm2
-	movdqu	48(%rdx),%xmm3
-	movdqa	%xmm4,576(%rsp)
-	movdqa	%xmm4,592(%rsp)
-	movdqa	%xmm4,608(%rsp)
-	movdqa	%xmm4,624(%rsp)
-	movdqa	%xmm0,512(%rsp)
-	movdqa	%xmm1,528(%rsp)
-	movdqa	%xmm2,544(%rsp)
-	movdqa	%xmm3,560(%rsp)
-	call	mont_reduce
-
-
-
-	movq	8(%rsp),%rax
-	movq	0(%rax),%r8
-	movq	8(%rax),%r9
-	movq	16(%rax),%r10
-	movq	24(%rax),%r11
-	movq	32(%rax),%r12
-	movq	40(%rax),%r13
-	movq	48(%rax),%r14
-	movq	56(%rax),%r15
-
-
-	movq	24(%rsp),%rbx
-	addq	$512,%rbx
-
-	subq	0(%rbx),%r8
-	sbbq	8(%rbx),%r9
-	sbbq	16(%rbx),%r10
-	sbbq	24(%rbx),%r11
-	sbbq	32(%rbx),%r12
-	sbbq	40(%rbx),%r13
-	sbbq	48(%rbx),%r14
-	sbbq	56(%rbx),%r15
-
-
-	movq	0(%rax),%rsi
-	movq	8(%rax),%rdi
-	movq	16(%rax),%rcx
-	movq	24(%rax),%rdx
-	cmovncq	%r8,%rsi
-	cmovncq	%r9,%rdi
-	cmovncq	%r10,%rcx
-	cmovncq	%r11,%rdx
-	movq	%rsi,0(%rax)
-	movq	%rdi,8(%rax)
-	movq	%rcx,16(%rax)
-	movq	%rdx,24(%rax)
-
-	movq	32(%rax),%rsi
-	movq	40(%rax),%rdi
-	movq	48(%rax),%rcx
-	movq	56(%rax),%rdx
-	cmovncq	%r12,%rsi
-	cmovncq	%r13,%rdi
-	cmovncq	%r14,%rcx
-	cmovncq	%r15,%rdx
-	movq	%rsi,32(%rax)
-	movq	%rdi,40(%rax)
-	movq	%rcx,48(%rax)
-	movq	%rdx,56(%rax)
-
-	movq	0(%rsp),%rsi
-	movq	0(%rsi),%r15
-	movq	8(%rsi),%r14
-	movq	16(%rsi),%r13
-	movq	24(%rsi),%r12
-	movq	32(%rsi),%rbx
-	movq	40(%rsi),%rbp
-	leaq	48(%rsi),%rsp
-L$epilogue:
-	.byte	0xf3,0xc3
-
-#endif
diff --git a/mac-x86_64/crypto/cpu-x86_64-asm.S b/mac-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 0dde04d..0000000
--- a/mac-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-.globl	_OPENSSL_ia32_cpuid
-.private_extern _OPENSSL_ia32_cpuid
-
-.p2align	4
-_OPENSSL_ia32_cpuid:
-
-
-	movq	%rdi,%rdi
-	movq	%rbx,%r8
-
-	xorl	%eax,%eax
-	movl	%eax,8(%rdi)
-	cpuid
-	movl	%eax,%r11d
-
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%r9d
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%r9d
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%r9d
-	jz	L$intel
-
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%r10d
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%r10d
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%r10d
-	jnz	L$intel
-
-
-
-
-	movl	$2147483648,%eax
-	cpuid
-
-
-	cmpl	$2147483649,%eax
-	jb	L$intel
-	movl	%eax,%r10d
-	movl	$2147483649,%eax
-	cpuid
-
-
-	orl	%ecx,%r9d
-	andl	$2049,%r9d
-
-	cmpl	$2147483656,%r10d
-	jb	L$intel
-
-	movl	$2147483656,%eax
-	cpuid
-
-	movzbq	%cl,%r10
-	incq	%r10
-
-	movl	$1,%eax
-	cpuid
-
-	btl	$28,%edx
-	jnc	L$generic
-	shrl	$16,%ebx
-	cmpb	%r10b,%bl
-	ja	L$generic
-	andl	$4026531839,%edx
-	jmp	L$generic
-
-L$intel:
-	cmpl	$4,%r11d
-	movl	$-1,%r10d
-	jb	L$nocacheinfo
-
-	movl	$4,%eax
-	movl	$0,%ecx
-	cpuid
-	movl	%eax,%r10d
-	shrl	$14,%r10d
-	andl	$4095,%r10d
-
-	cmpl	$7,%r11d
-	jb	L$nocacheinfo
-
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	cpuid
-	movl	%ebx,8(%rdi)
-
-L$nocacheinfo:
-	movl	$1,%eax
-	cpuid
-
-	andl	$3220176895,%edx
-	cmpl	$0,%r9d
-	jne	L$notintel
-	orl	$1073741824,%edx
-L$notintel:
-	btl	$28,%edx
-	jnc	L$generic
-	andl	$4026531839,%edx
-	cmpl	$0,%r10d
-	je	L$generic
-
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	L$generic
-	andl	$4026531839,%edx
-L$generic:
-	andl	$2048,%r9d
-	andl	$4294965247,%ecx
-	orl	%ecx,%r9d
-
-	movl	%edx,%r10d
-	btl	$27,%r9d
-	jnc	L$clear_avx
-	xorl	%ecx,%ecx
-.byte	0x0f,0x01,0xd0
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	L$done
-L$clear_avx:
-	movl	$4026525695,%eax
-	andl	%eax,%r9d
-	andl	$4294967263,8(%rdi)
-L$done:
-	movl	%r9d,4(%rdi)
-	movl	%r10d,0(%rdi)
-	movq	%r8,%rbx
-	.byte	0xf3,0xc3
-
-
-#endif
diff --git a/sources.mk b/sources.mk
index cdb7abc..42d9fa6 100644
--- a/sources.mk
+++ b/sources.mk
@@ -70,6 +70,7 @@
   src/crypto/bn/add.c\
   src/crypto/bn/asm/x86_64-gcc.c\
   src/crypto/bn/bn.c\
+  src/crypto/bn/bn_asn1.c\
   src/crypto/bn/cmp.c\
   src/crypto/bn/convert.c\
   src/crypto/bn/ctx.c\
@@ -136,15 +137,13 @@
   src/crypto/engine/engine.c\
   src/crypto/err/err.c\
   src/crypto/evp/algorithm.c\
-  src/crypto/evp/asn1.c\
   src/crypto/evp/digestsign.c\
   src/crypto/evp/evp.c\
+  src/crypto/evp/evp_asn1.c\
   src/crypto/evp/evp_ctx.c\
   src/crypto/evp/p_dsa_asn1.c\
   src/crypto/evp/p_ec.c\
   src/crypto/evp/p_ec_asn1.c\
-  src/crypto/evp/p_hmac.c\
-  src/crypto/evp/p_hmac_asn1.c\
   src/crypto/evp/p_rsa.c\
   src/crypto/evp/p_rsa_asn1.c\
   src/crypto/evp/pbkdf.c\
@@ -209,6 +208,7 @@
   src/crypto/x509/i2d_pr.c\
   src/crypto/x509/pkcs7.c\
   src/crypto/x509/t_crl.c\
+  src/crypto/x509/t_req.c\
   src/crypto/x509/t_x509.c\
   src/crypto/x509/t_x509a.c\
   src/crypto/x509/x509.c\
@@ -281,6 +281,7 @@
   src/crypto/x509v3/v3_utl.c\
 
 ssl_sources := \
+  src/ssl/custom_extensions.c\
   src/ssl/d1_both.c\
   src/ssl/d1_clnt.c\
   src/ssl/d1_lib.c\
@@ -288,6 +289,7 @@
   src/ssl/d1_pkt.c\
   src/ssl/d1_srtp.c\
   src/ssl/d1_srvr.c\
+  src/ssl/dtls_record.c\
   src/ssl/pqueue/pqueue.c\
   src/ssl/s3_both.c\
   src/ssl/s3_clnt.c\
@@ -297,24 +299,26 @@
   src/ssl/s3_pkt.c\
   src/ssl/s3_srvr.c\
   src/ssl/ssl_aead_ctx.c\
-  src/ssl/ssl_algs.c\
   src/ssl/ssl_asn1.c\
+  src/ssl/ssl_buffer.c\
   src/ssl/ssl_cert.c\
   src/ssl/ssl_cipher.c\
+  src/ssl/ssl_file.c\
   src/ssl/ssl_lib.c\
   src/ssl/ssl_rsa.c\
-  src/ssl/ssl_sess.c\
+  src/ssl/ssl_session.c\
   src/ssl/ssl_stat.c\
   src/ssl/ssl_txt.c\
   src/ssl/t1_enc.c\
   src/ssl/t1_lib.c\
-  src/ssl/t1_reneg.c\
+  src/ssl/tls_record.c\
 
 tool_sources := \
   src/tool/args.cc\
   src/tool/client.cc\
   src/tool/const.cc\
   src/tool/digest.cc\
+  src/tool/genrsa.cc\
   src/tool/pkcs12.cc\
   src/tool/rand.cc\
   src/tool/server.cc\
@@ -323,19 +327,19 @@
   src/tool/transport_common.cc\
 
 linux_aarch64_sources := \
-  linux-aarch64/crypto/aes/aesv8-armx.S\
-  linux-aarch64/crypto/modes/ghashv8-armx.S\
+  linux-aarch64/crypto/aes/aesv8-armx64.S\
+  linux-aarch64/crypto/modes/ghashv8-armx64.S\
   linux-aarch64/crypto/sha/sha1-armv8.S\
   linux-aarch64/crypto/sha/sha256-armv8.S\
   linux-aarch64/crypto/sha/sha512-armv8.S\
 
 linux_arm_sources := \
   linux-arm/crypto/aes/aes-armv4.S\
-  linux-arm/crypto/aes/aesv8-armx.S\
+  linux-arm/crypto/aes/aesv8-armx32.S\
   linux-arm/crypto/aes/bsaes-armv7.S\
   linux-arm/crypto/bn/armv4-mont.S\
   linux-arm/crypto/modes/ghash-armv4.S\
-  linux-arm/crypto/modes/ghashv8-armx.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\
@@ -350,7 +354,6 @@
   linux-x86/crypto/bn/bn-586.S\
   linux-x86/crypto/bn/co-586.S\
   linux-x86/crypto/bn/x86-mont.S\
-  linux-x86/crypto/cpu-x86-asm.S\
   linux-x86/crypto/md5/md5-586.S\
   linux-x86/crypto/modes/ghash-x86.S\
   linux-x86/crypto/rc4/rc4-586.S\
@@ -367,7 +370,6 @@
   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/cpu-x86_64-asm.S\
   linux-x86_64/crypto/md5/md5-x86_64.S\
   linux-x86_64/crypto/modes/aesni-gcm-x86_64.S\
   linux-x86_64/crypto/modes/ghash-x86_64.S\
@@ -385,7 +387,6 @@
   mac-x86/crypto/bn/bn-586.S\
   mac-x86/crypto/bn/co-586.S\
   mac-x86/crypto/bn/x86-mont.S\
-  mac-x86/crypto/cpu-x86-asm.S\
   mac-x86/crypto/md5/md5-586.S\
   mac-x86/crypto/modes/ghash-x86.S\
   mac-x86/crypto/rc4/rc4-586.S\
@@ -402,7 +403,6 @@
   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/cpu-x86_64-asm.S\
   mac-x86_64/crypto/md5/md5-x86_64.S\
   mac-x86_64/crypto/modes/aesni-gcm-x86_64.S\
   mac-x86_64/crypto/modes/ghash-x86_64.S\
@@ -420,7 +420,6 @@
   win-x86/crypto/bn/bn-586.asm\
   win-x86/crypto/bn/co-586.asm\
   win-x86/crypto/bn/x86-mont.asm\
-  win-x86/crypto/cpu-x86-asm.asm\
   win-x86/crypto/md5/md5-586.asm\
   win-x86/crypto/modes/ghash-x86.asm\
   win-x86/crypto/rc4/rc4-586.asm\
@@ -437,7 +436,6 @@
   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/cpu-x86_64-asm.asm\
   win-x86_64/crypto/md5/md5-x86_64.asm\
   win-x86_64/crypto/modes/aesni-gcm-x86_64.asm\
   win-x86_64/crypto/modes/ghash-x86_64.asm\
diff --git a/src/.gitignore b/src/.gitignore
index b54125f..a2e3ed2 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -3,3 +3,4 @@
 *.swp
 *.swo
 doc/*.html
+doc/doc.css
diff --git a/src/BUILDING b/src/BUILDING
deleted file mode 100644
index d818f95..0000000
--- a/src/BUILDING
+++ /dev/null
@@ -1,96 +0,0 @@
-Build Prerequisites:
-
-  * CMake[1] 2.8.8 or later is required.
-
-  * Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
-    have both been reported to work. If not found by CMake, it may be configured
-    explicitly by setting PERL_EXECUTABLE.
-
-  * On Windows you currently must use Ninja[2] to build; on other platforms,
-    it is not required, but recommended, because it makes builds faster.
-
-  * If you need to build Ninja from source, then a recent version of
-    Python[3] is required (Python 2.7.5 works).
-
-  * On Windows only, Yasm[4] is required. If not found by CMake, it may be
-    configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
-
-  * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
-    with Platform SDK 8.1 or later are supported. Recent versions of GCC and
-    Clang should work on non-Windows platforms, and maybe on Windows too.
-
-  * Go[5] is required. If not found by CMake, the go executable may be
-    configured explicitly by setting GO_EXECUTABLE.
-
-Using Ninja (note the 'N' is capitalized in the cmake invocation):
-
-  mkdir build
-  cd build
-  cmake -GNinja ..
-  ninja
-
-Using makefiles (does not work on Windows):
-
-  mkdir build
-  cd build
-  cmake ..
-  make
-
-You usually don't need to run cmake again after changing CMakeLists.txt files
-because the build scripts will detect changes to them and rebuild themselves
-automatically.
-
-Note that the default build flags in the top-level CMakeLists.txt are for
-debugging - optimisation isn't enabled.
-
-If you want to cross-compile then there is an example toolchain file for
-32-bit Intel in util/. Wipe out the build directory, recreate it and run cmake
-like this:
-
-  cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
-
-If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On
-Windows, where functions need to be tagged with "dllimport" when coming from a
-shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the
-BoringSSL headers.
-
-
-Building for Android:
-
-It's possible to build BoringSSL with the Android NDK using CMake. This has
-been tested with version 10d of the NDK.
-
-Unpack the Android NDK somewhere and export ANDROID_NDK to point to the
-directory. Clone https://github.com/taka-no-me/android-cmake into util/.
-Then make a build directory as above and run CMake *twice* like this:
-
-  cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
-        -DANDROID_ABI=armeabi-v7a \
-        -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
-        -GNinja ..
-
-Once you've run that twice, ninja should produce Android-compatible binaries.
-You can replace "armeabi-v7a" in the above with "arm64-v8a" to build aarch64
-binaries.
-
-
-Known Limitations on Windows:
-
-  * Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes
-    yasm to output warnings "yasm: warning: can open only one input file, only
-    the last file will be processed". These warnings can be safely ignored.
-    The cmake bug is http://www.cmake.org/Bug/view.php?id=15253.
-
-  * cmake can generate Visual Studio projects, but the generated project files
-    don't have steps for assembling the assembly language source files, so they
-    currently cannot be used to build BoringSSL.
-
-[1] http://www.cmake.org/download/
-
-[2] https://martine.github.io/ninja/
-
-[3] https://www.python.org/downloads/
-
-[4] http://yasm.tortall.net/
-
-[5] https://golang.org/dl/
diff --git a/src/BUILDING.md b/src/BUILDING.md
new file mode 100644
index 0000000..c75851f
--- /dev/null
+++ b/src/BUILDING.md
@@ -0,0 +1,100 @@
+# Building BoringSSL
+
+## Build Prerequisites
+
+  * [CMake] [1] 2.8.8 or later is required.
+
+  * Perl 5.6.1 or later is required. On Windows, [Strawberry Perl] [2] and MSYS
+    Perl have both been reported to work. If not found by CMake, it may be
+    configured explicitly by setting `PERL_EXECUTABLE`.
+
+  * On Windows you currently must use [Ninja] [3] to build; on other platforms,
+    it is not required, but recommended, because it makes builds faster.
+
+  * If you need to build Ninja from source, then a recent version of
+    [Python] [4] is required (Python 2.7.5 works).
+
+  * On Windows only, [Yasm] [5] is required. If not found by CMake, it may be
+    configured explicitly by setting `CMAKE_ASM_NASM_COMPILER`.
+
+  * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
+    with Platform SDK 8.1 or later are supported. Recent versions of GCC and
+    Clang should work on non-Windows platforms, and maybe on Windows too.
+
+  * [Go] [6] is required. If not found by CMake, the go executable may be
+    configured explicitly by setting `GO_EXECUTABLE`.
+
+## Building
+
+Using Ninja (note the 'N' is capitalized in the cmake invocation):
+
+    mkdir build
+    cd build
+    cmake -GNinja ..
+    ninja
+
+Using Make (does not work on Windows):
+
+    mkdir build
+    cd build
+    cmake ..
+    make
+
+You usually don't need to run `cmake` again after changing `CMakeLists.txt`
+files because the build scripts will detect changes to them and rebuild
+themselves automatically.
+
+Note that the default build flags in the top-level `CMakeLists.txt` are for
+debugging—optimisation isn't enabled.
+
+If you want to cross-compile then there is an example toolchain file for 32-bit
+Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
+this:
+
+    cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
+
+If you want to build as a shared library, pass `-DBUILD_SHARED_LIBS=1`. On
+Windows, where functions need to be tagged with `dllimport` when coming from a
+shared library, define `BORINGSSL_SHARED_LIBRARY` in any code which `#include`s
+the BoringSSL headers.
+
+### Building for Android
+
+It's possible to build BoringSSL with the Android NDK using CMake. This has
+been tested with version 10d of the NDK.
+
+Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
+directory. Clone https://github.com/taka-no-me/android-cmake into `util/`.  Then
+make a build directory as above and run CMake *twice* like this:
+
+    cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
+          -DANDROID_ABI=armeabi-v7a \
+          -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
+          -DANDROID_NATIVE_API_LEVEL=16 \
+          -GNinja ..
+
+Once you've run that twice, Ninja should produce Android-compatible binaries.
+You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
+binaries.
+
+## Known Limitations on Windows
+
+  * Versions of CMake since 3.0.2 have a bug in its Ninja generator that causes
+    yasm to output warnings
+
+        yasm: warning: can open only one input file, only the last file will be processed
+
+    These warnings can be safely ignored. The cmake bug is
+    http://www.cmake.org/Bug/view.php?id=15253.
+
+  * CMake can generate Visual Studio projects, but the generated project files
+    don't have steps for assembling the assembly language source files, so they
+    currently cannot be used to build BoringSSL.
+
+
+ [1]: http://www.cmake.org/download/
+ [2]: http://strawberryperl.com/
+ [3]: https://martine.github.io/ninja/
+ [4]: https://www.python.org/downloads/
+ [5]: http://yasm.tortall.net/
+ [6]: https://golang.org/dl/
diff --git a/src/LICENSE b/src/LICENSE
index 8ae5e77..b242dcb 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -5,6 +5,9 @@
 Contributors to BoringSSL are required to follow the CLA rules for Chromium:
 https://cla.developers.google.com/clas
 
+Some files from Intel are under yet another license, which is also included
+underneath.
+
 The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
 OpenSSL License and the original SSLeay license apply to the toolkit. See below
 for the actual license texts. Actually both licenses are BSD-style Open Source
@@ -144,3 +147,39 @@
  * 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. */
+
+
+Some files from Intel carry the following license:
+
+# Copyright (c) 2012, Intel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# *  Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# *  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.
+#
+# *  Neither the name of the Intel Corporation nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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.
diff --git a/src/PORTING.md b/src/PORTING.md
new file mode 100644
index 0000000..70b67cc
--- /dev/null
+++ b/src/PORTING.md
@@ -0,0 +1,157 @@
+# Porting from OpenSSL to BoringSSL
+
+BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
+subset of OpenSSL retained. Libraries ideally need little to no changes for
+BoringSSL support, provided they do not use removed APIs. In general, see if the
+library compiles and, on failure, consult the documentation in the header files
+and see if problematic features can be removed.
+
+In some cases, BoringSSL-specific code may be necessary. In that case, the
+`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
+should also be used in lieu of the presence of any particular function to detect
+OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
+
+For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
+corresponding to removed features. These may also be used to disable code which
+uses a removed feature.
+
+Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
+consumers. It is not suitable for, say, a system library in a traditional Linux
+distribution. For instance, Chromium statically links the specific revision of
+BoringSSL it was built against. Likewise, Android's system-internal copy of
+BoringSSL is not exposed by the NDK and must not be used by third-party
+applications.
+
+
+## Major API changes
+
+### Integer types
+
+Some APIs have been converted to use `size_t` for consistency and to avoid
+integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
+`long`, and `unsigned`.)  For the most part, implicit casts mean that existing
+code continues to compile. In some cases, this may require BoringSSL-specific
+code, particularly to avoid compiler warnings.
+
+Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
+instead of `int` for indices and lengths.
+
+### Reference counts
+
+Some external consumers increment reference counts directly by calling
+`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
+
+These APIs no longer exist in BoringSSL. Instead, code which increments
+reference counts should call the corresponding `FOO_up_ref` function, such as
+`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
+may require `#ifdef`s.
+
+### Error codes
+
+OpenSSL's errors are extremely specific, leaking internals of the library,
+including even a function code for the function which emitted the error! As some
+logic in BoringSSL has been rewritten, code which conditions on the error may
+break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
+when upgrading OpenSSL versions.
+
+Where possible, avoid conditioning on the exact error reason. Otherwise, a
+BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
+still being determined. It's possible some new APIs will be added in the future.
+
+Function codes have been completely removed. Remove code which conditions on
+these as it will break with the slightest change in the library, OpenSSL or
+BoringSSL.
+
+### `*_ctrl` functions
+
+Some OpenSSL APIs are implemented with `ioctl`-style functions such as
+`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
+
+    # define SSL_CTX_set_mode(ctx,op) \
+            SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+
+In BoringSSL, these macros have been replaced with proper functions. The
+underlying `_ctrl` functions have been removed.
+
+For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
+existing code which uses them (or the wrapper macros) in `#ifdef` expressions
+will continue to function. However, the macros themselves will not work.
+
+Switch any `*_ctrl` callers to the macro/function versions. This works in both
+OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
+type-checked and may require more care with types.
+
+### HMAC `EVP_PKEY`s
+
+`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
+is compatible with OpenSSL.
+
+### DSA `EVP_PKEY`s
+
+`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
+DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
+
+### DES
+
+The `DES_cblock` type has been switched from an array to a struct to avoid the
+pitfalls around array types in C. Where features which require DES cannot be
+disabled, BoringSSL-specific codepaths may be necessary.
+
+### TLS renegotiation
+
+OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
+from the peer transparently. Renegotiation is an extremely problematic protocol
+feature, so BoringSSL rejects peer renegotiations by default.
+
+To enable renegotiation, call `SSL_set_reject_peer_renegotiations` and set it to
+off. Renegotiation is only supported as a client in SSL3/TLS and the
+HelloRequest must be received at a quiet point in the application protocol. This
+is sufficient to support the common use of requesting a new client certificate
+between an HTTP request and response in (unpipelined) HTTP/1.1.
+
+Things which do not work:
+
+* There is no support for renegotiation as a server.
+
+* There is no support for renegotiation in DTLS.
+
+* There is no support for initiating renegotiation; `SSL_renegotiate` always
+  fails and `SSL_set_state` does nothing.
+
+* Interleaving application data with the new handshake is forbidden.
+
+* If a HelloRequest is received while `SSL_write` has unsent application data,
+  the renegotiation is rejected.
+
+
+## Optional BoringSSL-specific simplifications
+
+BoringSSL makes some changes to OpenSSL which simplify the API but remain
+compatible with OpenSSL consumers. In general, consult the BoringSSL
+documentation for any functions in new BoringSSL-only code.
+
+### Return values
+
+Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
+has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
+code may take advantage of the less error-prone APIs and use `!` to check for
+errors.
+
+### Initialization
+
+OpenSSL has a number of different initialization functions for setting up error
+strings and loading algorithms, etc. All of these functions still exist in
+BoringSSL for convenience, but they do nothing and are not necessary.
+
+The one exception is `CRYPTO_library_init` (and `SSL_library_init` which merely
+calls it). In `BORINGSSL_NO_STATIC_INITIALIZER` builds, it must be called to
+query CPU capabitilies before the rest of the library. In the default
+configuration, this is done with a static initializer and is also unnecessary.
+
+### Threading
+
+OpenSSL provides a number of APIs to configure threading callbacks and set up
+locks. Without initializing these, the library is not thread-safe. Configuring
+these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
+corresponding Windows APIs internally and is always thread-safe where the API
+guarantees it.
diff --git a/src/STYLE b/src/STYLE
deleted file mode 100644
index 578da68..0000000
--- a/src/STYLE
+++ /dev/null
@@ -1,198 +0,0 @@
-BoringSSL Style Guide.
-
-BoringSSL usually follows the Google C++ style guide, found below. The
-rest of this document describes differences and clarifications on top
-of the base guide.
-
-https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
-
-
-Legacy code.
-
-As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
-that does not follow this style guide. Particularly where public API
-is concerned, balance consistency within a module with the benefits of
-a given rule. Module-wide deviations on naming should be respected
-while integer and return value conventions take precedence over
-consistency.
-
-Some modules have seen few changes, so they still retain the original
-indentation style for now. When editing these, try to retain the
-original style. For Emacs, doc/c-indentation.el from OpenSSL may be
-helpful in this.
-
-
-Language.
-
-The majority of the project is in C, so C++-specific rules in the
-Google style guide do not apply. Support for C99 features depends on
-our target platforms. Typically, Chromium's target MSVC is the most
-restrictive.
-
-Variable declarations in the middle of a function are allowed.
-
-Comments should be /* C-style */ for consistency.
-
-When declaration pointer types, * should be placed next to the variable
-name, not the type. So
-
-  uint8_t *ptr;
-
-not
-
-  uint8_t* ptr;
-
-Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
-OPENSSL_free(). Use the standard C assert() function freely.
-
-For new constants, prefer enums when the values are sequential and typed
-constants for flags. If adding values to an existing set of #defines, continue
-with #define.
-
-
-Formatting.
-
-Single-statement blocks are not allowed. All conditions and loops must
-use braces:
-
-  if (foo) {
-    do_something();
-  }
-
-not
-
-  if (foo)
-    do_something();
-
-
-Integers.
-
-Prefer using explicitly-sized integers where appropriate rather than
-generic C ones. For instance, to represent a byte, use uint8_t, not
-unsigned char. Likewise, represent a two-byte field as uint16_t, not
-unsigned short.
-
-Sizes are represented as size_t.
-
-Within a struct that is retained across the lifetime of an SSL
-connection, if bounds of a size are known and it's easy, use a smaller
-integer type like uint8_t. This is a "free" connection footprint
-optimization for servers. Don't make code significantly more complex
-for it, and do still check the bounds when passing in and out of the
-struct. This narrowing should not propagate to local variables and
-function parameters.
-
-When doing arithmetic, account for overflow conditions.
-
-Except with platform APIs, do not use ssize_t. MSVC lacks it, and
-prefer out-of-band error signaling for size_t (see Return values).
-
-
-Naming.
-
-Follow Google naming conventions in C++ files. In C files, use the
-following naming conventions for consistency with existing OpenSSL and C
-styles:
-
-Define structs with typedef named TYPE_NAME. The corresponding struct
-should be named struct type_name_st.
-
-Name public functions as MODULE_function_name, unless the module
-already uses a different naming scheme for legacy reasons. The module
-name should be a type name if the function is a method of a particular
-type.
-
-Some types are allocated within the library while others are
-initialized into a struct allocated by the caller, often on the
-stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
-TYPE_NAME_init/TYPE_NAME_cleanup, respectively. All TYPE_NAME_free
-functions must do nothing on NULL input.
-
-If a variable is the length of a pointer value, it has the suffix
-_len. An output parameter is named out or has an out_ prefix. For
-instance, For instance:
-
-  uint8_t *out,
-  size_t *out_len,
-  const uint8_t *in,
-  size_t in_len,
-
-Name public headers like include/openssl/evp.h with header guards like
-OPENSSL_HEADER_EVP_H. Name internal headers like crypto/ec/internal.h
-with header guards like OPENSSL_HEADER_EC_INTERNAL_H.
-
-Name enums like unix_hacker_t. For instance:
-
-enum should_free_handshake_buffer_t {
-  free_handshake_buffer,
-  dont_free_handshake_buffer,
-};
-
-
-Return values.
-
-As even malloc may fail in BoringSSL, the vast majority of functions
-will have a failure case. Functions should return int with one on
-success and zero on error. Do not overload the return value to both
-signal success/failure and output an integer. For example:
-
-  OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
-
-If a function needs more than a true/false result code, define an enum
-rather than arbitrarily assigning meaning to int values.
-
-If a function outputs a pointer to an object on success and there are no
-other outputs, return the pointer directly and NULL on error.
-
-
-Parameters.
-
-Where not constrained by legacy code, parameter order should be:
-
-1. context parameters
-2. output parameters
-3. input parameters
-
-For example,
-
-/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
- * ASN.1 object can be written. The |tag| argument will be used as the tag for
- * the object. It returns one on success or zero on error. */
-OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
-
-
-Documentation.
-
-All public symbols must have a documentation comment in their header
-file. The style is based on that of Go. The first sentence begins with
-the symbol name, optionally prefixed with "A" or "An". Apart from the
-initial mention of symbol, references to other symbols or parameter
-names should be surrounded by |pipes|.
-
-Documentation should be concise but completely describe the exposed
-behavior of the function. Pay special note to success/failure behaviors
-and caller obligations on object lifetimes. If this sacrifices
-conciseness, consider simplifying the function's behavior.
-
-/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
- * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
- * zero otherwise. */
-OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
-                                          size_t len);
-
-Explicitly mention any surprising edge cases or deviations from common
-return value patterns in legacy functions.
-
-/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
- * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
- * least |RSA_size| bytes of space. It returns the number of bytes written, or
- * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
- * values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use |RSA_sign_raw| instead. */
-OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
-                                       uint8_t *to, RSA *rsa, int padding);
-
-Document private functions in their internal.h header or, if static,
-where defined.
diff --git a/src/STYLE.md b/src/STYLE.md
new file mode 100644
index 0000000..d51de78
--- /dev/null
+++ b/src/STYLE.md
@@ -0,0 +1,197 @@
+# BoringSSL Style Guide
+
+BoringSSL usually follows the
+[Google C++ style guide](https://google-styleguide.googlecode.com/svn/trunk/cppguide.html).
+The rest of this document describes differences and clarifications on
+top of the base guide.
+
+
+## Legacy code
+
+As a derivative of OpenSSL, BoringSSL contains a lot of legacy code that
+does not follow this style guide. Particularly where public API is
+concerned, balance consistency within a module with the benefits of a
+given rule. Module-wide deviations on naming should be respected while
+integer and return value conventions take precedence over consistency.
+
+Some modules have seen few changes, so they still retain the original
+indentation style for now. When editing these, try to retain the
+original style. For Emacs, `doc/c-indentation.el` from OpenSSL may be
+helpful in this.
+
+
+## Language
+
+The majority of the project is in C, so C++-specific rules in the
+Google style guide do not apply. Support for C99 features depends on
+our target platforms. Typically, Chromium's target MSVC is the most
+restrictive.
+
+Variable declarations in the middle of a function are allowed.
+
+Comments should be `/* C-style */` for consistency.
+
+When declaration pointer types, `*` should be placed next to the variable
+name, not the type. So
+
+    uint8_t *ptr;
+
+not
+
+    uint8_t* ptr;
+
+Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
+and `OPENSSL_free()`. Use the standard C `assert()` function freely.
+
+For new constants, prefer enums when the values are sequential and typed
+constants for flags. If adding values to an existing set of `#define`s,
+continue with `#define`.
+
+
+## Formatting
+
+Single-statement blocks are not allowed. All conditions and loops must
+use braces:
+
+    if (foo) {
+      do_something();
+    }
+
+not
+
+    if (foo)
+      do_something();
+
+
+## Integers
+
+Prefer using explicitly-sized integers where appropriate rather than
+generic C ones. For instance, to represent a byte, use `uint8_t`, not
+`unsigned char`. Likewise, represent a two-byte field as `uint16_t`, not
+`unsigned short`.
+
+Sizes are represented as `size_t`.
+
+Within a struct that is retained across the lifetime of an SSL
+connection, if bounds of a size are known and it's easy, use a smaller
+integer type like `uint8_t`. This is a "free" connection footprint
+optimization for servers. Don't make code significantly more complex for
+it, and do still check the bounds when passing in and out of the
+struct. This narrowing should not propagate to local variables and
+function parameters.
+
+When doing arithmetic, account for overflow conditions.
+
+Except with platform APIs, do not use `ssize_t`. MSVC lacks it, and
+prefer out-of-band error signaling for `size_t` (see Return values).
+
+
+## Naming
+
+Follow Google naming conventions in C++ files. In C files, use the
+following naming conventions for consistency with existing OpenSSL and C
+styles:
+
+Define structs with typedef named `TYPE_NAME`. The corresponding struct
+should be named `struct type_name_st`.
+
+Name public functions as `MODULE_function_name`, unless the module
+already uses a different naming scheme for legacy reasons. The module
+name should be a type name if the function is a method of a particular
+type.
+
+Some types are allocated within the library while others are initialized
+into a struct allocated by the caller, often on the stack. Name these
+functions `TYPE_NAME_new`/`TYPE_NAME_free` and
+`TYPE_NAME_init`/`TYPE_NAME_cleanup`, respectively. All `TYPE_NAME_free`
+functions must do nothing on `NULL` input.
+
+If a variable is the length of a pointer value, it has the suffix
+`_len`. An output parameter is named `out` or has an `out_` prefix. For
+instance, For instance:
+
+    uint8_t *out,
+    size_t *out_len,
+    const uint8_t *in,
+    size_t in_len,
+
+Name public headers like `include/openssl/evp.h` with header guards like
+`OPENSSL_HEADER_EVP_H`. Name internal headers like
+`crypto/ec/internal.h` with header guards like
+`OPENSSL_HEADER_EC_INTERNAL_H`.
+
+Name enums like `enum unix_hacker_t`. For instance:
+
+    enum should_free_handshake_buffer_t {
+      free_handshake_buffer,
+      dont_free_handshake_buffer,
+    };
+
+
+## Return values
+
+As even `malloc` may fail in BoringSSL, the vast majority of functions
+will have a failure case. Functions should return `int` with one on
+success and zero on error. Do not overload the return value to both
+signal success/failure and output an integer. For example:
+
+    OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
+
+If a function needs more than a true/false result code, define an enum
+rather than arbitrarily assigning meaning to int values.
+
+If a function outputs a pointer to an object on success and there are no
+other outputs, return the pointer directly and `NULL` on error.
+
+
+## Parameters
+
+Where not constrained by legacy code, parameter order should be:
+
+1. context parameters
+2. output parameters
+3. input parameters
+
+For example,
+
+    /* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
+     * ASN.1 object can be written. The |tag| argument will be used as the tag for
+     * the object. It returns one on success or zero on error. */
+    OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+
+
+## Documentation
+
+All public symbols must have a documentation comment in their header
+file. The style is based on that of Go. The first sentence begins with
+the symbol name, optionally prefixed with "A" or "An". Apart from the
+initial mention of symbol, references to other symbols or parameter
+names should be surrounded by |pipes|.
+
+Documentation should be concise but completely describe the exposed
+behavior of the function. Pay special note to success/failure behaviors
+and caller obligations on object lifetimes. If this sacrifices
+conciseness, consider simplifying the function's behavior.
+
+    /* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
+     * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
+     * zero otherwise. */
+    OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
+                                              size_t len);
+
+Explicitly mention any surprising edge cases or deviations from common
+return value patterns in legacy functions.
+
+    /* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
+     * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
+     * least |RSA_size| bytes of space. It returns the number of bytes written, or
+     * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
+     * values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
+     *
+     * WARNING: this function is dangerous because it breaks the usual return value
+     * convention. Use |RSA_sign_raw| instead. */
+    OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+                                           uint8_t *to, RSA *rsa, int padding);
+
+Document private functions in their `internal.h` header or, if static,
+where defined.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6858cbb..3115279 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../include)
+include_directories(../include)
 
 if(APPLE)
   if (${ARCH} STREQUAL "x86")
@@ -57,7 +57,6 @@
   set(
     CRYPTO_ARCH_SOURCES
 
-    cpu-x86_64-asm.${ASM_EXT}
     cpu-intel.c
   )
 endif()
@@ -66,7 +65,6 @@
   set(
     CRYPTO_ARCH_SOURCES
 
-    cpu-x86-asm.${ASM_EXT}
     cpu-intel.c
   )
 endif()
@@ -230,6 +228,3 @@
 )
 
 target_link_libraries(refcount_test crypto)
-
-perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
-perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
diff --git a/src/crypto/aes/CMakeLists.txt b/src/crypto/aes/CMakeLists.txt
index 490f40a..c82d99a 100644
--- a/src/crypto/aes/CMakeLists.txt
+++ b/src/crypto/aes/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 if (${ARCH} STREQUAL "x86_64")
   set(
@@ -60,3 +60,12 @@
 perlasm(aes-armv4.${ASM_EXT} asm/aes-armv4.pl)
 perlasm(bsaes-armv7.${ASM_EXT} asm/bsaes-armv7.pl)
 perlasm(aesv8-armx.${ASM_EXT} asm/aesv8-armx.pl)
+
+add_executable(
+  aes_test
+
+  aes_test.cc
+  $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(aes_test crypto)
diff --git a/src/crypto/aes/aes_test.cc b/src/crypto/aes/aes_test.cc
new file mode 100644
index 0000000..e488d81
--- /dev/null
+++ b/src/crypto/aes/aes_test.cc
@@ -0,0 +1,102 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/crypto.h>
+
+
+static bool TestAES(const uint8_t *key, size_t key_len,
+                    const uint8_t plaintext[AES_BLOCK_SIZE],
+                    const uint8_t ciphertext[AES_BLOCK_SIZE]) {
+  AES_KEY aes_key;
+  if (AES_set_encrypt_key(key, key_len * 8, &aes_key) != 0) {
+    fprintf(stderr, "AES_set_encrypt_key failed\n");
+    return false;
+  }
+
+  // Test encryption.
+  uint8_t block[AES_BLOCK_SIZE];
+  AES_encrypt(plaintext, block, &aes_key);
+  if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+    fprintf(stderr, "AES_encrypt gave the wrong output\n");
+    return false;
+  }
+
+  // Test in-place encryption.
+  memcpy(block, plaintext, AES_BLOCK_SIZE);
+  AES_encrypt(block, block, &aes_key);
+  if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+    fprintf(stderr, "AES_encrypt gave the wrong output\n");
+    return false;
+  }
+
+  if (AES_set_decrypt_key(key, key_len * 8, &aes_key) != 0) {
+    fprintf(stderr, "AES_set_decrypt_key failed\n");
+    return false;
+  }
+
+  // Test decryption.
+  AES_decrypt(ciphertext, block, &aes_key);
+  if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+    fprintf(stderr, "AES_decrypt gave the wrong output\n");
+    return false;
+  }
+
+  // Test in-place decryption.
+  memcpy(block, ciphertext, AES_BLOCK_SIZE);
+  AES_decrypt(block, block, &aes_key);
+  if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+    fprintf(stderr, "AES_decrypt gave the wrong output\n");
+    return false;
+  }
+  return true;
+}
+
+int main() {
+  CRYPTO_library_init();
+
+  // Test vectors from FIPS-197, Appendix C.
+  if (!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+                                "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               128 / 8,
+               (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+                                "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               (const uint8_t *)"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+                                "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a") ||
+      !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+                                "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                                "\x10\x11\x12\x13\x14\x15\x16\x17",
+               192 / 8,
+               (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+                                "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               (const uint8_t *)"\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+                                "\x6e\xaf\x70\xa0\xec\x0d\x71\x91") ||
+      !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+                                "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                                "\x10\x11\x12\x13\x14\x15\x16\x17"
+                                "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               256 / 8,
+               (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+                                "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               (const uint8_t *)"\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+                                "\xea\xfc\x49\x90\x4b\x49\x60\x89")) {
+    return false;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/aes/asm/aes-586.pl b/src/crypto/aes/asm/aes-586.pl
index 07fb94c..6e8a6a8 100755
--- a/src/crypto/aes/asm/aes-586.pl
+++ b/src/crypto/aes/asm/aes-586.pl
@@ -45,7 +45,7 @@
 # the undertaken effort was that it appeared that in tight IA-32
 # register window little-endian flavor could achieve slightly higher
 # Instruction Level Parallelism, and it indeed resulted in up to 15%
-# better performance on most recent µ-archs...
+# better performance on most recent µ-archs...
 #
 # Third version adds AES_cbc_encrypt implementation, which resulted in
 # up to 40% performance imrovement of CBC benchmark results. 40% was
@@ -224,7 +224,7 @@
 $speed_limit=512;	# chunks smaller than $speed_limit are
 			# processed with compact routine in CBC mode
 $small_footprint=1;	# $small_footprint=1 code is ~5% slower [on
-			# recent µ-archs], but ~5 times smaller!
+			# recent µ-archs], but ~5 times smaller!
 			# I favor compact code to minimize cache
 			# contention and in hope to "collect" 5% back
 			# in real-life applications...
@@ -565,7 +565,7 @@
 # Performance is not actually extraordinary in comparison to pure
 # x86 code. In particular encrypt performance is virtually the same.
 # Decrypt performance on the other hand is 15-20% better on newer
-# µ-archs [but we're thankful for *any* improvement here], and ~50%
+# µ-archs [but we're thankful for *any* improvement here], and ~50%
 # better on PIII:-) And additionally on the pros side this code
 # eliminates redundant references to stack and thus relieves/
 # minimizes the pressure on the memory bus.
diff --git a/src/crypto/aes/asm/aes-armv4.pl b/src/crypto/aes/asm/aes-armv4.pl
index 36cd3b6..882017a 100644
--- a/src/crypto/aes/asm/aes-armv4.pl
+++ b/src/crypto/aes/asm/aes-armv4.pl
@@ -65,7 +65,7 @@
 $code=<<___;
 #if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 #else
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
diff --git a/src/crypto/aes/asm/aesv8-armx.pl b/src/crypto/aes/asm/aesv8-armx.pl
index b0916f6..121154a 100644
--- a/src/crypto/aes/asm/aesv8-armx.pl
+++ b/src/crypto/aes/asm/aesv8-armx.pl
@@ -45,7 +45,7 @@
 $prefix="aes_v8";
 
 $code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 #if __ARM_MAX_ARCH__>=7
 .text
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 273f0b9..7fe349a 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -703,7 +703,7 @@
 $code.=<<___;
 #if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 
 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index 283636e..41e3122 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   asn1
diff --git a/src/crypto/asn1/a_bitstr.c b/src/crypto/asn1/a_bitstr.c
index 8055f0c..8bad339 100644
--- a/src/crypto/asn1/a_bitstr.c
+++ b/src/crypto/asn1/a_bitstr.c
@@ -125,8 +125,7 @@
 
 	if (len < 1)
 		{
-		OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
-			ASN1_R_STRING_TOO_SHORT);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
 		goto err;
 		}
 
@@ -141,8 +140,7 @@
 	padding = *(p++);
 	if (padding > 7)
 		{
-		OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
-			ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
 		goto err;
 		}
 
@@ -157,8 +155,7 @@
 		s=(unsigned char *)OPENSSL_malloc((int)len);
 		if (s == NULL)
 			{
-			OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
-				ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 		memcpy(s,p,(int)len);
@@ -209,7 +206,7 @@
 								 w+1);
 		if (c == NULL)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_BIT_STRING_set_bit, ERR_R_MALLOC_FAILURE);
+			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);
diff --git a/src/crypto/asn1/a_bool.c b/src/crypto/asn1/a_bool.c
index c30ee48..826bcf4 100644
--- a/src/crypto/asn1/a_bool.c
+++ b/src/crypto/asn1/a_bool.c
@@ -107,6 +107,6 @@
 	*pp=p;
 	return(ret);
 err:
-	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_BOOLEAN, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	return(ret);
 	}
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
index 8874f48..1904375 100644
--- a/src/crypto/asn1/a_bytes.c
+++ b/src/crypto/asn1/a_bytes.c
@@ -125,7 +125,7 @@
 	*pp=p;
 	return(ret);
 err:
-	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		ASN1_STRING_free(ret);
 	return(NULL);
@@ -243,7 +243,7 @@
 err:
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		ASN1_STRING_free(ret);
-	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_bytes, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	return(NULL);
 	}
 
@@ -309,7 +309,7 @@
 	if (os != NULL) ASN1_STRING_free(os);
 	return(1);
 err:
-	OPENSSL_PUT_ERROR(ASN1, asn1_collate_primitive, c->error);
+	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 6022c74..97ec75b 100644
--- a/src/crypto/asn1/a_d2i_fp.c
+++ b/src/crypto/asn1/a_d2i_fp.c
@@ -75,7 +75,7 @@
 
         if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_d2i_fp, ERR_R_BUF_LIB);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
                 return(NULL);
 		}
         BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -129,7 +129,7 @@
 
         if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_d2i_fp, ERR_R_BUF_LIB);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
                 return(NULL);
 		}
         BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -154,7 +154,7 @@
 	b=BUF_MEM_new();
 	if (b == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return -1;
 		}
 
@@ -167,20 +167,20 @@
 
 			if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+				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_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
 				goto err;
 				}
 			if (i > 0)
 				{
 				if (len+i < len)
 					{
-					OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
 					goto err;
 					}
 				len+=i;
@@ -211,7 +211,7 @@
 			eos++;
 			if (eos < 0)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_HEADER_TOO_LONG);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
 				goto err;
 				}
 			want=HEADER_SIZE;
@@ -235,12 +235,12 @@
 				if (want > INT_MAX /* BIO_read takes an int length */ ||
 					len+want < len)
 						{
-						OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+						OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
 						goto err;
 						}
 				if (!BUF_MEM_grow_clean(b,len+want))
 					{
-					OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+					OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 					goto err;
 					}
 				while (want > 0)
@@ -248,7 +248,7 @@
 					i=BIO_read(in,&(b->data[len]),want);
 					if (i <= 0)
 						{
-						OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+						OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
 						goto err;
 						}
 					/* This can't overflow because
@@ -259,7 +259,7 @@
 				}
 			if (off + c.slen < off)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
 				goto err;
 				}
 			off+=c.slen;
@@ -274,7 +274,7 @@
 
 	if (off > INT_MAX)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
 		goto err;
 		}
 
diff --git a/src/crypto/asn1/a_dup.c b/src/crypto/asn1/a_dup.c
index 8ec1c5f..5e87457 100644
--- a/src/crypto/asn1/a_dup.c
+++ b/src/crypto/asn1/a_dup.c
@@ -72,7 +72,7 @@
 	i=i2d(x,NULL);
 	b=OPENSSL_malloc(i+10);
 	if (b == NULL)
-		{ OPENSSL_PUT_ERROR(ASN1, ASN1_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+		{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
 	p= b;
 	i=i2d(x,&p);
 	p2= b;
@@ -95,7 +95,7 @@
 
 	i=ASN1_item_i2d(x,&b,it);
 	if (b == NULL)
-		{ OPENSSL_PUT_ERROR(ASN1, ASN1_item_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+		{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
 	p= b;
 	ret=ASN1_item_d2i(NULL,&p,i, it);
 	OPENSSL_free(b);
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index a581a34..579dafd 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -84,7 +84,7 @@
 		}
 	if (a->data == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_set, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(0);
 		}
 	d=v;
@@ -147,7 +147,7 @@
 		ret=ai;
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 		goto err;
 		}
 	if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
@@ -159,7 +159,7 @@
 		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
 		if (!new_data)
 			{
-			OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 		ret->data=new_data;
@@ -177,7 +177,7 @@
 	BIGNUM *ret;
 
 	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
-		OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_to_BN, ASN1_R_BN_LIB);
+		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 be093a4..7cb18a9 100644
--- a/src/crypto/asn1/a_gentm.c
+++ b/src/crypto/asn1/a_gentm.c
@@ -239,7 +239,7 @@
 		p=OPENSSL_malloc(len);
 		if (p == NULL)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_GENERALIZEDTIME_adj, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return(NULL);
 			}
 		if (s->data != NULL)
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 11e40d3..74ded78 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -67,7 +67,7 @@
 
         if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_fp, ERR_R_BUF_LIB);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
                 return(0);
 		}
         BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -76,7 +76,7 @@
         return(ret);
         }
 
-int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
 	{
 	char *b;
 	unsigned char *p;
@@ -86,7 +86,7 @@
 	b=(char *)OPENSSL_malloc(n);
 	if (b == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_bio, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(0);
 		}
 
@@ -116,7 +116,7 @@
 
         if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_fp, ERR_R_BUF_LIB);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
                 return(0);
 		}
         BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -133,7 +133,7 @@
 	n = ASN1_item_i2d(x, &b, it);
 	if (b == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_bio, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(0);
 		}
 
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 2ecccc5..9a56534 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -257,7 +257,7 @@
 	*pp=pend;
 	return(ret);
 err:
-	OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_INTEGER, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		M_ASN1_INTEGER_free(ret);
 	return(NULL);
@@ -327,7 +327,7 @@
 	*pp=p;
 	return(ret);
 err:
-	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_UINTEGER, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		M_ASN1_INTEGER_free(ret);
 	return(NULL);
@@ -350,7 +350,7 @@
 		}
 	if (a->data == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_set, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(0);
 		}
 	d=v;
@@ -413,7 +413,7 @@
 		ret=ai;
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ASN1_R_NESTED_ASN1_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 		goto err;
 		}
 	if (BN_is_negative(bn) && !BN_is_zero(bn))
@@ -426,7 +426,7 @@
 		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
 		if (!new_data)
 			{
-			OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 		ret->data=new_data;
@@ -449,7 +449,7 @@
 	BIGNUM *ret;
 
 	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
-		OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_to_BN, ASN1_R_BN_LIB);
+		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 9abe659..42806d1 100644
--- a/src/crypto/asn1/a_mbstr.c
+++ b/src/crypto/asn1/a_mbstr.c
@@ -108,7 +108,7 @@
 
 		case MBSTRING_BMP:
 		if(len & 1) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ASN1_R_INVALID_BMPSTRING_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
 			return -1;
 		}
 		nchar = len >> 1;
@@ -116,7 +116,7 @@
 
 		case MBSTRING_UNIV:
 		if(len & 3) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
 			return -1;
 		}
 		nchar = len >> 2;
@@ -127,7 +127,7 @@
 		/* 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_mbstring_ncopy,  ASN1_R_INVALID_UTF8STRING);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
 			return -1;
 		}
 		break;
@@ -137,19 +137,19 @@
 		break;
 
 		default:
-		OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ASN1_R_UNKNOWN_FORMAT);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
 		return -1;
 	}
 
 	if((minsize > 0) && (nchar < minsize)) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ASN1_R_STRING_TOO_SHORT);
+		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_mbstring_ncopy,  ASN1_R_STRING_TOO_LONG);
+		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;
@@ -157,7 +157,7 @@
 
 	/* Now work out minimal type (if any) */
 	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ASN1_R_ILLEGAL_CHARACTERS);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
 		return -1;
 	}
 
@@ -191,7 +191,7 @@
 		free_out = 1;
 		dest = ASN1_STRING_type_new(str_type);
 		if(!dest) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return -1;
 		}
 		*out = dest;
@@ -199,7 +199,7 @@
 	/* If both the same type just copy across */
 	if(inform == outform) {
 		if(!ASN1_STRING_set(dest, in, len)) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return -1;
 		}
 		return str_type;
@@ -230,7 +230,7 @@
 	}
 	if(!(p = OPENSSL_malloc(outlen + 1))) {
 		if(free_out) ASN1_STRING_free(dest);
-		OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return -1;
 	}
 	dest->length = outlen;
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 189886c..6ddfca9 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -106,13 +106,13 @@
 		}
 	else
 		{
-		OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
 		goto err;
 		}
 
 	if (num <= 0)
 		{
-		OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
 		goto err;
 		}
 	c= *(p++);
@@ -122,7 +122,7 @@
 		if (num <= 0) break;
 		if ((c != '.') && (c != ' '))
 			{
-			OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
 			goto err;
 			}
 		l=0;
@@ -136,7 +136,7 @@
 				break;
 			if ((c < '0') || (c > '9'))
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
 				goto err;
 				}
 			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
@@ -160,7 +160,7 @@
 			{
 			if ((first < 2) && (l >= 40))
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
 				goto err;
 				}
 			if (use_bn)
@@ -204,7 +204,7 @@
 			{
 			if (len+i > olen)
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
 				goto err;
 				}
 			while (--i > 0)
@@ -280,7 +280,7 @@
 	if(ret) *pp = p;
 	return ret;
 err:
-	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	return(NULL);
 }
 
@@ -300,7 +300,7 @@
 	if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
 	    p[len - 1] & 0x80)
 		{
-		OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
 		return NULL;
 		}
 	/* Now 0 < len <= INT_MAX, so the cast is safe. */
@@ -309,7 +309,7 @@
 		{
 		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
 			{
-			OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
 			return NULL;
 			}
 		}
@@ -350,7 +350,7 @@
 	*pp=p;
 	return(ret);
 err:
-	OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, i);
+	OPENSSL_PUT_ERROR(ASN1, i);
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		ASN1_OBJECT_free(ret);
 	return(NULL);
@@ -363,7 +363,7 @@
 	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_OBJECT_new, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(NULL);
 		}
 	ret->length=0;
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index df849e1..d4316f7 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -215,13 +215,13 @@
 	flags &= ~STABLE_FLAGS_MALLOC;
 	if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
 	if(!stable) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add,  ERR_R_MALLOC_FAILURE);
+		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, ASN1_STRING_TABLE_add,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return 0;
 		}
 		tmp->flags = flags | STABLE_FLAGS_MALLOC;
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index e02e858..ac2cb48 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -85,7 +85,7 @@
 	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, XXX, ASN1_R_EXPECTING_A_TIME);
+	OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
 	return -1;
 	}
 #endif
@@ -105,7 +105,7 @@
 	ts=OPENSSL_gmtime(&t,&data);
 	if (ts == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_TIME_adj,  ASN1_R_ERROR_GETTING_TIME);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
 		return NULL;
 		}
 	if (offset_day || offset_sec)
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index 52b010f..dbbbecb 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -81,12 +81,12 @@
 		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_NESTED_ASN1_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
 		return(NULL);
 		}
 	if (!ASN1_UTCTIME_check(ret))
 		{
-		OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_INVALID_TIME_FORMAT);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
 		goto err;
 		}
 
@@ -257,7 +257,7 @@
 		p=OPENSSL_malloc(len);
 		if (p == NULL)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_UTCTIME_adj, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 		if (s->data != NULL)
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 9aa2678..a109749 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -69,17 +69,10 @@
 OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
 
 /* Cross-module errors from crypto/x509/i2d_pr.c */
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, i2d_PrivateKey);
 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. */
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, ASN1_generate_v3);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_cb);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, parse_tagging);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, append_exp);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_str2type);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, bitstr_cb);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -183,7 +176,7 @@
 #endif
 	if (*plength > (omax - (p - *pp)))
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_TOO_LONG);
+		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;
@@ -191,7 +184,7 @@
 	*pp=p;
 	return(ret|inf);
 err:
-	OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_HEADER_TOO_LONG);
+	OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
 	return(0x80);
 	}
 
@@ -433,7 +426,7 @@
 
 		if (str->data == NULL)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_set, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			str->data=c;
 			return(0);
 			}
@@ -469,7 +462,7 @@
 	ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_type_new, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return(NULL);
 		}
 	ret->length=0;
diff --git a/src/crypto/asn1/asn_pack.c b/src/crypto/asn1/asn_pack.c
index ee58fa5..e842a10 100644
--- a/src/crypto/asn1/asn_pack.c
+++ b/src/crypto/asn1/asn_pack.c
@@ -68,7 +68,7 @@
 
 	if (!oct || !*oct) {
 		if (!(octmp = ASN1_STRING_new ())) {
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return NULL;
 		}
 		if (oct) *oct = octmp;
@@ -80,11 +80,11 @@
 	}
 		
 	if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ASN1_R_ENCODE_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
 		return NULL;
 	}
 	if (!octmp->data) {
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return NULL;
 	}
 	return octmp;
@@ -99,6 +99,6 @@
 
 	p = oct->data;
 	if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_unpack, ASN1_R_DECODE_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
 	return ret;
 }
diff --git a/src/crypto/asn1/bio_ndef.c b/src/crypto/asn1/bio_ndef.c
index 2f7105d..f07d3de 100644
--- a/src/crypto/asn1/bio_ndef.c
+++ b/src/crypto/asn1/bio_ndef.c
@@ -112,7 +112,7 @@
 
 	if (!aux || !aux->asn1_cb)
 		{
-		OPENSSL_PUT_ERROR(ASN1, BIO_new_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
 		return NULL;
 		}
 	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index 530afe5..bcdb773 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -144,7 +144,7 @@
 		i-=again;
 		if (i%2 != 0)
 			{
-			OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
 			goto err;
 			}
 		i/=2;
@@ -158,7 +158,7 @@
 					(unsigned int)num+i*2);
 			if (sp == NULL)
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			s=sp;
@@ -177,7 +177,7 @@
 					m=m-'A'+10;
 				else
 					{
-					OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_NON_HEX_CHARACTERS);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
 					goto err;
 					}
 				s[num+j]<<=4;
@@ -197,7 +197,7 @@
 	if (0)
 		{
 err_sl:
-		OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
 		}
 	if (s != NULL)
 		OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 2c4fe6f..5186304 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -149,7 +149,7 @@
 		i-=again;
 		if (i%2 != 0)
 			{
-			OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
 			goto err;
 			}
 		i/=2;
@@ -162,7 +162,7 @@
 				sp=OPENSSL_realloc_clean(s,slen,num+i*2);
 			if (sp == NULL)
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			s=sp;
@@ -181,7 +181,7 @@
 					m=m-'A'+10;
 				else
 					{
-					OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_NON_HEX_CHARACTERS);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
 					goto err;
 					}
 				s[num+j]<<=4;
@@ -201,7 +201,7 @@
 	if (0)
 		{
 err_sl:
-		OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
 		}
 	if (s != NULL)
 		OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index 2f53670..5a7fe36 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -142,7 +142,7 @@
 		i-=again;
 		if (i%2 != 0)
 			{
-			OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
 			goto err;
 			}
 		i/=2;
@@ -156,7 +156,7 @@
 					(unsigned int)num+i*2);
 			if (sp == NULL)
 				{
-				OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			s=sp;
@@ -175,7 +175,7 @@
 					m=m-'A'+10;
 				else
 					{
-					OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_NON_HEX_CHARACTERS);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
 					goto err;
 					}
 				s[num+j]<<=4;
@@ -195,7 +195,7 @@
 	if (0)
 		{
 err_sl:
-		OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
 		}
 	if (s != NULL)
 		OPENSSL_free(s);
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 73d3bb3..507a842 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -189,7 +189,7 @@
 			 */
 			if ((tag != -1) || opt)
 				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
 				goto err;
 				}
 			return asn1_template_ex_d2i(pval, in, len,
@@ -206,7 +206,7 @@
 						&p, len, -1, 0, 1, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 
@@ -215,7 +215,7 @@
 			{
 			/* If OPTIONAL, assume this is OK */
 			if (opt) return -1;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_MSTRING_NOT_UNIVERSAL);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
 			goto err;
 			}
 		/* Check tag matches bit map */
@@ -224,7 +224,7 @@
 			/* If OPTIONAL, assume this is OK */
 			if (opt)
 				return -1;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_MSTRING_WRONG_TAG);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
 			goto err;
 			}
 		return asn1_d2i_ex_primitive(pval, in, len,
@@ -255,7 +255,7 @@
 					&p, len, exptag, aclass, 1, ctx);
 			if (!ret)
 				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 				goto err;
 				}
 			if (ret == -1)
@@ -283,7 +283,7 @@
 			imphack = *wp;
 			if (p == NULL)
 				{
-				OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 				goto err;
 				}
 			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
@@ -298,7 +298,7 @@
 		if (ptmpval)
 			return 1;
 
-		OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 		goto err;
 
 
@@ -320,7 +320,7 @@
 			}
 		else if (!ASN1_item_ex_new(pval, it))
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 		/* CHOICE type, try each possibility in turn */
@@ -340,7 +340,7 @@
 				break;
 			/* Otherwise must be an ASN1 parsing error */
 			errtt = tt;
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 
@@ -354,7 +354,7 @@
 				ASN1_item_ex_free(pval, it);
 				return -1;
 				}
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NO_MATCHING_CHOICE_TYPE);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
 			goto err;
 			}
 
@@ -380,7 +380,7 @@
 					&p, len, tag, aclass, opt, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 		else if (ret == -1)
@@ -394,13 +394,13 @@
 		else seq_nolen = seq_eoc;
 		if (!cst)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
 			goto err;
 			}
 
 		if (!*pval && !ASN1_item_ex_new(pval, it))
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 
@@ -437,7 +437,7 @@
 				{
 				if (!seq_eoc)
 					{
-					OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_UNEXPECTED_EOC);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
 					goto err;
 					}
 				len -= p - q;
@@ -479,13 +479,13 @@
 		/* Check for EOC if expecting one */
 		if (seq_eoc && !asn1_check_eoc(&p, len))
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_MISSING_EOC);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
 			goto err;
 			}
 		/* Check all data read */
 		if (!seq_nolen && len)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
 			goto err;
 			}
 
@@ -508,7 +508,7 @@
 			else
 				{
 				errtt = seqtt;
-				OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_FIELD_MISSING);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
 				goto err;
 				}
 			}
@@ -524,7 +524,7 @@
 		return 0;
 		}
 	auxerr:
-	OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i,  ASN1_R_AUX_ERROR);
+	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
 	err:
 	ASN1_item_ex_free(pval, it);
 	if (errtt)
@@ -569,21 +569,21 @@
 		q = p;
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 		else if (ret == -1)
 			return -1;
 		if (!cst)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i,  ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+			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_template_ex_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 		/* We read the field in OK so update length */
@@ -593,7 +593,7 @@
 			/* If NDEF we must have an EOC here */
 			if (!asn1_check_eoc(&p, len))
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i,  ASN1_R_MISSING_EOC);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
 				goto err;
 				}
 			}
@@ -603,7 +603,7 @@
 			 * an error */
 			if (len)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i,  ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
 				goto err;
 				}
 			}
@@ -659,7 +659,7 @@
 					&p, len, sktag, skaclass, opt, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 		else if (ret == -1)
@@ -682,7 +682,7 @@
 				
 		if (!*val)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 
@@ -696,7 +696,7 @@
 				{
 				if (!sk_eoc)
 					{
-					OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_UNEXPECTED_EOC);
+					OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
 					goto err;
 					}
 				len -= p - q;
@@ -708,20 +708,20 @@
 						ASN1_ITEM_ptr(tt->item),
 						-1, 0, 0, ctx))
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+				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, asn1_template_noexp_d2i,  ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			}
 		if (sk_eoc)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_MISSING_EOC);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
 			goto err;
 			}
 		}
@@ -732,7 +732,7 @@
 			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 		else if (ret == -1)
@@ -745,7 +745,7 @@
 							-1, 0, opt, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			goto err;
 			}
 		else if (ret == -1)
@@ -775,7 +775,7 @@
 	long len; 
 	if (!pval)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_ILLEGAL_NULL);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
 		return 0; /* Should never happen */
 		}
 
@@ -793,12 +793,12 @@
 		unsigned char oclass;
 		if (tag >= 0)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_ILLEGAL_TAGGED_ANY);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
 			return 0;
 			}
 		if (opt)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_ILLEGAL_OPTIONAL_ANY);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
 			return 0;
 			}
 		p = *in;
@@ -806,7 +806,7 @@
 					&p, inlen, -1, 0, 0, ctx);
 		if (!ret)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 		if (oclass != V_ASN1_UNIVERSAL)
@@ -823,7 +823,7 @@
 				&p, inlen, tag, aclass, opt, ctx);
 	if (!ret)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_NESTED_ASN1_ERROR);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 		return 0;
 		}
 	else if (ret == -1)
@@ -843,7 +843,7 @@
 		/* SEQUENCE and SET must be constructed */
 		else if (!cst)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ASN1_R_TYPE_NOT_CONSTRUCTED);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
 			return 0;
 			}
 
@@ -869,8 +869,7 @@
 			|| utype == V_ASN1_ENUMERATED)
 			{
 			/* These types only have primitive encodings. */
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,
-				ASN1_R_TYPE_NOT_PRIMITIVE);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
 			return 0;
 			}
 
@@ -892,7 +891,7 @@
 		/* Append a final null to string */
 		if (!BUF_MEM_grow_clean(&buf, len + 1))
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return 0;
 			}
 		buf.data[len] = 0;
@@ -960,7 +959,7 @@
 		case V_ASN1_NULL:
 		if (len)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ASN1_R_NULL_IS_WRONG_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
 			goto err;
 			}
 		*pval = (ASN1_VALUE *)1;
@@ -969,7 +968,7 @@
 		case V_ASN1_BOOLEAN:
 		if (len != 1)
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
 			goto err;
 			}
 		else
@@ -1016,12 +1015,12 @@
 		default:
 		if (utype == V_ASN1_BMPSTRING && (len & 1))
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
 			goto err;
 			}
 		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
 			goto err;
 			}
 		/* All based on ASN1_STRING and handled the same */
@@ -1030,7 +1029,7 @@
 			stmp = ASN1_STRING_type_new(utype);
 			if (!stmp)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			*pval = (ASN1_VALUE *)stmp;
@@ -1053,7 +1052,7 @@
 			{
 			if (!ASN1_STRING_set(stmp, cont, len))
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i,  ERR_R_MALLOC_FAILURE);
+				OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 				ASN1_STRING_free(stmp);	
 				*pval = NULL;
 				goto err;
@@ -1115,7 +1114,7 @@
 		if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
 				-1, 0, 0, NULL))
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_find_end,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 		if (inf)
@@ -1126,7 +1125,7 @@
 		}
 	if (expected_eoc)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_find_end,  ASN1_R_MISSING_EOC);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
 		return 0;
 		}
 	*in = p;
@@ -1173,7 +1172,7 @@
 			 * constructed form */
 			if (!inf)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_collect,  ASN1_R_UNEXPECTED_EOC);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
 				return 0;
 				}
 			inf = 0;
@@ -1183,7 +1182,7 @@
 		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
 					len, tag, aclass, 0, NULL))
 			{
-			OPENSSL_PUT_ERROR(ASN1, asn1_collect,  ASN1_R_NESTED_ASN1_ERROR);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
 			return 0;
 			}
 
@@ -1192,7 +1191,7 @@
 			{
 			if (depth >= ASN1_MAX_STRING_NEST)
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_collect,  ASN1_R_NESTED_ASN1_STRING);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
 				return 0;
 				}
 			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
@@ -1205,7 +1204,7 @@
 		}
 	if (inf)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_collect,  ASN1_R_MISSING_EOC);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
 		return 0;
 		}
 	*in = p;
@@ -1220,7 +1219,7 @@
 		len = buf->length;
 		if (!BUF_MEM_grow_clean(buf, len + plen))
 			{
-			OPENSSL_PUT_ERROR(ASN1, collect_data,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			return 0;
 			}
 		memcpy(buf->data + len, *p, plen);
@@ -1288,7 +1287,7 @@
 			 */
 			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
 				{
-				OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen,  ASN1_R_TOO_LONG);
+				OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
 				asn1_tlc_clear(ctx);
 				return 0;
 				}
@@ -1297,7 +1296,7 @@
 
 	if (i & 0x80)
 		{
-		OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen,  ASN1_R_BAD_OBJECT_HEADER);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
 		asn1_tlc_clear(ctx);
 		return 0;
 		}
@@ -1310,7 +1309,7 @@
 			 */
 			if (opt) return -1;
 			asn1_tlc_clear(ctx);
-			OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen,  ASN1_R_WRONG_TAG);
+			OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
 			return 0;
 			}
 		/* We have a tag and class match:
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index 6d69dcb..c68fe06 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -209,7 +209,7 @@
 	return 1;
 
 	memerr:
-	OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new,  ERR_R_MALLOC_FAILURE);
+	OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 	ASN1_item_ex_free(pval, it);
 #ifdef CRYPTO_MDEBUG
 	if (it->sname) CRYPTO_pop_info();
@@ -217,7 +217,7 @@
 	return 0;
 
 	auxerr:
-	OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new,  ASN1_R_AUX_ERROR);
+	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
 	ASN1_item_ex_free(pval, it);
 #ifdef CRYPTO_MDEBUG
 	if (it->sname) CRYPTO_pop_info();
@@ -289,7 +289,7 @@
 		skval = sk_ASN1_VALUE_new_null();
 		if (!skval)
 			{
-			OPENSSL_PUT_ERROR(ASN1, ASN1_template_new,  ERR_R_MALLOC_FAILURE);
+			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 			ret = 0;
 			goto done;
 			}
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index df19ff0..6a097a1 100644
--- a/src/crypto/asn1/tasn_prn.c
+++ b/src/crypto/asn1/tasn_prn.c
@@ -88,7 +88,7 @@
 	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
 	if (ret == NULL)
 		{
-		OPENSSL_PUT_ERROR(ASN1, ASN1_PCTX_new, ERR_R_MALLOC_FAILURE);
+		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
 		return NULL;
 		}
 	ret->flags = 0;
diff --git a/src/crypto/asn1/tasn_utl.c b/src/crypto/asn1/tasn_utl.c
index ff3764e..960cdbb 100644
--- a/src/crypto/asn1/tasn_utl.c
+++ b/src/crypto/asn1/tasn_utl.c
@@ -260,8 +260,7 @@
 err:
   /* FIXME: should log the value or OID of unsupported type */
   if (nullerr) {
-    OPENSSL_PUT_ERROR(ASN1, asn1_do_adb,
-                      ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
   }
   return NULL;
 }
diff --git a/src/crypto/asn1/x_long.c b/src/crypto/asn1/x_long.c
index 5c2f96e..7b1a6fe 100644
--- a/src/crypto/asn1/x_long.c
+++ b/src/crypto/asn1/x_long.c
@@ -150,7 +150,7 @@
 	unsigned long utmp = 0;
 	char *cp = (char *)pval;
 	if(len > (int)sizeof(long)) {
-		OPENSSL_PUT_ERROR(ASN1, long_c2i,  ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
 		return 0;
 	}
 	/* Is it negative? */
@@ -168,7 +168,7 @@
 		ltmp = -ltmp;
 	}
 	if(ltmp == it->size) {
-		OPENSSL_PUT_ERROR(ASN1, long_c2i,  ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
 		return 0;
 	}
 	memcpy(cp, &ltmp, sizeof(long));
diff --git a/src/crypto/base64/CMakeLists.txt b/src/crypto/base64/CMakeLists.txt
index 42037a5..f1dba6c 100644
--- a/src/crypto/base64/CMakeLists.txt
+++ b/src/crypto/base64/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   base64
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index dbf5951..8de090a 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   bio
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 5ac5911..4bc98ba 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -90,7 +90,7 @@
 BIO *BIO_new(const BIO_METHOD *method) {
   BIO *ret = OPENSSL_malloc(sizeof(BIO));
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(BIO, BIO_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -153,7 +153,7 @@
   }
 
   if (io_func == NULL) {
-    OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
 
@@ -165,7 +165,7 @@
   }
 
   if (!bio->init) {
-    OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNINITIALIZED);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return -2;
   }
 
@@ -217,7 +217,7 @@
   }
 
   if (bio->method == NULL || bio->method->ctrl == NULL) {
-    OPENSSL_PUT_ERROR(BIO, BIO_ctrl, BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
 
@@ -323,7 +323,7 @@
   }
 
   if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
-    OPENSSL_PUT_ERROR(BIO, BIO_callback_ctrl, BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
@@ -462,6 +462,10 @@
   ERR_print_errors_cb(print_bio, bio);
 }
 
+void ERR_print_errors(BIO *bio) {
+  BIO_print_errors(bio);
+}
+
 /* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
  * success, |*out| is set to an allocated buffer (which should be freed with
  * |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index f3aad6f..ef56111 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -70,7 +70,7 @@
   const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
 
   if (!buf && len != 0) {
-    OPENSSL_PUT_ERROR(BIO, BIO_new_mem_buf, BIO_R_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER);
     return NULL;
   }
 
@@ -167,7 +167,7 @@
   b = (BUF_MEM *)bio->ptr;
 
   if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
-    OPENSSL_PUT_ERROR(BIO, mem_write, BIO_R_WRITE_TO_READ_ONLY_BIO);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
     goto err;
   }
 
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
index 3fc0685..9d0cb3c 100644
--- a/src/crypto/bio/buffer.c
+++ b/src/crypto/bio/buffer.c
@@ -406,7 +406,7 @@
   return ret;
 
 malloc_error:
-  OPENSSL_PUT_ERROR(BIO, buffer_ctrl, ERR_R_MALLOC_FAILURE);
+  OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
   return 0;
 }
 
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 32361bf..2ed2def 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -142,7 +142,7 @@
       case BIO_CONN_S_BEFORE:
         p = c->param_hostname;
         if (p == NULL) {
-          OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_HOSTNAME_SPECIFIED);
+          OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
           goto exit_loop;
         }
         for (; *p != 0; p++) {
@@ -167,7 +167,7 @@
         }
 
         if (c->param_port == NULL) {
-          OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_PORT_SPECIFIED);
+          OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
           ERR_add_error_data(2, "host=", c->param_hostname);
           goto exit_loop;
         }
@@ -175,7 +175,7 @@
         if (!bio_ip_and_port_to_socket_and_addr(
                 &bio->num, &c->them, &c->them_length, c->param_hostname,
                 c->param_port)) {
-          OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_UNABLE_TO_CREATE_SOCKET);
+          OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
           ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
           goto exit_loop;
         }
@@ -185,7 +185,7 @@
 
         if (c->nbio) {
           if (!bio_socket_nbio(bio->num, 1)) {
-            OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_ERROR_SETTING_NBIO);
+            OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
             ERR_add_error_data(4, "host=", c->param_hostname, ":",
                                c->param_port);
             goto exit_loop;
@@ -197,7 +197,7 @@
                          sizeof(i));
         if (ret < 0) {
           OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
-          OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_KEEPALIVE);
+          OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
           ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
           goto exit_loop;
         }
@@ -211,7 +211,7 @@
             bio->retry_reason = BIO_RR_CONNECT;
           } else {
             OPENSSL_PUT_SYSTEM_ERROR(connect);
-            OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_CONNECT_ERROR);
+            OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
             ERR_add_error_data(4, "host=", c->param_hostname, ":",
                                c->param_port);
           }
@@ -232,7 +232,7 @@
           } else {
             BIO_clear_retry_flags(bio);
             OPENSSL_PUT_SYSTEM_ERROR(connect);
-            OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NBIO_CONNECT_ERROR);
+            OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
             ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
             ret = 0;
           }
@@ -464,7 +464,7 @@
       break;
     case BIO_CTRL_SET_CALLBACK: {
 #if 0 /* FIXME: Should this be used?  -- Richard Levitte */
-		OPENSSL_PUT_ERROR(BIO, XXX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
 		ret = -1;
 #else
       ret = 0;
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index 7f57aad..2d3ccfe 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -88,7 +88,7 @@
 #define BIO_FP_APPEND 0x08
 
 static FILE *open_file(const char *filename, const char *mode) {
-#if defined(_WIN32) && defined(CP_UTF8)
+#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
   int sz, len_0 = (int)strlen(filename) + 1;
   DWORD flags;
 
@@ -133,9 +133,9 @@
 
     ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
     if (errno == ENOENT) {
-      OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_NO_SUCH_FILE);
+      OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
     } else {
-      OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_SYS_LIB);
+      OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
     }
     return NULL;
   }
@@ -182,20 +182,19 @@
 }
 
 static int file_read(BIO *b, char *out, int outl) {
-  int ret = 0;
-
   if (!b->init) {
     return 0;
   }
 
-  ret = fread(out, 1, outl, (FILE *)b->ptr);
+  size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
   if (ret == 0 && ferror((FILE *)b->ptr)) {
     OPENSSL_PUT_SYSTEM_ERROR(fread);
-    OPENSSL_PUT_ERROR(BIO, file_read, ERR_R_SYS_LIB);
-    ret = -1;
+    OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
+    return -1;
   }
 
-  return ret;
+  /* fread reads at most |outl| bytes, so |ret| fits in an int. */
+  return (int)ret;
 }
 
 static int file_write(BIO *b, const char *in, int inl) {
@@ -253,7 +252,7 @@
       } else if (num & BIO_FP_READ) {
         BUF_strlcpy(p, "r", sizeof(p));
       } else {
-        OPENSSL_PUT_ERROR(BIO, file_ctrl, BIO_R_BAD_FOPEN_MODE);
+        OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
         ret = 0;
         break;
       }
@@ -261,7 +260,7 @@
       if (fp == NULL) {
         OPENSSL_PUT_SYSTEM_ERROR(fopen);
         ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
-        OPENSSL_PUT_ERROR(BIO, file_ctrl, ERR_R_SYS_LIB);
+        OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
         ret = 0;
         break;
       }
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index cc55950..6f78890 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -181,27 +181,25 @@
   BIO_clear_retry_flags(bio);
 
   if (!bio->init) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return 0;
   }
 
   b = bio->ptr;
 
   if (!b || !b->peer) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   peer_b = b->peer->ptr;
   if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   if (peer_b->zero_copy_read_lock) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
@@ -229,37 +227,32 @@
   assert(BIO_get_retry_flags(bio) == 0);
 
   if (!bio->init) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
-                      BIO_R_UNINITIALIZED);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return 0;
   }
 
   b = bio->ptr;
 
   if (!b || !b->peer) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   peer_b = b->peer->ptr;
   if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   if (!peer_b->zero_copy_read_lock) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
-                      BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
   max_available =
       bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
   if (bytes_read > max_available) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
-                      BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
@@ -318,35 +311,33 @@
   BIO_clear_retry_flags(bio);
 
   if (!bio->init) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return 0;
   }
 
   b = bio->ptr;
 
   if (!b || !b->buf || !b->peer) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
   peer_b = b->peer->ptr;
   if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   assert(b->buf != NULL);
 
   if (b->zero_copy_write_lock) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
   b->request = 0;
   if (b->closed) {
     /* Bio is already closed. */
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
     return 0;
   }
 
@@ -369,43 +360,38 @@
   uint8_t* dummy_write_buf;
 
   if (!bio->init) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
-                      BIO_R_UNINITIALIZED);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return 0;
   }
 
   b = bio->ptr;
 
   if (!b || !b->buf || !b->peer) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
   peer_b = b->peer->ptr;
   if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
-                      BIO_R_UNSUPPORTED_METHOD);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
   b->request = 0;
   if (b->closed) {
     /* BIO is already closed. */
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
     return 0;
   }
 
   if (!b->zero_copy_write_lock) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
-                      BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
   rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
 
   if (bytes_written > rest) {
-    OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
-                      BIO_R_INVALID_ARGUMENT);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
     return 0;
   }
 
@@ -525,7 +511,7 @@
   b->request = 0;
   if (b->closed) {
     /* we already closed */
-    OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
     return -1;
   }
 
@@ -590,7 +576,7 @@
   b2 = bio2->ptr;
 
   if (b1->peer != NULL || b2->peer != NULL) {
-    OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
+    OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
     return 0;
   }
 
@@ -605,7 +591,7 @@
       b1->buf_externally_allocated = 0;
       b1->buf = OPENSSL_malloc(b1->size);
       if (b1->buf == NULL) {
-        OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
         return 0;
       }
     } else {
@@ -624,7 +610,7 @@
       b2->buf_externally_allocated = 0;
       b2->buf = OPENSSL_malloc(b2->size);
       if (b2->buf == NULL) {
-        OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
         return 0;
       }
     } else {
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index f51b396..2f5ae4a 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -95,7 +95,7 @@
     out = OPENSSL_malloc(requested_len + 1);
     out_malloced = 1;
     if (out == NULL) {
-      OPENSSL_PUT_ERROR(BIO, BIO_printf, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
       return -1;
     }
     va_start(args, format);
diff --git a/src/crypto/bio/socket_helper.c b/src/crypto/bio/socket_helper.c
index b1cdd1a..01f635e 100644
--- a/src/crypto/bio/socket_helper.c
+++ b/src/crypto/bio/socket_helper.c
@@ -12,7 +12,8 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
 
-#define _POSIX_SOURCE
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
 
 #include <openssl/bio.h>
 #include <openssl/err.h>
@@ -50,7 +51,7 @@
 
   ret = getaddrinfo(hostname, port_str, &hint, &result);
   if (ret != 0) {
-    OPENSSL_PUT_ERROR(SYS, getaddrinfo, 0);
+    OPENSSL_PUT_ERROR(SYS, 0);
     ERR_add_error_data(1, gai_strerror(ret));
     return 0;
   }
diff --git a/src/crypto/bn/CMakeLists.txt b/src/crypto/bn/CMakeLists.txt
index 2e0cb45..232e40a 100644
--- a/src/crypto/bn/CMakeLists.txt
+++ b/src/crypto/bn/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 if (${ARCH} STREQUAL "x86_64")
   set(
@@ -39,6 +39,7 @@
   add.c
   asm/x86_64-gcc.c
   bn.c
+  bn_asn1.c
   cmp.c
   convert.c
   ctx.c
diff --git a/src/crypto/bn/add.c b/src/crypto/bn/add.c
index 1c6b2d7..a043d83 100644
--- a/src/crypto/bn/add.c
+++ b/src/crypto/bn/add.c
@@ -267,7 +267,7 @@
 
   if (dif < 0) /* hmm... should not be happening */
   {
-    OPENSSL_PUT_ERROR(BN, BN_usub, BN_R_ARG2_LT_ARG3);
+    OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
     return 0;
   }
 
diff --git a/src/crypto/bn/asm/armv4-mont.pl b/src/crypto/bn/asm/armv4-mont.pl
index 0f1b6a9..4206fd8 100644
--- a/src/crypto/bn/asm/armv4-mont.pl
+++ b/src/crypto/bn/asm/armv4-mont.pl
@@ -79,7 +79,7 @@
 $_num="$num,#15*4";	$_bpend=$_num;
 
 $code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 .code	32
diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c
index f32d6b0..b342749 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -69,7 +69,7 @@
   BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM));
 
   if (bn == NULL) {
-    OPENSSL_PUT_ERROR(BN, BN_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -279,26 +279,26 @@
   }
 }
 
-BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
+BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
   BN_ULONG *a;
 
-  if (words <= (unsigned) bn->dmax) {
+  if (words <= (size_t)bn->dmax) {
     return bn;
   }
 
   if (words > (INT_MAX / (4 * BN_BITS2))) {
-    OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_BIGNUM_TOO_LONG);
+    OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
     return NULL;
   }
 
   if (bn->flags & BN_FLG_STATIC_DATA) {
-    OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+    OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
     return NULL;
   }
 
   a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
   if (a == NULL) {
-    OPENSSL_PUT_ERROR(BN, bn_wexpand, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -306,12 +306,16 @@
 
   OPENSSL_free(bn->d);
   bn->d = a;
-  bn->dmax = words;
+  bn->dmax = (int)words;
 
   return bn;
 }
 
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits) {
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits) {
+  if (bits + BN_BITS2 - 1 < bits) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+    return NULL;
+  }
   return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2);
 }
 
diff --git a/src/crypto/bn/bn_asn1.c b/src/crypto/bn/bn_asn1.c
new file mode 100644
index 0000000..9d70ba8
--- /dev/null
+++ b/src/crypto/bn/bn_asn1.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/bn.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+
+int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
+  CBS child;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+      CBS_len(&child) == 0) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+    return 0;
+  }
+
+  if (CBS_data(&child)[0] & 0x80) {
+    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+    return 0;
+  }
+
+  /* INTEGERs must be minimal. */
+  if (CBS_data(&child)[0] == 0x00 &&
+      CBS_len(&child) > 1 &&
+      !(CBS_data(&child)[1] & 0x80)) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+    return 0;
+  }
+
+  return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
+  CBS child;
+  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+      CBS_len(&child) == 0) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+    return 0;
+  }
+
+  /* This function intentionally does not reject negative numbers or non-minimal
+   * encodings. Estonian IDs issued between September 2014 to September 2015 are
+   * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+   *
+   * TODO(davidben): Remove this code and callers in March 2016. */
+  return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
+  /* Negative numbers are unsupported. */
+  if (BN_is_negative(bn)) {
+    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+    return 0;
+  }
+
+  CBB child;
+  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
+    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 6a7d48c..47093a7 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -82,6 +82,7 @@
 #include <openssl/mem.h>
 
 #include "../crypto/test/scoped_types.h"
+#include "../crypto/test/test_util.h"
 
 
 // This program tests the BIGNUM implementation. It takes an optional -bc
@@ -117,11 +118,13 @@
 static bool test_small_prime(FILE *fp, BN_CTX *ctx);
 static bool test_mod_exp_mont5(FILE *fp, BN_CTX *ctx);
 static bool test_sqrt(FILE *fp, BN_CTX *ctx);
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx);
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx);
-static bool test_hex2bn(FILE *fp, BN_CTX *ctx);
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx);
+static bool test_bn2bin_padded(BN_CTX *ctx);
+static bool test_dec2bn(BN_CTX *ctx);
+static bool test_hex2bn(BN_CTX *ctx);
+static bool test_asc2bn(BN_CTX *ctx);
+static bool test_mpi();
 static bool test_rand();
+static bool test_asn1();
 
 static const uint8_t kSample[] =
     "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
@@ -311,35 +314,15 @@
   }
   flush_fp(bc_file.get());
 
-  message(bc_file.get(), "BN_bn2bin_padded");
-  if (!test_bn2bin_padded(bc_file.get(), ctx.get())) {
+  if (!test_bn2bin_padded(ctx.get()) ||
+      !test_dec2bn(ctx.get()) ||
+      !test_hex2bn(ctx.get()) ||
+      !test_asc2bn(ctx.get()) ||
+      !test_mpi() ||
+      !test_rand() ||
+      !test_asn1()) {
     return 1;
   }
-  flush_fp(bc_file.get());
-
-  message(bc_file.get(), "BN_dec2bn");
-  if (!test_dec2bn(bc_file.get(), ctx.get())) {
-    return 1;
-  }
-  flush_fp(bc_file.get());
-
-  message(bc_file.get(), "BN_hex2bn");
-  if (!test_hex2bn(bc_file.get(), ctx.get())) {
-    return 1;
-  }
-  flush_fp(bc_file.get());
-
-  message(bc_file.get(), "BN_asc2bn");
-  if (!test_asc2bn(bc_file.get(), ctx.get())) {
-    return 1;
-  }
-  flush_fp(bc_file.get());
-
-  message(bc_file.get(), "BN_rand");
-  if (!test_rand()) {
-    return 1;
-  }
-  flush_fp(bc_file.get());
 
   printf("PASS\n");
   return 0;
@@ -440,6 +423,16 @@
     return false;
   }
 
+  if (!BN_one(a.get())) {
+    return false;
+  }
+  BN_zero(b.get());
+  if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
+    fprintf(stderr, "Division by zero succeeded!\n");
+    return false;
+  }
+  ERR_clear_error();
+
   for (int i = 0; i < num0 + num1; i++) {
     if (i < num1) {
       if (!BN_rand(a.get(), 400, 0, 0) ||
@@ -837,18 +830,17 @@
   }
 
   for (int i = 0; i < num0; i++) {
-    BN_ULONG s;
     do {
       if (!BN_rand(a.get(), 512, -1, 0) ||
           !BN_rand(b.get(), BN_BITS2, -1, 0)) {
         return false;
       }
-      s = b->d[0];
-    } while (!s);
+    } while (BN_is_zero(b.get()));
 
     if (!BN_copy(b.get(), a.get())) {
       return false;
     }
+    BN_ULONG s = b->d[0];
     BN_ULONG r = BN_div_word(b.get(), s);
     if (r == (BN_ULONG)-1) {
       return false;
@@ -891,8 +883,27 @@
   ScopedBIGNUM B(BN_new());
   ScopedBIGNUM n(BN_new());
   ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
-  if (!a || !b || !c || !d || !A || !B || !n || !mont ||
-      !BN_rand(a.get(), 100, 0, 0) ||
+  if (!a || !b || !c || !d || !A || !B || !n || !mont) {
+    return false;
+  }
+
+  BN_zero(n.get());
+  if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+    fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
+    return false;
+  }
+  ERR_clear_error();
+
+  if (!BN_set_word(n.get(), 16)) {
+    return false;
+  }
+  if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+    fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
+    return false;
+  }
+  ERR_clear_error();
+
+  if (!BN_rand(a.get(), 100, 0, 0) ||
       !BN_rand(b.get(), 100, 0, 0)) {
     return false;
   }
@@ -932,6 +943,7 @@
       return false;
     }
   }
+
   return true;
 }
 
@@ -985,6 +997,16 @@
     return false;
   }
 
+  if (!BN_one(a.get()) || !BN_one(b.get())) {
+    return false;
+  }
+  BN_zero(c.get());
+  if (BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
+    fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
+    return false;
+  }
+  ERR_clear_error();
+
   for (int j = 0; j < 3; j++) {
     if (!BN_rand(c.get(), 1024, 0, 0)) {
       return false;
@@ -1039,8 +1061,21 @@
   ScopedBIGNUM c(BN_new());
   ScopedBIGNUM d(BN_new());
   ScopedBIGNUM e(BN_new());
-  if (!a || !b || !c || !d || !e ||
-      !BN_rand(c.get(), 30, 0, 1)) {  // must be odd for montgomery
+  if (!a || !b || !c || !d || !e) {
+    return false;
+  }
+
+  if (!BN_one(a.get()) || !BN_one(b.get())) {
+    return false;
+  }
+  BN_zero(c.get());
+  if (BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
+    fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
+    return 0;
+  }
+  ERR_clear_error();
+
+  if (!BN_rand(c.get(), 30, 0, 1)) {  // must be odd for montgomery
     return false;
   }
   for (int i = 0; i < num2; i++) {
@@ -1079,8 +1114,32 @@
   ScopedBIGNUM c(BN_new());
   ScopedBIGNUM d(BN_new());
   ScopedBIGNUM e(BN_new());
-  if (!a || !b || !c || !d || !e ||
-      !BN_rand(c.get(), 30, 0, 1)) {  // must be odd for montgomery
+  if (!a || !b || !c || !d || !e) {
+    return false;
+  }
+
+  if (!BN_one(a.get()) || !BN_one(b.get())) {
+    return false;
+  }
+  BN_zero(c.get());
+  if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+                                nullptr)) {
+    fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus succeeded!\n");
+    return 0;
+  }
+  ERR_clear_error();
+
+  if (!BN_set_word(c.get(), 16)) {
+    return false;
+  }
+  if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+                                nullptr)) {
+    fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus succeeded!\n");
+    return 0;
+  }
+  ERR_clear_error();
+
+  if (!BN_rand(c.get(), 30, 0, 1)) {  // must be odd for montgomery
     return false;
   }
   for (int i = 0; i < num2; i++) {
@@ -1208,8 +1267,9 @@
     if (!BN_one(e.get())) {
       return false;
     }
-    for (; !BN_is_zero(b.get()); BN_sub(b.get(), b.get(), BN_value_one())) {
-      if (!BN_mul(e.get(), e.get(), a.get(), ctx)) {
+    while (!BN_is_zero(b.get())) {
+      if (!BN_mul(e.get(), e.get(), a.get(), ctx) ||
+          !BN_sub(b.get(), b.get(), BN_value_one())) {
         return false;
       }
     }
@@ -1371,7 +1431,7 @@
   return true;
 }
 
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx) {
+static bool test_bn2bin_padded(BN_CTX *ctx) {
   uint8_t zeros[256], out[256], reference[128];
 
   memset(zeros, 0, sizeof(zeros));
@@ -1448,7 +1508,7 @@
   return ret;
 }
 
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_dec2bn(BN_CTX *ctx) {
   ScopedBIGNUM bn;
   int ret = DecimalToBIGNUM(&bn, "0");
   if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1490,7 +1550,7 @@
   return ret;
 }
 
-static bool test_hex2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_hex2bn(BN_CTX *ctx) {
   ScopedBIGNUM bn;
   int ret = HexToBIGNUM(&bn, "0");
   if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1533,7 +1593,7 @@
   return ScopedBIGNUM(raw);
 }
 
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_asc2bn(BN_CTX *ctx) {
   ScopedBIGNUM bn = ASCIIToBIGNUM("0");
   if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
     fprintf(stderr, "BN_asc2bn gave a bad result.\n");
@@ -1585,6 +1645,63 @@
   return true;
 }
 
+struct MPITest {
+  const char *base10;
+  const char *mpi;
+  size_t mpi_len;
+};
+
+static const MPITest kMPITests[] = {
+  { "0", "\x00\x00\x00\x00", 4 },
+  { "1", "\x00\x00\x00\x01\x01", 5 },
+  { "-1", "\x00\x00\x00\x01\x81", 5 },
+  { "128", "\x00\x00\x00\x02\x00\x80", 6 },
+  { "256", "\x00\x00\x00\x02\x01\x00", 6 },
+  { "-256", "\x00\x00\x00\x02\x81\x00", 6 },
+};
+
+static bool test_mpi() {
+  uint8_t scratch[8];
+
+  for (size_t i = 0; i < sizeof(kMPITests) / sizeof(kMPITests[0]); i++) {
+    const MPITest &test = kMPITests[i];
+    ScopedBIGNUM bn(ASCIIToBIGNUM(test.base10));
+    const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
+    if (mpi_len > sizeof(scratch)) {
+      fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
+              (unsigned)i);
+      return false;
+    }
+
+    const size_t mpi_len2 = BN_bn2mpi(bn.get(), scratch);
+    if (mpi_len != mpi_len2) {
+      fprintf(stderr, "MPI test #%u: length changes.\n", (unsigned)i);
+      return false;
+    }
+
+    if (mpi_len != test.mpi_len ||
+        memcmp(test.mpi, scratch, mpi_len) != 0) {
+      fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
+      hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
+      hexdump(stderr, "Got:      ", scratch, mpi_len);
+      return false;
+    }
+
+    ScopedBIGNUM bn2(BN_mpi2bn(scratch, mpi_len, NULL));
+    if (bn2.get() == nullptr) {
+      fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
+      return false;
+    }
+
+    if (BN_cmp(bn.get(), bn2.get()) != 0) {
+      fprintf(stderr, "MPI test #%u: wrong result\n", (unsigned)i);
+      return false;
+    }
+  }
+
+  return true;
+}
+
 static bool test_rand() {
   ScopedBIGNUM bn(BN_new());
   if (!bn) {
@@ -1628,3 +1745,170 @@
 
   return true;
 }
+
+struct ASN1Test {
+  const char *value_ascii;
+  const char *der;
+  size_t der_len;
+};
+
+static const ASN1Test kASN1Tests[] = {
+    {"0", "\x02\x01\x00", 3},
+    {"1", "\x02\x01\x01", 3},
+    {"127", "\x02\x01\x7f", 3},
+    {"128", "\x02\x02\x00\x80", 4},
+    {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
+    {"0x0102030405060708",
+     "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
+    {"0xffffffffffffffff",
+      "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
+};
+
+struct ASN1InvalidTest {
+  const char *der;
+  size_t der_len;
+};
+
+static const ASN1InvalidTest kASN1InvalidTests[] = {
+    // Bad tag.
+    {"\x03\x01\x00", 3},
+    // Empty contents.
+    {"\x02\x00", 2},
+};
+
+// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
+// should interpret them.
+static const ASN1Test kASN1BuggyTests[] = {
+    // Negative numbers.
+    {"128", "\x02\x01\x80", 3},
+    {"255", "\x02\x01\xff", 3},
+    // Unnecessary leading zeros.
+    {"1", "\x02\x02\x00\x01", 4},
+};
+
+static bool test_asn1() {
+  for (const ASN1Test &test : kASN1Tests) {
+    ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
+    if (!bn) {
+      return false;
+    }
+
+    // Test that the input is correctly parsed.
+    ScopedBIGNUM bn2(BN_new());
+    if (!bn2) {
+      return false;
+    }
+    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) {
+      fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+      return false;
+    }
+    if (BN_cmp(bn.get(), bn2.get()) != 0) {
+      fprintf(stderr, "Bad parse.\n");
+      return false;
+    }
+
+    // Test the value serializes correctly.
+    CBB cbb;
+    uint8_t *der;
+    size_t der_len;
+    CBB_zero(&cbb);
+    if (!CBB_init(&cbb, 0) ||
+        !BN_bn2cbb(&cbb, bn.get()) ||
+        !CBB_finish(&cbb, &der, &der_len)) {
+      CBB_cleanup(&cbb);
+      return false;
+    }
+    ScopedOpenSSLBytes delete_der(der);
+    if (der_len != test.der_len ||
+        memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
+      fprintf(stderr, "Bad serialization.\n");
+      return false;
+    }
+
+    // |BN_cbs2unsigned_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) {
+      fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+      return false;
+    }
+    if (BN_cmp(bn.get(), bn2.get()) != 0) {
+      fprintf(stderr, "Bad parse.\n");
+      return false;
+    }
+  }
+
+  for (const ASN1InvalidTest &test : kASN1InvalidTests) {
+    ScopedBIGNUM bn(BN_new());
+    if (!bn) {
+      return false;
+    }
+    CBS cbs;
+    CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+    if (BN_cbs2unsigned(&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|.
+    CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+    if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
+      fprintf(stderr, "Parsed invalid input.\n");
+      return false;
+    }
+    ERR_clear_error();
+  }
+
+  for (const ASN1Test &test : kASN1BuggyTests) {
+    // These broken encodings are rejected by |BN_cbs2unsigned|.
+    ScopedBIGNUM bn(BN_new());
+    if (!bn) {
+      return false;
+    }
+
+    CBS cbs;
+    CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+    if (BN_cbs2unsigned(&cbs, bn.get())) {
+      fprintf(stderr, "Parsed invalid input.\n");
+      return false;
+    }
+    ERR_clear_error();
+
+    // However |BN_cbs2unsigned_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) {
+      fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
+      return false;
+    }
+
+    if (BN_cmp(bn.get(), bn2.get()) != 0) {
+      fprintf(stderr, "\"Bad\" parse.\n");
+      return false;
+    }
+  }
+
+  // Serializing negative numbers is not supported.
+  ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
+  if (!bn) {
+    return false;
+  }
+  CBB cbb;
+  CBB_zero(&cbb);
+  if (!CBB_init(&cbb, 0) ||
+      BN_bn2cbb(&cbb, bn.get())) {
+    fprintf(stderr, "Serialized negative number.\n");
+    CBB_cleanup(&cbb);
+    return false;
+  }
+  CBB_cleanup(&cbb);
+
+  return true;
+}
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 531b661..0122709 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -56,7 +56,9 @@
 
 #include <openssl/bn.h>
 
+#include <assert.h>
 #include <ctype.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -67,7 +69,8 @@
 #include "internal.h"
 
 BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
-  unsigned num_words, m;
+  size_t num_words;
+  unsigned m;
   BN_ULONG word = 0;
   BIGNUM *bn = NULL;
 
@@ -93,7 +96,10 @@
     return NULL;
   }
 
-  ret->top = num_words;
+  /* |bn_wexpand| must check bounds on |num_words| to write it into
+   * |ret->dmax|. */
+  assert(num_words <= INT_MAX);
+  ret->top = (int)num_words;
   ret->neg = 0;
 
   while (len--) {
@@ -198,7 +204,7 @@
 
   buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
   if (buf == NULL) {
-    OPENSSL_PUT_ERROR(BN, BN_bn2hex, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -227,47 +233,59 @@
   return buf;
 }
 
-/* decode_hex decodes |i| bytes of hex data from |in| and updates |bn|. */
-static void decode_hex(BIGNUM *bn, const char *in, int i) {
-  int h, m, j, k, c;
-  BN_ULONG l=0;
-
-  j = i; /* least significant 'hex' */
-  h = 0;
-  while (j > 0) {
-    m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
-    l = 0;
-    for (;;) {
-      c = in[j - m];
-      if ((c >= '0') && (c <= '9')) {
-        k = c - '0';
-      } else if ((c >= 'a') && (c <= 'f')) {
-        k = c - 'a' + 10;
-      } else if ((c >= 'A') && (c <= 'F')) {
-        k = c - 'A' + 10;
-      } else {
-        k = 0; /* paranoia */
-      }
-
-      l = (l << 4) | k;
-
-      if (--m <= 0) {
-        bn->d[h++] = l;
-        break;
-      }
-    }
-
-    j -= (BN_BYTES * 2);
+/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
+static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
+  if (in_len > INT_MAX/4) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+    return 0;
+  }
+  /* |in_len| is the number of hex digits. */
+  if (bn_expand(bn, in_len * 4) == NULL) {
+    return 0;
   }
 
-  bn->top = h;
+  int i = 0;
+  while (in_len > 0) {
+    /* Decode one |BN_ULONG| at a time. */
+    int todo = BN_BYTES * 2;
+    if (todo > in_len) {
+      todo = in_len;
+    }
+
+    BN_ULONG word = 0;
+    int j;
+    for (j = todo; j > 0; j--) {
+      char c = in[in_len - j];
+
+      BN_ULONG hex;
+      if (c >= '0' && c <= '9') {
+        hex = c - '0';
+      } else if (c >= 'a' && c <= 'f') {
+        hex = c - 'a' + 10;
+      } else if (c >= 'A' && c <= 'F') {
+        hex = c - 'A' + 10;
+      } else {
+        hex = 0;
+        /* This shouldn't happen. The caller checks |isxdigit|. */
+        assert(0);
+      }
+      word = (word << 4) | hex;
+    }
+
+    bn->d[i++] = word;
+    in_len -= todo;
+  }
+  assert(i <= bn->dmax);
+  bn->top = i;
+  return 1;
 }
 
 /* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */
-static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
+static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
   int i, j;
   BN_ULONG l = 0;
 
+  /* Decode |BN_DEC_NUM| digits at a time. */
   j = BN_DEC_NUM - (in_len % BN_DEC_NUM);
   if (j == BN_DEC_NUM) {
     j = 0;
@@ -277,15 +295,18 @@
     l *= 10;
     l += in[i] - '0';
     if (++j == BN_DEC_NUM) {
-      BN_mul_word(bn, BN_DEC_CONV);
-      BN_add_word(bn, l);
+      if (!BN_mul_word(bn, BN_DEC_CONV) ||
+          !BN_add_word(bn, l)) {
+        return 0;
+      }
       l = 0;
       j = 0;
     }
   }
+  return 1;
 }
 
-typedef void (*decode_func) (BIGNUM *bn, const char *in, int i);
+typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
 typedef int (*char_test_func) (int c);
 
 static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
@@ -302,7 +323,7 @@
     in++;
   }
 
-  for (i = 0; want_char((unsigned char)in[i]); i++) {}
+  for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
 
   num = i + neg;
   if (outp == NULL) {
@@ -320,13 +341,10 @@
     BN_zero(ret);
   }
 
-  /* i is the number of hex digests; */
-  if (bn_expand(ret, i * 4) == NULL) {
+  if (!decode(ret, in, i)) {
     goto err;
   }
 
-  decode(ret, in, i);
-
   bn_correct_top(ret);
   if (!BN_is_zero(ret)) {
     ret->neg = neg;
@@ -365,7 +383,7 @@
       (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
   buf = (char *)OPENSSL_malloc(num + 3);
   if ((buf == NULL) || (bn_data == NULL)) {
-    OPENSSL_PUT_ERROR(BN, BN_bn2dec, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     goto err;
   }
   t = BN_dup(a);
@@ -499,3 +517,81 @@
       return BN_MASK2;
   }
 }
+
+size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
+  const size_t bits = BN_num_bits(in);
+  const size_t bytes = (bits + 7) / 8;
+  /* If the number of bits is a multiple of 8, i.e. if the MSB is set,
+   * prefix with a zero byte. */
+  int extend = 0;
+  if (bytes != 0 && (bits & 0x07) == 0) {
+    extend = 1;
+  }
+
+  const size_t len = bytes + extend;
+  if (len < bytes ||
+      4 + len < len ||
+      (len & 0xffffffff) != len) {
+    /* If we cannot represent the number then we emit zero as the interface
+     * doesn't allow an error to be signalled. */
+    if (out) {
+      memset(out, 0, 4);
+    }
+    return 4;
+  }
+
+  if (out == NULL) {
+    return 4 + len;
+  }
+
+  out[0] = len >> 24;
+  out[1] = len >> 16;
+  out[2] = len >> 8;
+  out[3] = len;
+  if (extend) {
+    out[4] = 0;
+  }
+  BN_bn2bin(in, out + 4 + extend);
+  if (in->neg && len > 0) {
+    out[4] |= 0x80;
+  }
+  return len + 4;
+}
+
+BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
+  if (len < 4) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+    return NULL;
+  }
+  const size_t in_len = ((size_t)in[0] << 24) |
+                        ((size_t)in[1] << 16) |
+                        ((size_t)in[2] << 8) |
+                        ((size_t)in[3]);
+  if (in_len != len - 4) {
+    OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+    return NULL;
+  }
+
+  if (out == NULL) {
+    out = BN_new();
+  }
+  if (out == NULL) {
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+
+  if (in_len == 0) {
+    BN_zero(out);
+    return out;
+  }
+
+  in += 4;
+  if (BN_bin2bn(in, in_len, out) == NULL) {
+    return NULL;
+  }
+  out->neg = ((*in) & 0x80) != 0;
+  if (out->neg) {
+    BN_clear_bit(out, BN_num_bits(out) - 1);
+  }
+  return out;
+}
diff --git a/src/crypto/bn/ctx.c b/src/crypto/bn/ctx.c
index 0578376..48d9adf 100644
--- a/src/crypto/bn/ctx.c
+++ b/src/crypto/bn/ctx.c
@@ -124,7 +124,7 @@
 BN_CTX *BN_CTX_new(void) {
   BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
   if (!ret) {
-    OPENSSL_PUT_ERROR(BN, BN_CTX_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -153,7 +153,7 @@
     ctx->err_stack++;
   } else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
     /* (Try to) get a new frame pointer */
-    OPENSSL_PUT_ERROR(BN, BN_CTX_start, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+    OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
     ctx->err_stack++;
   }
 }
@@ -169,7 +169,7 @@
     /* Setting too_many prevents repeated "get" attempts from
      * cluttering the error stack. */
     ctx->too_many = 1;
-    OPENSSL_PUT_ERROR(BN, BN_CTX_get, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+    OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
     return NULL;
   }
 
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index 3588ea1..779dda2 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -125,7 +125,7 @@
    * so don't just rely on bn_check_top() here */
   if ((num->top > 0 && num->d[num->top - 1] == 0) ||
       (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
-    OPENSSL_PUT_ERROR(BN, BN_div, BN_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
     return 0;
   }
 
@@ -135,7 +135,7 @@
   }
 
   if (BN_is_zero(divisor)) {
-    OPENSSL_PUT_ERROR(BN, BN_div, BN_R_DIV_BY_ZERO);
+    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
     return 0;
   }
 
@@ -511,7 +511,7 @@
     /* max_shift >= 0 */
 
     if (max_shift < 0) {
-      OPENSSL_PUT_ERROR(BN, BN_mod_lshift_quick, BN_R_INPUT_NOT_REDUCED);
+      OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
       return 0;
     }
 
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index d3063c9..6c5e11b 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -131,7 +131,7 @@
 
   if ((p->flags & BN_FLG_CONSTTIME) != 0) {
     /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-    OPENSSL_PUT_ERROR(BN, BN_exp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
 
@@ -173,8 +173,8 @@
     }
   }
 
-  if (r != rr) {
-    BN_copy(r, rr);
+  if (r != rr && !BN_copy(r, rr)) {
+    goto err;
   }
   ret = 1;
 
@@ -333,7 +333,7 @@
   j = 0;
   while (BN_ucmp(r, &(recp->N)) >= 0) {
     if (j++ > 2) {
-      OPENSSL_PUT_ERROR(BN, BN_div_recp, BN_R_BAD_RECIPROCAL);
+      OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL);
       goto err;
     }
     if (!BN_usub(r, r, &(recp->N))) {
@@ -427,7 +427,7 @@
 
   if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
     /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-    OPENSSL_PUT_ERROR(BN, mod_exp_recp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
 
@@ -616,7 +616,7 @@
   }
 
   if (!BN_is_odd(m)) {
-    OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+    OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
     return 0;
   }
   bits = BN_num_bits(p);
@@ -862,13 +862,13 @@
   unsigned char *powerbuf = NULL;
   BIGNUM tmp, am;
 
-  top = m->top;
-
-  if (!(m->d[0] & 1)) {
-    OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_consttime,
-                      BN_R_CALLED_WITH_EVEN_MODULUS);
+  if (!BN_is_odd(m)) {
+    OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
     return 0;
   }
+
+  top = m->top;
+
   bits = BN_num_bits(p);
   if (bits == 0) {
     ret = BN_one(rr);
@@ -926,7 +926,6 @@
     }
   }
 #endif
-  (void)0;
 
   /* Allocate a buffer large enough to hold all of the pre-computed
    * powers of am, am itself and tmp.
@@ -1223,13 +1222,12 @@
 
   if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
     /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-    OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word,
-        ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
 
   if (!BN_is_odd(m)) {
-    OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word, BN_R_CALLED_WITH_EVEN_MODULUS);
+    OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
     return 0;
   }
 
@@ -1372,7 +1370,7 @@
   BN_MONT_CTX *mont = NULL;
 
   if (!(m->d[0] & 1)) {
-    OPENSSL_PUT_ERROR(BN, BN_mod_exp2_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+    OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
     return 0;
   }
   bits1 = BN_num_bits(p1);
diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c
index 3132c29..e106149 100644
--- a/src/crypto/bn/gcd.c
+++ b/src/crypto/bn/gcd.c
@@ -223,20 +223,23 @@
 }
 
 /* solves ax == 1 (mod n) */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
-                                        const BIGNUM *n, BN_CTX *ctx);
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+                                        const BIGNUM *a, const BIGNUM *n,
+                                        BN_CTX *ctx);
 
-BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
-                       BN_CTX *ctx) {
+BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
+                          const BIGNUM *n, BN_CTX *ctx) {
   BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
   BIGNUM *ret = NULL;
   int sign;
 
   if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
       (n->flags & BN_FLG_CONSTTIME) != 0) {
-    return BN_mod_inverse_no_branch(out, a, n, ctx);
+    return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
   }
 
+  *out_no_inverse = 0;
+
   BN_CTX_start(ctx);
   A = BN_CTX_get(ctx);
   B = BN_CTX_get(ctx);
@@ -522,7 +525,8 @@
       }
     }
   } else {
-    OPENSSL_PUT_ERROR(BN, BN_mod_inverse, BN_R_NO_INVERSE);
+    *out_no_inverse = 1;
+    OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
     goto err;
   }
   ret = R;
@@ -535,16 +539,25 @@
   return ret;
 }
 
+BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
+                       BN_CTX *ctx) {
+  int no_inverse;
+  return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
+}
+
 /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
  * It does not contain branches that may leak sensitive information. */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
-                                        const BIGNUM *n, BN_CTX *ctx) {
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+                                        const BIGNUM *a, const BIGNUM *n,
+                                        BN_CTX *ctx) {
   BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
   BIGNUM local_A, local_B;
   BIGNUM *pA, *pB;
   BIGNUM *ret = NULL;
   int sign;
 
+  *out_no_inverse = 0;
+
   BN_CTX_start(ctx);
   A = BN_CTX_get(ctx);
   B = BN_CTX_get(ctx);
@@ -682,7 +695,8 @@
       }
     }
   } else {
-    OPENSSL_PUT_ERROR(BN, BN_mod_inverse_no_branch, BN_R_NO_INVERSE);
+    *out_no_inverse = 1;
+    OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
     goto err;
   }
   ret = R;
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 2674b3c..0d0eb44 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -136,9 +136,9 @@
 extern "C" {
 #endif
 
-/* bn_expand acts the same as |BN_wexpand|, but takes a number of bits rather
+/* bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather
  * than a number of words. */
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
 
 #if defined(OPENSSL_64_BIT)
 
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index 152cf2d..c6c9c88 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -110,6 +110,7 @@
 
 #include <string.h>
 
+#include <openssl/err.h>
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
@@ -176,6 +177,11 @@
   BIGNUM tmod;
   BN_ULONG buf[2];
 
+  if (BN_is_zero(mod)) {
+    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
+    return 0;
+  }
+
   BN_CTX_start(ctx);
   Ri = BN_CTX_get(ctx);
   if (Ri == NULL) {
diff --git a/src/crypto/bn/mul.c b/src/crypto/bn/mul.c
index a17d766..029a59e 100644
--- a/src/crypto/bn/mul.c
+++ b/src/crypto/bn/mul.c
@@ -666,8 +666,8 @@
 
 end:
   bn_correct_top(rr);
-  if (r != rr) {
-    BN_copy(r, rr);
+  if (r != rr && !BN_copy(r, rr)) {
+    goto err;
   }
   ret = 1;
 
@@ -877,8 +877,8 @@
     rr->top = max;
   }
 
-  if (rr != r) {
-    BN_copy(r, rr);
+  if (rr != r && !BN_copy(r, rr)) {
+    goto err;
   }
   ret = 1;
 
diff --git a/src/crypto/bn/prime.c b/src/crypto/bn/prime.c
index cf3afcf..bbb8fe0 100644
--- a/src/crypto/bn/prime.c
+++ b/src/crypto/bn/prime.c
@@ -362,11 +362,11 @@
 
   if (bits < 2) {
     /* There are no prime numbers this small. */
-    OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
     return 0;
   } else if (bits == 2 && safe) {
     /* The smallest safe prime (7) is three bits. */
-    OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
     return 0;
   }
 
@@ -515,11 +515,10 @@
 
   /* A := abs(a) */
   if (a->neg) {
-    BIGNUM *t;
-    if ((t = BN_CTX_get(ctx)) == NULL) {
+    BIGNUM *t = BN_CTX_get(ctx);
+    if (t == NULL || !BN_copy(t, a)) {
       goto err;
     }
-    BN_copy(t, a);
     t->neg = 0;
     A = t;
   } else {
diff --git a/src/crypto/bn/random.c b/src/crypto/bn/random.c
index 549ac48..3116e54 100644
--- a/src/crypto/bn/random.c
+++ b/src/crypto/bn/random.c
@@ -134,7 +134,7 @@
 
   buf = OPENSSL_malloc(bytes);
   if (buf == NULL) {
-    OPENSSL_PUT_ERROR(BN, BN_rand, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
@@ -186,7 +186,7 @@
   unsigned count = 100;
 
   if (range->neg || BN_is_zero(range)) {
-    OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_INVALID_RANGE);
+    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
     return 0;
   }
 
@@ -219,7 +219,7 @@
       }
 
       if (!--count) {
-        OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+        OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
         return 0;
       }
     } while (BN_cmp(r, range) >= 0);
@@ -231,7 +231,7 @@
       }
 
       if (!--count) {
-        OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+        OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
         return 0;
       }
     } while (BN_cmp(r, range) >= 0);
@@ -264,13 +264,13 @@
   }
 
   if (BN_is_zero(range)) {
-    OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_DIV_BY_ZERO);
+    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
     goto err;
   }
 
   k_bytes = OPENSSL_malloc(num_k_bytes);
   if (!k_bytes) {
-    OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
@@ -281,7 +281,7 @@
     /* No reasonable DSA or ECDSA key should have a private key
      * this large and we don't handle this case in order to avoid
      * leaking the length of the private key. */
-    OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_PRIVATE_KEY_TOO_LARGE);
+    OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
     goto err;
   }
   memcpy(private_bytes, priv->d, todo);
diff --git a/src/crypto/bn/rsaz_exp.h b/src/crypto/bn/rsaz_exp.h
index 0bb6b0c..c752b45 100644
--- a/src/crypto/bn/rsaz_exp.h
+++ b/src/crypto/bn/rsaz_exp.h
@@ -1,32 +1,44 @@
-/******************************************************************************
-* Copyright(c) 2012, Intel Corp.                                             
-* Developers and authors:                                                    
-* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   
-* (1) Intel Corporation, Israel Development Center, Haifa, Israel                               
-* (2) University of Haifa, Israel                                              
+/*****************************************************************************
+*                                                                            *
+*  Copyright (c) 2012, Intel Corporation                                     *
+*                                                                            *
+*  All rights reserved.                                                      *
+*                                                                            *
+*  Redistribution and use in source and binary forms, with or without        *
+*  modification, are permitted provided that the following conditions are    *
+*  met:                                                                      *
+*                                                                            *
+*  *  Redistributions of source code must retain the above copyright         *
+*     notice, this list of conditions and the following disclaimer.          *
+*                                                                            *
+*  *  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.                                                          *
+*                                                                            *
+*  *  Neither the name of the Intel Corporation nor the names of its         *
+*     contributors may be used to endorse or promote products derived from   *
+*     this software without specific prior written permission.               *
+*                                                                            *
+*                                                                            *
+*  THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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.              *
+*                                                                            *
 ******************************************************************************
-* LICENSE:                                                                
-* This submission to OpenSSL is to be made available under the OpenSSL  
-* license, and only to the OpenSSL project, in order to allow integration    
-* into the publicly distributed code. 
-* The use of this code, or portions of this code, or concepts embedded in
-* this code, or modification of this code and/or algorithm(s) in it, or the
-* use of this code for any other purpose than stated above, requires special
-* licensing.                                                                  
-******************************************************************************
-* DISCLAIMER:                                                                
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS AND THE COPYRIGHT OWNERS     
-* ``AS IS''. 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 CONTRIBUTORS OR THE COPYRIGHT
-* OWNERS 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.                                                
-******************************************************************************/
+* Developers and authors:                                                    *
+* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel            *
+* (2) University of Haifa, Israel                                            *
+*****************************************************************************/
 
 #ifndef RSAZ_EXP_H
 #define RSAZ_EXP_H
diff --git a/src/crypto/bn/shift.c b/src/crypto/bn/shift.c
index f143996..defec92 100644
--- a/src/crypto/bn/shift.c
+++ b/src/crypto/bn/shift.c
@@ -69,7 +69,7 @@
   BN_ULONG l;
 
   if (n < 0) {
-    OPENSSL_PUT_ERROR(BN, BN_lshift, BN_R_NEGATIVE_NUMBER);
+    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
     return 0;
   }
 
@@ -138,7 +138,7 @@
   BN_ULONG l, tmp;
 
   if (n < 0) {
-    OPENSSL_PUT_ERROR(BN, BN_rshift, BN_R_NEGATIVE_NUMBER);
+    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
     return 0;
   }
 
diff --git a/src/crypto/bn/sqrt.c b/src/crypto/bn/sqrt.c
index e71a818..2ed66c2 100644
--- a/src/crypto/bn/sqrt.c
+++ b/src/crypto/bn/sqrt.c
@@ -86,7 +86,7 @@
       return ret;
     }
 
-    OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
     return (NULL);
   }
 
@@ -260,7 +260,7 @@
     }
     if (r == 0) {
       /* m divides p */
-      OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+      OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
       goto end;
     }
   } while (r == 1 && ++i < 82);
@@ -271,7 +271,7 @@
      * Even if  p  is not prime, we should have found some  y
      * such that r == -1.
      */
-    OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_TOO_MANY_ITERATIONS);
+    OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
     goto end;
   }
 
@@ -286,7 +286,7 @@
     goto end;
   }
   if (BN_is_one(y)) {
-    OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
     goto end;
   }
 
@@ -377,7 +377,7 @@
     while (!BN_is_one(t)) {
       i++;
       if (i == e) {
-        OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+        OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
         goto end;
       }
       if (!BN_mod_mul(t, t, t, p, ctx)) {
@@ -413,7 +413,7 @@
     }
 
     if (!err && 0 != BN_cmp(x, A)) {
-      OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+      OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
       err = 1;
     }
   }
@@ -434,7 +434,7 @@
   int ok = 0, last_delta_valid = 0;
 
   if (in->neg) {
-    OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NEGATIVE_NUMBER);
+    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
     return 0;
   }
   if (BN_is_zero(in)) {
@@ -452,7 +452,7 @@
   last_delta = BN_CTX_get(ctx);
   delta = BN_CTX_get(ctx);
   if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
-    OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
@@ -470,7 +470,7 @@
         !BN_sqr(tmp, estimate, ctx) ||
         /* |delta| = |in| - |tmp| */
         !BN_sub(delta, in, tmp)) {
-      OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_BN_LIB);
+      OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
       goto err;
     }
 
@@ -490,15 +490,15 @@
   }
 
   if (BN_cmp(tmp, in) != 0) {
-    OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NOT_A_SQUARE);
+    OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
     goto err;
   }
 
   ok = 1;
 
 err:
-  if (ok && out_sqrt == in) {
-    BN_copy(out_sqrt, estimate);
+  if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
+    ok = 0;
   }
   BN_CTX_end(ctx);
   return ok;
diff --git a/src/crypto/buf/CMakeLists.txt b/src/crypto/buf/CMakeLists.txt
index 19edf7d..63f1025 100644
--- a/src/crypto/buf/CMakeLists.txt
+++ b/src/crypto/buf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   buf
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index 5769e77..13b5ceb 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -67,7 +67,7 @@
 
   ret = OPENSSL_malloc(sizeof(BUF_MEM));
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(BUF, BUF_MEM_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -105,14 +105,14 @@
   n = len + 3;
   if (n < len) {
     /* overflow */
-    OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return 0;
   }
   n = n / 3;
   alloc_size = n * 4;
   if (alloc_size / 4 != n) {
     /* overflow */
-    OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return 0;
   }
 
@@ -127,7 +127,7 @@
   }
 
   if (new_buf == NULL) {
-    OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     len = 0;
   } else {
     buf->data = new_buf;
@@ -180,12 +180,12 @@
   alloc_size = size + 1;
   if (alloc_size < size) {
     /* overflow */
-    OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
   ret = OPENSSL_malloc(alloc_size);
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -226,7 +226,7 @@
 
   ret = OPENSSL_malloc(dst_size);
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(BUF, BUF_memdup, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index cbbacf2..3462aee 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   bytestring
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 66e9c1e..e987e1b 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -109,7 +109,7 @@
   static const uint8_t kData2[] = {0x30, 3, 1, 2};
   static const uint8_t kData3[] = {0x30, 0x80};
   static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
-  static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
+  static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80};
   static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1};
   static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1};
   static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1};
@@ -649,6 +649,14 @@
   return true;
 }
 
+static int TestZero() {
+  CBB cbb;
+  CBB_zero(&cbb);
+  // Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
+  CBB_cleanup(&cbb);
+  return 1;
+}
+
 int main(void) {
   CRYPTO_library_init();
 
@@ -665,7 +673,8 @@
       !TestCBBASN1() ||
       !TestBerConvert() ||
       !TestASN1Uint64() ||
-      !TestGetOptionalASN1Bool()) {
+      !TestGetOptionalASN1Bool() ||
+      !TestZero()) {
     return 1;
   }
 
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index f1e09a2..1da6a21 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -20,6 +20,10 @@
 #include <openssl/mem.h>
 
 
+void CBB_zero(CBB *cbb) {
+  memset(cbb, 0, sizeof(CBB));
+}
+
 static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
   struct cbb_buffer_st *base;
 
@@ -243,6 +247,11 @@
   return 1;
 }
 
+size_t CBB_len(const CBB *cbb) {
+  assert(cbb->child == NULL);
+
+  return cbb->base->len;
+}
 
 static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
                                    size_t len_len) {
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index b8caedd..5e0c538 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -137,6 +137,15 @@
   return 1;
 }
 
+int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
+  const uint8_t *v;
+  if (!cbs_get(cbs, &v, len)) {
+    return 0;
+  }
+  memcpy(out, v, len);
+  return 1;
+}
+
 static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
   uint32_t len;
   if (!cbs_get_u(cbs, &len, len_len)) {
@@ -320,14 +329,19 @@
 }
 
 int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
+  int present = 0;
+
   if (CBS_peek_asn1_tag(cbs, tag)) {
     if (!CBS_get_asn1(cbs, out, tag)) {
       return 0;
     }
-    *out_present = 1;
-  } else {
-    *out_present = 0;
+    present = 1;
   }
+
+  if (out_present != NULL) {
+    *out_present = present;
+  }
+
   return 1;
 }
 
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index 391ad19..b4ea7e5 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -38,14 +38,6 @@
  * It returns one on success and zero otherwise. */
 OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
 
-/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
- * also allows indefinite-length elements to be returned. In that case,
- * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
- * returned. */
-OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
-                                                unsigned *out_tag,
-                                                size_t *out_header_len);
-
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/chacha/CMakeLists.txt b/src/crypto/chacha/CMakeLists.txt
index 6c3f87e..266e869 100644
--- a/src/crypto/chacha/CMakeLists.txt
+++ b/src/crypto/chacha/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 if (${ARCH} STREQUAL "arm")
   set(
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
index ddc374e..0f82627 100644
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ b/src/crypto/chacha/chacha_vec_arm.S
@@ -23,6 +23,7 @@
 #     /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__) || defined(__aarch64__)
 
 	.syntax unified
 	.cpu cortex-a8
@@ -1423,4 +1424,5 @@
 	.ident	"GCC: (Linaro GCC 2014.11) 4.9.3 20141031 (prerelease)"
 	.section	.note.GNU-stack,"",%progbits
 
+#endif  /* __arm__ || __aarch64__ */
 #endif  /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/chacha/chacha_vec_arm_generate.go b/src/crypto/chacha/chacha_vec_arm_generate.go
index d681e8a..6d167b9 100644
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ b/src/crypto/chacha/chacha_vec_arm_generate.go
@@ -52,7 +52,8 @@
 	output.WriteString(compiler)
 	output.WriteString(" ")
 	output.WriteString(strings.Join(args, " "))
-	output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n\n")
+	output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n")
+	output.WriteString("#if defined(__arm__) || defined(__aarch64__)\n\n")
 
 	cmd := exec.Command(compiler, args...)
 	cmd.Stderr = os.Stderr
@@ -144,5 +145,6 @@
 `
 
 const trailer = `
+#endif  /* __arm__ || __aarch64__ */
 #endif  /* !OPENSSL_NO_ASM */
 `
diff --git a/src/crypto/cipher/CMakeLists.txt b/src/crypto/cipher/CMakeLists.txt
index 2775698..6b4c729 100644
--- a/src/crypto/cipher/CMakeLists.txt
+++ b/src/crypto/cipher/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   cipher
diff --git a/src/crypto/cipher/aead.c b/src/crypto/cipher/aead.c
index 20d699d..7e747f8 100644
--- a/src/crypto/cipher/aead.c
+++ b/src/crypto/cipher/aead.c
@@ -30,11 +30,15 @@
 
 size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }
 
+void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) {
+  memset(ctx, 0, sizeof(EVP_AEAD_CTX));
+}
+
 int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
                       const uint8_t *key, size_t key_len, size_t tag_len,
                       ENGINE *impl) {
   if (!aead->init) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_NO_DIRECTION_SET);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET);
     ctx->aead = NULL;
     return 0;
   }
@@ -47,8 +51,7 @@
                                      size_t tag_len,
                                      enum evp_aead_direction_t dir) {
   if (key_len != aead->key_len) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init_with_direction,
-                      CIPHER_R_UNSUPPORTED_KEY_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE);
     ctx->aead = NULL;
     return 0;
   }
@@ -101,12 +104,12 @@
   size_t possible_out_len = in_len + ctx->aead->overhead;
 
   if (possible_out_len < in_len /* overflow */) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     goto error;
   }
 
   if (!check_alias(in, in_len, out)) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_OUTPUT_ALIASES_INPUT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
     goto error;
   }
 
@@ -128,7 +131,7 @@
                       size_t nonce_len, const uint8_t *in, size_t in_len,
                       const uint8_t *ad, size_t ad_len) {
   if (!check_alias(in, in_len, out)) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_open, CIPHER_R_OUTPUT_ALIASES_INPUT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
     goto error;
   }
 
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index e4b75d6..baaee9e 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -22,6 +22,7 @@
 #include <openssl/err.h>
 
 #include "../test/file_test.h"
+#include "../test/scoped_types.h"
 #include "../test/stl_compat.h"
 
 
@@ -35,18 +36,6 @@
 //   CT: 5294265a60
 //   TAG: 1d45758621762e061368e68868e2f929
 
-// EVP_AEAD_CTX lacks a zero state, so it doesn't fit easily into
-// ScopedOpenSSLContext.
-class EVP_AEAD_CTXScoper {
- public:
-  EVP_AEAD_CTXScoper(EVP_AEAD_CTX *ctx) : ctx_(ctx) {}
-  ~EVP_AEAD_CTXScoper() {
-    EVP_AEAD_CTX_cleanup(ctx_);
-  }
- private:
-  EVP_AEAD_CTX *ctx_;
-};
-
 static bool TestAEAD(FileTest *t, void *arg) {
   const EVP_AEAD *aead = reinterpret_cast<const EVP_AEAD*>(arg);
 
@@ -60,20 +49,19 @@
     return false;
   }
 
-  EVP_AEAD_CTX ctx;
-  if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
-                                        key.size(), tag.size(),
-                                        evp_aead_seal)) {
+  ScopedEVP_AEAD_CTX ctx;
+  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+                                        bssl::vector_data(&key), key.size(),
+                                        tag.size(), evp_aead_seal)) {
     t->PrintLine("Failed to init AEAD.");
     return false;
   }
-  EVP_AEAD_CTXScoper cleanup(&ctx);
 
   std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead));
   if (!t->HasAttribute("NO_SEAL")) {
     size_t out_len;
-    if (!EVP_AEAD_CTX_seal(&ctx, bssl::vector_data(&out), &out_len, out.size(),
-                           bssl::vector_data(&nonce), nonce.size(),
+    if (!EVP_AEAD_CTX_seal(ctx.get(), bssl::vector_data(&out), &out_len,
+                           out.size(), bssl::vector_data(&nonce), nonce.size(),
                            bssl::vector_data(&in), in.size(),
                            bssl::vector_data(&ad), ad.size())) {
       t->PrintLine("Failed to run AEAD.");
@@ -101,17 +89,17 @@
 
   // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
   // reset after each operation.
-  EVP_AEAD_CTX_cleanup(&ctx);
-  if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
-                                        key.size(), tag.size(),
-                                        evp_aead_open)) {
+  ctx.Reset();
+  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+                                        bssl::vector_data(&key), key.size(),
+                                        tag.size(), evp_aead_open)) {
     t->PrintLine("Failed to init AEAD.");
     return false;
   }
 
   std::vector<uint8_t> out2(out.size());
   size_t out2_len;
-  int ret = EVP_AEAD_CTX_open(&ctx,
+  int ret = EVP_AEAD_CTX_open(ctx.get(),
                               bssl::vector_data(&out2), &out2_len, out2.size(),
                               bssl::vector_data(&nonce), nonce.size(),
                               bssl::vector_data(&out), out.size(),
@@ -137,10 +125,10 @@
 
   // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
   // reset after each operation.
-  EVP_AEAD_CTX_cleanup(&ctx);
-  if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
-                                        key.size(), tag.size(),
-                                        evp_aead_open)) {
+  ctx.Reset();
+  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+                                        bssl::vector_data(&key), key.size(),
+                                        tag.size(), evp_aead_open)) {
     t->PrintLine("Failed to init AEAD.");
     return false;
   }
@@ -148,8 +136,8 @@
   // Garbage at the end isn't ignored.
   out.push_back(0);
   out2.resize(out.size());
-  if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
-                        bssl::vector_data(&nonce), nonce.size(),
+  if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
+                        out2.size(), bssl::vector_data(&nonce), nonce.size(),
                         bssl::vector_data(&out), out.size(),
                         bssl::vector_data(&ad), ad.size())) {
     t->PrintLine("Decrypted bad data with trailing garbage.");
@@ -159,10 +147,10 @@
 
   // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
   // reset after each operation.
-  EVP_AEAD_CTX_cleanup(&ctx);
-  if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
-                                        key.size(), tag.size(),
-                                        evp_aead_open)) {
+  ctx.Reset();
+  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+                                        bssl::vector_data(&key), key.size(),
+                                        tag.size(), evp_aead_open)) {
     t->PrintLine("Failed to init AEAD.");
     return false;
   }
@@ -171,8 +159,8 @@
   out[0] ^= 0x80;
   out.resize(out.size() - 1);
   out2.resize(out.size());
-  if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
-                        bssl::vector_data(&nonce), nonce.size(),
+  if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
+                        out2.size(), bssl::vector_data(&nonce), nonce.size(),
                         bssl::vector_data(&out), out.size(),
                         bssl::vector_data(&ad), ad.size())) {
     t->PrintLine("Decrypted bad data with corrupted byte.");
@@ -200,6 +188,7 @@
     fprintf(stderr, "A silly tag length didn't trigger an error!\n");
     return 0;
   }
+  ERR_clear_error();
 
   /* Running a second, failed _init should not cause a memory leak. */
   if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
@@ -208,6 +197,7 @@
     fprintf(stderr, "A silly tag length didn't trigger an error!\n");
     return 0;
   }
+  ERR_clear_error();
 
   /* Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
    * no-op. */
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 400c3f5..4401867 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -68,12 +68,18 @@
 
 const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
   switch (nid) {
+    case NID_rc2_cbc:
+      return EVP_rc2_cbc();
+    case NID_rc2_40_cbc:
+      return EVP_rc2_40_cbc();
     case NID_des_ede3_cbc:
       return EVP_des_ede3_cbc();
     case NID_des_ede_cbc:
       return EVP_des_cbc();
     case NID_aes_128_cbc:
       return EVP_aes_128_cbc();
+    case NID_aes_192_cbc:
+      return EVP_aes_192_cbc();
     case NID_aes_256_cbc:
       return EVP_aes_256_cbc();
     default:
@@ -115,7 +121,7 @@
 
 int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
   if (in == NULL || in->cipher == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, CIPHER_R_INPUT_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED);
     return 0;
   }
 
@@ -125,7 +131,7 @@
   if (in->cipher_data && in->cipher->ctx_size) {
     out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
     if (!out->cipher_data) {
-      OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
       return 0;
     }
     memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
@@ -165,7 +171,7 @@
       ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
       if (!ctx->cipher_data) {
         ctx->cipher = NULL;
-        OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
         return 0;
       }
     } else {
@@ -178,12 +184,12 @@
     if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
       if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
         ctx->cipher = NULL;
-        OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_INITIALIZATION_ERROR);
+        OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR);
         return 0;
       }
     }
   } else if (!ctx->cipher) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_NO_CIPHER_SET);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
     return 0;
   }
 
@@ -338,8 +344,7 @@
   bl = ctx->buf_len;
   if (ctx->flags & EVP_CIPH_NO_PADDING) {
     if (bl) {
-      OPENSSL_PUT_ERROR(CIPHER, EVP_EncryptFinal_ex,
-                        CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
       return 0;
     }
     *out_len = 0;
@@ -434,8 +439,7 @@
   b = ctx->cipher->block_size;
   if (ctx->flags & EVP_CIPH_NO_PADDING) {
     if (ctx->buf_len) {
-      OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
-                        CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
       return 0;
     }
     *out_len = 0;
@@ -444,8 +448,7 @@
 
   if (b > 1) {
     if (ctx->buf_len || !ctx->final_used) {
-      OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
-                        CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
       return 0;
     }
     assert(b <= sizeof(ctx->final));
@@ -454,13 +457,13 @@
      * Otherwise it provides a padding oracle. */
     n = ctx->final[b - 1];
     if (n == 0 || n > (int)b) {
-      OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
       return 0;
     }
 
     for (i = 0; i < n; i++) {
       if (ctx->final[--b] != n) {
-        OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+        OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
         return 0;
       }
     }
@@ -538,19 +541,18 @@
 int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) {
   int ret;
   if (!ctx->cipher) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_NO_CIPHER_SET);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
     return 0;
   }
 
   if (!ctx->cipher->ctrl) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_CTRL_NOT_IMPLEMENTED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
     return 0;
   }
 
   ret = ctx->cipher->ctrl(ctx, command, arg, ptr);
   if (ret == -1) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl,
-                      CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
     return 0;
   }
 
@@ -572,8 +574,7 @@
   }
 
   if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
-    OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_set_key_length,
-                      CIPHER_R_INVALID_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH);
     return 0;
   }
 
@@ -630,7 +631,7 @@
     return EVP_rc4();
   } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
     return EVP_des_cbc();
-  } else if (OPENSSL_strcasecmp(name, "3des-cbc") == 0 ||
+  } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
              OPENSSL_strcasecmp(name, "3des") == 0) {
     return EVP_des_ede3_cbc();
   } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 97a84e0..5f04178 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -69,6 +69,12 @@
 static const EVP_CIPHER *GetCipher(const std::string &name) {
   if (name == "DES-CBC") {
     return EVP_des_cbc();
+  } else if (name == "DES-ECB") {
+    return EVP_des_ecb();
+  } else if (name == "DES-EDE") {
+    return EVP_des_ede();
+  } else if (name == "DES-EDE-CBC") {
+    return EVP_des_ede_cbc();
   } else if (name == "DES-EDE3-CBC") {
     return EVP_des_ede3_cbc();
   } else if (name == "RC4") {
@@ -104,6 +110,7 @@
 static bool TestOperation(FileTest *t,
                           const EVP_CIPHER *cipher,
                           bool encrypt,
+                          bool streaming,
                           const std::vector<uint8_t> &key,
                           const std::vector<uint8_t> &iv,
                           const std::vector<uint8_t> &plaintext,
@@ -160,11 +167,29 @@
       (!aad.empty() &&
        !EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad),
                          aad.size())) ||
-      !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
-      (!in->empty() &&
-       !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), &result_len1,
-                         bssl::vector_data(in), in->size())) ||
-      !EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+      !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
+    t->PrintLine("Operation failed.");
+    return false;
+  }
+  if (streaming) {
+    for (size_t i = 0; i < in->size(); i++) {
+      uint8_t c = (*in)[i];
+      int len;
+      if (!EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result) + result_len1,
+                            &len, &c, 1)) {
+        t->PrintLine("Operation failed.");
+        return false;
+      }
+      result_len1 += len;
+    }
+  } else if (!in->empty() &&
+             !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result),
+                               &result_len1, bssl::vector_data(in),
+                               in->size())) {
+    t->PrintLine("Operation failed.");
+    return false;
+  }
+  if (!EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
                           &result_len2)) {
     t->PrintLine("Operation failed.");
     return false;
@@ -236,15 +261,21 @@
   }
 
   // By default, both directions are run, unless overridden by the operation.
-  if (operation != kDecrypt &&
-      !TestOperation(t, cipher, true /* encrypt */, key, iv, plaintext,
-                     ciphertext, aad, tag)) {
-    return false;
+  if (operation != 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)) {
+      return false;
+    }
   }
-  if (operation != kEncrypt &&
-      !TestOperation(t, cipher, false /* decrypt */, 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)) {
+      return false;
+    }
   }
 
   return true;
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index 41d0aec..e8905f6 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -64,7 +64,7 @@
 #include "../modes/internal.h"
 
 #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "../arm_arch.h"
+#include <openssl/arm_arch.h>
 #endif
 
 
@@ -98,8 +98,6 @@
 #if !defined(OPENSSL_NO_ASM) && \
     (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
 #define VPAES
-extern unsigned int OPENSSL_ia32cap_P[];
-
 static char vpaes_capable(void) {
   return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0;
 }
@@ -113,7 +111,6 @@
 
 #elif !defined(OPENSSL_NO_ASM) && \
     (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#include "../arm_arch.h"
 
 #if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
 #define BSAES
@@ -338,7 +335,7 @@
   }
 
   if (ret < 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aes_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
     return 0;
   }
 
@@ -711,7 +708,7 @@
   } else {
     if (!ctx->encrypt) {
       if (gctx->taglen < 0 ||
-          !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) {
+          !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
         return -1;
       }
       gctx->iv_set = 0;
@@ -853,7 +850,7 @@
   }
 
   if (ret < 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aesni_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
     return 0;
   }
 
@@ -1066,7 +1063,7 @@
   const size_t key_bits = key_len * 8;
 
   if (key_bits != 128 && key_bits != 256) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0; /* EVP_AEAD_CTX_init should catch this. */
   }
 
@@ -1075,7 +1072,7 @@
   }
 
   if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_TAG_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
     return 0;
   }
 
@@ -1108,12 +1105,12 @@
   GCM128_CONTEXT gcm;
 
   if (in_len + gcm_ctx->tag_len < in_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + gcm_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
@@ -1152,14 +1149,14 @@
   GCM128_CONTEXT gcm;
 
   if (in_len < gcm_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   plaintext_len = in_len - gcm_ctx->tag_len;
 
   if (max_out_len < plaintext_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
@@ -1185,7 +1182,7 @@
 
   CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
   if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
@@ -1239,7 +1236,7 @@
   const size_t key_bits = key_len * 8;
 
   if (key_bits != 128 && key_bits != 256) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0; /* EVP_AEAD_CTX_init should catch this. */
   }
 
@@ -1248,14 +1245,13 @@
   }
 
   if (tag_len != 8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init,
-                      CIPHER_R_UNSUPPORTED_TAG_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
     return 0;
   }
 
   kw_ctx = OPENSSL_malloc(sizeof(struct aead_aes_key_wrap_ctx));
   if (kw_ctx == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
     return 0;
   }
 
@@ -1293,8 +1289,7 @@
   uint8_t A[AES_BLOCK_SIZE];
 
   if (ad_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_UNSUPPORTED_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
     return 0;
   }
 
@@ -1304,14 +1299,12 @@
   }
 
   if (nonce_len != 8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   if (in_len % 8 != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
     return 0;
   }
 
@@ -1320,32 +1313,29 @@
    * conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
    * a comparison is always true. */
   if (in_len > 0xfffffff0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   n = in_len / 8;
 
   if (n < 2) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
     return 0;
   }
 
   if (in_len + 8 < in_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + 8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (AES_set_encrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
-                      CIPHER_R_AES_KEY_SETUP_FAILED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
     return 0;
   }
 
@@ -1388,8 +1378,7 @@
   uint8_t A[AES_BLOCK_SIZE];
 
   if (ad_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
-                      CIPHER_R_UNSUPPORTED_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
     return 0;
   }
 
@@ -1399,14 +1388,12 @@
   }
 
   if (nonce_len != 8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
-                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   if (in_len % 8 != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
-                      CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
     return 0;
   }
 
@@ -1415,26 +1402,24 @@
    * conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
    * a comparison is always true. */
   if (in_len > 0xfffffff8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (in_len < 24) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   n = (in_len / 8) - 1;
 
   if (max_out_len < in_len - 8) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (AES_set_decrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
-                      CIPHER_R_AES_KEY_SETUP_FAILED);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
     return 0;
   }
 
@@ -1457,7 +1442,7 @@
   }
 
   if (CRYPTO_memcmp(A, nonce, 8) != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
@@ -1541,15 +1526,13 @@
   static const size_t hmac_key_len = 32;
 
   if (key_len < hmac_key_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
-                      CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0; /* EVP_AEAD_CTX_init should catch this. */
   }
 
   const size_t aes_key_len = key_len - hmac_key_len;
   if (aes_key_len != 16 && aes_key_len != 32) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
-                      CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0; /* EVP_AEAD_CTX_init should catch this. */
   }
 
@@ -1558,15 +1541,13 @@
   }
 
   if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
-                      CIPHER_R_TAG_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
     return 0;
   }
 
   aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
   if (aes_ctx == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
-                      ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
     return 0;
   }
 
@@ -1666,20 +1647,17 @@
   if (in_len + aes_ctx->tag_len < in_len ||
       /* This input is so large it would overflow the 32-bit block counter. */
       in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
-                      CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + aes_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
-                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
@@ -1703,22 +1681,19 @@
   size_t plaintext_len;
 
   if (in_len < aes_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
-                      CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   plaintext_len = in_len - aes_ctx->tag_len;
 
   if (max_out_len < plaintext_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
-                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
@@ -1727,8 +1702,7 @@
                  &aes_ctx->outer_init_state, ad, ad_len, nonce, in,
                  plaintext_len);
   if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
-                      CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index ebf0088..9dda1b0 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -42,7 +42,7 @@
   }
 
   if (tag_len > POLY1305_TAG_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_init, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
@@ -107,23 +107,22 @@
    * Casting to uint64_t inside the conditional is not sufficient to stop
    * the warning. */
   if (in_len_64 >= (1ull << 32) * 64 - 64) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (in_len + c20_ctx->tag_len < in_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + c20_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != CHACHA20_NONCE_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_IV_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
     return 0;
   }
 
@@ -156,7 +155,7 @@
   const uint64_t in_len_64 = in_len;
 
   if (in_len < c20_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
@@ -168,20 +167,19 @@
    * Casting to uint64_t inside the conditional is not sufficient to stop
    * the warning. */
   if (in_len_64 >= (1ull << 32) * 64 - 64) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (nonce_len != CHACHA20_NONCE_LEN) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_IV_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
     return 0;
   }
 
   plaintext_len = in_len - c20_ctx->tag_len;
 
   if (max_out_len < plaintext_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open,
-                      CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
@@ -195,7 +193,7 @@
   CRYPTO_poly1305_finish(&poly1305, mac);
 
   if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
diff --git a/src/crypto/cipher/e_des.c b/src/crypto/cipher/e_des.c
index 74e1fce..b1d312c 100644
--- a/src/crypto/cipher/e_des.c
+++ b/src/crypto/cipher/e_des.c
@@ -96,6 +96,31 @@
 const EVP_CIPHER *EVP_des_cbc(void) { return &des_cbc; }
 
 
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+                          size_t in_len) {
+  if (in_len < ctx->cipher->block_size) {
+    return 1;
+  }
+  in_len -= ctx->cipher->block_size;
+
+  EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+  size_t i;
+  for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+    DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+                    &dat->ks.ks, ctx->encrypt);
+  }
+  return 1;
+}
+
+static const EVP_CIPHER des_ecb = {
+    NID_des_ecb,         8 /* block_size */,  8 /* key_size */,
+    0 /* iv_len */,      sizeof(EVP_DES_KEY), EVP_CIPH_ECB_MODE,
+    NULL /* app_data */, des_init_key,        des_ecb_cipher,
+    NULL /* cleanup */,  NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ecb(void) { return &des_ecb; }
+
+
 typedef struct {
   union {
     double align;
@@ -126,10 +151,57 @@
   return 1;
 }
 
-static const EVP_CIPHER des3_cbc = {
-    NID_des_cbc,         8 /* block_size */,  24 /* key_size */,
+static const EVP_CIPHER des_ede3_cbc = {
+    NID_des_ede3_cbc,    8 /* block_size */,  24 /* key_size */,
     8 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
     NULL /* app_data */, des_ede3_init_key,   des_ede3_cbc_cipher,
     NULL /* cleanup */,  NULL /* ctrl */, };
 
-const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des3_cbc; }
+const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des_ede3_cbc; }
+
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
+                             const uint8_t *iv, int enc) {
+  DES_cblock *deskey = (DES_cblock *) key;
+  DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+
+  DES_set_key(&deskey[0], &dat->ks.ks[0]);
+  DES_set_key(&deskey[1], &dat->ks.ks[1]);
+  DES_set_key(&deskey[0], &dat->ks.ks[2]);
+
+  return 1;
+}
+
+static const EVP_CIPHER des_ede_cbc = {
+    NID_des_ede_cbc,     8 /* block_size */,  16 /* key_size */,
+    8 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
+    NULL /* app_data */, des_ede_init_key ,   des_ede3_cbc_cipher,
+    NULL /* cleanup */,  NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede_cbc(void) { return &des_ede_cbc; }
+
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                              const uint8_t *in, size_t in_len) {
+  if (in_len < ctx->cipher->block_size) {
+    return 1;
+  }
+  in_len -= ctx->cipher->block_size;
+
+  DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+  size_t i;
+  for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+    DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+                     &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2],
+                     ctx->encrypt);
+  }
+  return 1;
+}
+
+static const EVP_CIPHER des_ede_ecb = {
+    NID_des_ede_cbc,     8 /* block_size */,  16 /* key_size */,
+    0 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_ECB_MODE,
+    NULL /* app_data */, des_ede_init_key ,   des_ede_ecb_cipher,
+    NULL /* cleanup */,  NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede(void) { return &des_ede_ecb; }
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index c90ab93..8ca7bba 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -395,13 +395,18 @@
     case EVP_CTRL_INIT:
       key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
       return 1;
+    case EVP_CTRL_SET_RC2_KEY_BITS:
+      /* Should be overridden by later call to |EVP_CTRL_INIT|, but
+       * people call it, so it may as well work. */
+      key->key_bits = arg;
+      return 1;
 
     default:
       return -1;
   }
 }
 
-static const EVP_CIPHER rc2_40_cbc_cipher = {
+static const EVP_CIPHER rc2_40_cbc = {
     NID_rc2_40_cbc,
     8 /* block size */,
     5 /* 40 bit */,
@@ -416,5 +421,23 @@
 };
 
 const EVP_CIPHER *EVP_rc2_40_cbc(void) {
-  return &rc2_40_cbc_cipher;
+  return &rc2_40_cbc;
+}
+
+static const EVP_CIPHER rc2_cbc = {
+    NID_rc2_cbc,
+    8 /* block size */,
+    16 /* 128 bit */,
+    8 /* iv len */,
+    sizeof(EVP_RC2_KEY),
+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+    NULL /* app_data */,
+    rc2_init_key,
+    rc2_cbc_cipher,
+    NULL,
+    rc2_ctrl,
+};
+
+const EVP_CIPHER *EVP_rc2_cbc(void) {
+  return &rc2_cbc;
 }
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 80dea36..e05b9fd 100644
--- a/src/crypto/cipher/e_rc4.c
+++ b/src/crypto/cipher/e_rc4.c
@@ -115,20 +115,20 @@
   }
 
   if (tag_len > MD5_DIGEST_LENGTH) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   /* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed
    * by some number of bytes of RC4 key. */
   if (key_len <= MD5_DIGEST_LENGTH) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0;
   }
 
   rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx));
   if (rc4_ctx == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
     return 0;
   }
   memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx));
@@ -185,22 +185,22 @@
   uint8_t digest[MD5_DIGEST_LENGTH];
 
   if (in_len + rc4_ctx->tag_len < in_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (nonce_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_IV_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + rc4_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
@@ -288,21 +288,21 @@
   uint8_t digest[MD5_DIGEST_LENGTH];
 
   if (in_len < rc4_ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   plaintext_len = in_len - rc4_ctx->tag_len;
 
   if (nonce_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len) {
     /* This requires that the caller provide space for the MAC, even though it
      * will always be removed on return. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
@@ -366,7 +366,7 @@
   MD5_Final(digest, &md);
 
   if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
diff --git a/src/crypto/cipher/e_ssl3.c b/src/crypto/cipher/e_ssl3.c
index 1031d9b..389c52f 100644
--- a/src/crypto/cipher/e_ssl3.c
+++ b/src/crypto/cipher/e_ssl3.c
@@ -85,12 +85,12 @@
                           const EVP_CIPHER *cipher, const EVP_MD *md) {
   if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
       tag_len != EVP_MD_size(md)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
     return 0;
   }
 
   if (key_len != EVP_AEAD_key_length(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0;
   }
 
@@ -102,7 +102,7 @@
 
   AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX));
   if (ssl3_ctx == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
     return 0;
   }
   EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx);
@@ -133,29 +133,29 @@
 
   if (!ssl3_ctx->cipher_ctx.encrypt) {
     /* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_OPERATION);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
     return 0;
   }
 
   if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
       in_len > INT_MAX) {
     /* EVP_CIPHER takes int as input. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_IV_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
     return 0;
   }
 
   if (ad_len != 11 - 2 /* length bytes */) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
     return 0;
   }
 
@@ -217,36 +217,36 @@
 
   if (ssl3_ctx->cipher_ctx.encrypt) {
     /* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_OPERATION);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
     return 0;
   }
 
   size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
   if (in_len < mac_len) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   if (max_out_len < in_len) {
     /* This requires that the caller provide space for the MAC, even though it
      * will always be removed on return. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (ad_len != 11 - 2 /* length bytes */) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
     return 0;
   }
 
   if (in_len > INT_MAX) {
     /* EVP_CIPHER takes int as input. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
@@ -270,12 +270,12 @@
   if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
     unsigned padding_length = out[total - 1];
     if (total < padding_length + 1 + mac_len) {
-      OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
       return 0;
     }
     /* The padding must be minimal. */
     if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) {
-      OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
       return 0;
     }
     data_len = total - padding_length - 1 - mac_len;
@@ -289,7 +289,7 @@
     return 0;
   }
   if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
@@ -340,6 +340,13 @@
                         EVP_sha1());
 }
 
+static int aead_null_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+                                    size_t key_len, size_t tag_len,
+                                    enum evp_aead_direction_t dir) {
+  return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+                        EVP_sha1());
+}
+
 static const EVP_AEAD aead_rc4_md5_ssl3 = {
     MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
     0,                      /* nonce len */
@@ -405,6 +412,19 @@
     NULL,                        /* get_rc4_state */
 };
 
+static const EVP_AEAD aead_null_sha1_ssl3 = {
+    SHA_DIGEST_LENGTH,          /* key len */
+    0,                          /* nonce len */
+    SHA_DIGEST_LENGTH,          /* overhead (SHA1) */
+    SHA_DIGEST_LENGTH,          /* max tag length */
+    NULL,                       /* init */
+    aead_null_sha1_ssl3_init,
+    aead_ssl3_cleanup,
+    aead_ssl3_seal,
+    aead_ssl3_open,
+    NULL,                       /* get_rc4_state */
+};
+
 const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void) { return &aead_rc4_md5_ssl3; }
 
 const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void) { return &aead_rc4_sha1_ssl3; }
@@ -420,3 +440,5 @@
 const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) {
   return &aead_des_ede3_cbc_sha1_ssl3;
 }
+
+const EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; }
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index bed02cb..2778881 100644
--- a/src/crypto/cipher/e_tls.c
+++ b/src/crypto/cipher/e_tls.c
@@ -57,12 +57,12 @@
                          char implicit_iv) {
   if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
       tag_len != EVP_MD_size(md)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
     return 0;
   }
 
   if (key_len != EVP_AEAD_key_length(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_BAD_KEY_LENGTH);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
     return 0;
   }
 
@@ -75,7 +75,7 @@
 
   AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX));
   if (tls_ctx == NULL) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
     return 0;
   }
   EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
@@ -109,7 +109,7 @@
 
   if (!tls_ctx->cipher_ctx.encrypt) {
     /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_OPERATION);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
     return 0;
 
   }
@@ -117,22 +117,22 @@
   if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
       in_len > INT_MAX) {
     /* EVP_CIPHER takes int as input. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
   if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
   if (ad_len != 13 - 2 /* length bytes */) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
     return 0;
   }
 
@@ -214,36 +214,36 @@
 
   if (tls_ctx->cipher_ctx.encrypt) {
     /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_OPERATION);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
     return 0;
 
   }
 
   if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   if (max_out_len < in_len) {
     /* This requires that the caller provide space for the MAC, even though it
      * will always be removed on return. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
   if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_NONCE_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
   if (ad_len != 13 - 2 /* length bytes */) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_AD_SIZE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
     return 0;
   }
 
   if (in_len > INT_MAX) {
     /* EVP_CIPHER takes int as input. */
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_TOO_LARGE);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
@@ -278,7 +278,7 @@
         (unsigned)HMAC_size(&tls_ctx->hmac_ctx));
     /* Publicly invalid. This can be rejected in non-constant time. */
     if (padding_ok == 0) {
-      OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
       return 0;
     }
   } else {
@@ -312,7 +312,7 @@
     if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len,
                                    ad_fixed, out, data_plus_mac_len, total,
                                    tls_ctx->mac_key, tls_ctx->mac_key_len)) {
-      OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
       return 0;
     }
     assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
@@ -349,7 +349,7 @@
                                        0);
   good &= constant_time_eq_int(padding_ok, 1);
   if (!good) {
-    OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
@@ -444,6 +444,13 @@
   return 1;
 }
 
+static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+                                   size_t key_len, size_t tag_len,
+                                   enum evp_aead_direction_t dir) {
+  return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+                       EVP_sha1(), 1 /* implicit iv */);
+}
+
 static const EVP_AEAD aead_rc4_sha1_tls = {
     SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
     0,                      /* nonce len */
@@ -574,6 +581,19 @@
     NULL,                       /* get_rc4_state */
 };
 
+static const EVP_AEAD aead_null_sha1_tls = {
+    SHA_DIGEST_LENGTH,          /* key len */
+    0,                          /* nonce len */
+    SHA_DIGEST_LENGTH,          /* overhead (SHA1) */
+    SHA_DIGEST_LENGTH,          /* max tag length */
+    NULL,                       /* init */
+    aead_null_sha1_tls_init,
+    aead_tls_cleanup,
+    aead_tls_seal,
+    aead_tls_open,
+    NULL,                       /* get_rc4_state */
+};
+
 const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
 
 const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
@@ -611,3 +631,5 @@
 const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) {
   return &aead_des_ede3_cbc_sha1_tls_implicit_iv;
 }
+
+const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; }
diff --git a/src/crypto/cipher/test/aes_128_gcm_tests.txt b/src/crypto/cipher/test/aes_128_gcm_tests.txt
index 5f7ad35..75466fe 100644
--- a/src/crypto/cipher/test/aes_128_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_128_gcm_tests.txt
@@ -418,3 +418,9 @@
 CT: 5f3627bd53f8da0bbe6f3c9246d6f96fe9abb91cdecf66ddd42f833d98f4d4634c2e1e1ad4088c84c22191bdb9d99ef227320e455dd112c4a9e9cca95724fcc9ae024ed12bf60a802d0b87b99d9bf22590786567c2962171d2b05bec9754c627608e9eba7bccc70540aa4da72e1e04b26d8f968b10230f707501c0091a8ac118f86e87aae1ac00257aee29c3345bd3839154977acd378fc1b2197f5c1fd8e12262f9c2974fb92dc481eeb51aadd44a8851f61b93a84ba57f2870df0423d289bfdcfe634f9ecb7d7c6110a95b49418a2dd6663377690275c205b3efa79a0a77c92567fb429d8ee437312a39df7516dc238f7b9414938223d7ec24d256d3fb3a5954a7c75dbd79486d49ba6bb38a7ccce0f58700260b71319adf98ab8684e34913abe2d9d97193e2
 TAG: e690e89af39ff367f5d40a1b7c7ccd4f
 
+KEY: 31323334353637383930313233343536
+NONCE: 31323334353637383930313233343536
+IN: 48656c6c6f2c20576f726c64
+AD:
+CT: cec189d0e8419b90fb16d555
+TAG: 32893832a8d609224d77c2e56a922282
diff --git a/src/crypto/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index 93cb8f3..21fffdb 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -38,6 +38,22 @@
 Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
 
 
+# DES EDE CBC tests
+Cipher = DES-EDE-CBC
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 7948C0DA4FE91CD815DCA96DBC9B60A857EB954F4DEB08EB98722642AE69257B
+
+
+# DES EDE tests
+Cipher = DES-EDE
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F
+
+
 # AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
 Cipher = AES-128-ECB
 Key = 000102030405060708090A0B0C0D0E0F
@@ -360,6 +376,13 @@
 AAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
 Tag = 3b629ccfbc1119b7319e1dce2cd6fd6d
 
+Cipher = AES-128-GCM
+Key = 31323334353637383930313233343536
+IV = 31323334353637383930313233343536
+Plaintext = 48656c6c6f2c20576f726c64
+Ciphertext = cec189d0e8419b90fb16d555
+Tag = 32893832a8d609224d77c2e56a922282
+AAD =
 
 # OFB tests from OpenSSL upstream.
 
@@ -535,3 +558,40 @@
 Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
 Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
 Ciphertext = 9A4B41BA738D6C72FB16691603C18E0E
+
+# DES ECB tests
+
+Cipher = DES-ECB
+Key = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 8CA64DE9C1B123A7
+
+Cipher = DES-ECB
+Key = FFFFFFFFFFFFFFFF
+Plaintext = FFFFFFFFFFFFFFFF
+Ciphertext = 7359B2163E4EDC58
+
+Cipher = DES-ECB
+Key = 3000000000000000
+Plaintext = 1000000000000001
+Ciphertext = 958E6E627A05557B
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 1111111111111111
+Ciphertext = F40379AB9E0EC533
+
+Cipher = DES-ECB
+Key = 0123456789ABCDEF
+Plaintext = 1111111111111111
+Ciphertext = 17668DFC7292532D
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 0123456789ABCDEF
+Ciphertext = 8A5AE1F81AB8F2DD
+
+Cipher = DES-ECB
+Key = FEDCBA9876543210
+Plaintext = 0123456789ABCDEF
+Ciphertext = ED39D950FA74BCC4
diff --git a/src/crypto/cmac/CMakeLists.txt b/src/crypto/cmac/CMakeLists.txt
index 8ebd80c..bb3abc3 100644
--- a/src/crypto/cmac/CMakeLists.txt
+++ b/src/crypto/cmac/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   cmac
@@ -12,6 +12,8 @@
   cmac_test
 
   cmac_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(cmac_test crypto)
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 0f06860..53f45d1 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -19,16 +19,13 @@
 #include <openssl/cmac.h>
 
 #include "../test/scoped_types.h"
+#include "../test/test_util.h"
 
 
-static void dump(const uint8_t *got, const uint8_t *expected, size_t len) {
-  ScopedBIO bio(BIO_new_fp(stderr, 0 /* don't close */));
-
-  BIO_puts(bio.get(), "\nGot:\n");
-  BIO_hexdump(bio.get(), got, len, 2 /* indent */);
-  BIO_puts(bio.get(), "Expected:\n");
-  BIO_hexdump(bio.get(), expected, len, 2 /* indent */);
-  BIO_flush(bio.get());
+static void dump(const uint8_t *got, const uint8_t *want, size_t len) {
+  hexdump(stderr, "got :", got, len);
+  hexdump(stderr, "want:", want, len);
+  fflush(stderr);
 }
 
 static int test(const char *name, const uint8_t *key, size_t key_len,
diff --git a/src/crypto/conf/CMakeLists.txt b/src/crypto/conf/CMakeLists.txt
index 8046bb8..0a3c795 100644
--- a/src/crypto/conf/CMakeLists.txt
+++ b/src/crypto/conf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   conf
diff --git a/src/crypto/conf/conf.c b/src/crypto/conf/conf.c
index 213efc5..e098a2c 100644
--- a/src/crypto/conf/conf.c
+++ b/src/crypto/conf/conf.c
@@ -111,6 +111,16 @@
   return conf;
 }
 
+CONF_VALUE *CONF_VALUE_new(void) {
+  CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE));
+  if (!v) {
+    OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+  memset(v, 0, sizeof(CONF_VALUE));
+  return v;
+}
+
 static void value_free_contents(CONF_VALUE *value) {
   if (value->section) {
     OPENSSL_free(value->section);
@@ -137,29 +147,26 @@
     return;
   }
 
-  lh_CONF_VALUE_doall(conf->data, value_free_contents);
+  lh_CONF_VALUE_doall(conf->data, value_free);
   lh_CONF_VALUE_free(conf->data);
   OPENSSL_free(conf);
 }
 
 CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
   STACK_OF(CONF_VALUE) *sk = NULL;
-  int ok = 0, i;
+  int ok = 0;
   CONF_VALUE *v = NULL, *old_value;
 
   sk = sk_CONF_VALUE_new_null();
-  v = OPENSSL_malloc(sizeof(CONF_VALUE));
+  v = CONF_VALUE_new();
   if (sk == NULL || v == NULL) {
     goto err;
   }
-  i = strlen(section) + 1;
-  v->section = OPENSSL_malloc(i);
+  v->section = OPENSSL_strdup(section);
   if (v->section == NULL) {
     goto err;
   }
 
-  memcpy(v->section, section, i);
-  v->section[i-1] = 0;
   v->name = NULL;
   v->value = (char *)sk;
 
@@ -285,7 +292,7 @@
       rp = e;
       if (q) {
         if (r != q) {
-          OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_NO_CLOSE_BRACE);
+          OPENSSL_PUT_ERROR(CONF, CONF_R_NO_CLOSE_BRACE);
           goto err;
         }
         e++;
@@ -304,7 +311,7 @@
       }
       *rp = r;
       if (p == NULL) {
-        OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_VARIABLE_HAS_NO_VALUE);
+        OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE);
         goto err;
       }
       BUF_MEM_grow_clean(buf, (strlen(p) + buf->length - (e - from)));
@@ -372,11 +379,12 @@
   return value->value;
 }
 
-int add_string(const CONF *conf, CONF_VALUE *section, CONF_VALUE *value) {
+static int add_string(const CONF *conf, CONF_VALUE *section,
+                      CONF_VALUE *value) {
   STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value;
   CONF_VALUE *old_value;
 
-  value->section = section->section;
+  value->section = OPENSSL_strdup(section->section);
   if (!sk_CONF_VALUE_push(section_stack, value)) {
     return 0;
   }
@@ -505,20 +513,19 @@
   char *start, *psection, *pname;
 
   if ((buff = BUF_MEM_new()) == NULL) {
-    OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+    OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
     goto err;
   }
 
-  section = (char *)OPENSSL_malloc(10);
+  section = OPENSSL_strdup("default");
   if (section == NULL) {
-    OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
     goto err;
   }
-  BUF_strlcpy(section, "default", 10);
 
   sv = NCONF_new_section(conf, section);
   if (sv == NULL) {
-    OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+    OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
     goto err;
   }
 
@@ -526,7 +533,7 @@
   again = 0;
   for (;;) {
     if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
-      OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+      OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
       goto err;
     }
     p = &(buff->data[bufnum]);
@@ -595,7 +602,7 @@
           ss = p;
           goto again;
         }
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+        OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
         goto err;
       }
       *end = '\0';
@@ -606,7 +613,7 @@
         sv = NCONF_new_section(conf, section);
       }
       if (sv == NULL) {
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+        OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
         goto err;
       }
       continue;
@@ -623,7 +630,7 @@
       }
       p = eat_ws(conf, end);
       if (*p != '=') {
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_EQUAL_SIGN);
+        OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_EQUAL_SIGN);
         goto err;
       }
       *end = '\0';
@@ -639,20 +646,17 @@
       p++;
       *p = '\0';
 
-      if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+      if (!(v = CONF_VALUE_new())) {
         goto err;
       }
       if (psection == NULL) {
         psection = section;
       }
-      v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
-      v->value = NULL;
+      v->name = OPENSSL_strdup(pname);
       if (v->name == NULL) {
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
         goto err;
       }
-      BUF_strlcpy(v->name, pname, strlen(pname) + 1);
       if (!str_copy(conf, psection, &(v->value), start)) {
         goto err;
       }
@@ -662,14 +666,14 @@
           tv = NCONF_new_section(conf, psection);
         }
         if (tv == NULL) {
-          OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+          OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
           goto err;
         }
       } else {
         tv = sv;
       }
       if (add_string(conf, tv, v) == 0) {
-        OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
         goto err;
       }
       v = NULL;
@@ -715,7 +719,7 @@
   int ret;
 
   if (in == NULL) {
-    OPENSSL_PUT_ERROR(CONF, NCONF_load, ERR_R_SYS_LIB);
+    OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB);
     return 0;
   }
 
@@ -736,7 +740,7 @@
   const char *lstart, *tmpend, *p;
 
   if (list == NULL) {
-    OPENSSL_PUT_ERROR(CONF, CONF_parse_list, CONF_R_LIST_CANNOT_BE_NULL);
+    OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL);
     return 0;
   }
 
diff --git a/src/crypto/conf/internal.h b/src/crypto/conf/internal.h
new file mode 100644
index 0000000..03d1a8f
--- /dev/null
+++ b/src/crypto/conf/internal.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H
+#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. */
+CONF_VALUE *CONF_VALUE_new(void);
+
+
+#if defined(__cplusplus)
+}  /* extern C */
+#endif
+
+#endif  /* OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H */
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 74e937b..6e037ab 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -24,7 +24,7 @@
 #include <signal.h>
 #endif
 
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 
 /* We can't include <sys/auxv.h> because the Android SDK version against which
@@ -70,12 +70,12 @@
   siglongjmp(sigill_jmp, signal);
 }
 
-void CRYPTO_arm_neon_probe();
+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() {
+static int probe_for_NEON(void) {
   int supported = 0;
 
   sigset_t sigmask;
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index df0e127..924bab0 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -68,8 +68,58 @@
 #include <stdio.h>
 #include <string.h>
 
-/* OPENSSL_ia32_cpuid is defined in cpu-x86_64-asm.pl. */
-extern uint64_t OPENSSL_ia32_cpuid(uint32_t*);
+#if defined(OPENSSL_WINDOWS)
+#pragma warning(push, 3)
+#include <immintrin.h>
+#include <intrin.h>
+#pragma warning(pop)
+#endif
+
+
+/* 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
+ * |*out_edx|. */
+static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx,
+                          uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) {
+#if defined(OPENSSL_WINDOWS)
+  int tmp[4];
+  __cpuid(tmp, (int)leaf);
+  *out_eax = (uint32_t)tmp[0];
+  *out_ebx = (uint32_t)tmp[1];
+  *out_ecx = (uint32_t)tmp[2];
+  *out_edx = (uint32_t)tmp[3];
+#elif defined(__pic__) && defined(OPENSSL_32_BIT)
+  /* Inline assembly may not clobber the PIC register. For 32-bit, this is EBX.
+   * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. */
+  __asm__ volatile (
+    "xor %%ecx, %%ecx\n"
+    "mov %%ebx, %%edi\n"
+    "cpuid\n"
+    "xchg %%edi, %%ebx\n"
+    : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+    : "a"(leaf)
+  );
+#else
+  __asm__ volatile (
+    "xor %%ecx, %%ecx\n"
+    "cpuid\n"
+    : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+    : "a"(leaf)
+  );
+#endif
+}
+
+/* OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR).
+ * Currently only XCR0 is defined by Intel so |xcr| should always be zero. */
+static uint64_t OPENSSL_xgetbv(uint32_t xcr) {
+#if defined(OPENSSL_WINDOWS)
+  return (uint64_t)_xgetbv(xcr);
+#else
+  uint32_t eax, edx;
+  __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr));
+  return (((uint64_t)edx) << 32) | eax;
+#endif
+}
 
 /* handle_cpu_env applies the value from |in| to the CPUID values in |out[0]|
  * and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. */
@@ -91,18 +141,101 @@
 }
 
 void OPENSSL_cpuid_setup(void) {
+  /* Determine the vendor and maximum input value. */
+  uint32_t eax, ebx, ecx, edx;
+  OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0);
+
+  uint32_t num_ids = eax;
+
+  int is_intel = ebx == 0x756e6547 /* Genu */ &&
+                 edx == 0x49656e69 /* ineI */ &&
+                 ecx == 0x6c65746e /* ntel */;
+  int is_amd = ebx == 0x68747541 /* Auth */ &&
+               edx == 0x69746e65 /* enti */ &&
+               ecx == 0x444d4163 /* cAMD */;
+
+  int has_amd_xop = 0;
+  if (is_amd) {
+    /* AMD-specific logic.
+     * See http://developer.amd.com/wordpress/media/2012/10/254811.pdf */
+    OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000000);
+    uint32_t num_extended_ids = eax;
+    if (num_extended_ids >= 0x80000001) {
+      OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001);
+      if (ecx & (1 << 11)) {
+        has_amd_xop = 1;
+      }
+    }
+  }
+
+  uint32_t extended_features = 0;
+  if (num_ids >= 7) {
+    OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7);
+    extended_features = ebx;
+  }
+
+  /* Determine the number of cores sharing an L1 data cache to adjust the
+   * hyper-threading bit. */
+  uint32_t cores_per_cache = 0;
+  if (is_amd) {
+    /* AMD CPUs never share an L1 data cache between threads but do set the HTT
+     * bit on multi-core CPUs. */
+    cores_per_cache = 1;
+  } else if (num_ids >= 4) {
+    /* TODO(davidben): The Intel manual says this CPUID leaf enumerates all
+     * caches using ECX and doesn't say which is first. Does this matter? */
+    OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 4);
+    cores_per_cache = 1 + ((eax >> 14) & 0xfff);
+  }
+
+  OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1);
+
+  /* Adjust the hyper-threading bit. */
+  if (edx & (1 << 28)) {
+    uint32_t num_logical_cores = (ebx >> 16) & 0xff;
+    if (cores_per_cache == 1 || num_logical_cores <= 1) {
+      edx &= ~(1 << 28);
+    }
+  }
+
+  /* Reserved bit #20 was historically repurposed to control the in-memory
+   * representation of RC4 state. Always set it to zero. */
+  edx &= ~(1 << 20);
+
+  /* Reserved bit #30 is repurposed to signal an Intel CPU. */
+  if (is_intel) {
+    edx |= (1 << 30);
+  } else {
+    edx &= ~(1 << 30);
+  }
+
+  /* The SDBG bit is repurposed to denote AMD XOP support. */
+  if (has_amd_xop) {
+    ecx |= (1 << 11);
+  } else {
+    ecx &= ~(1 << 11);
+  }
+
+  uint64_t xcr0 = 0;
+  if (ecx & (1 << 27)) {
+    /* XCR0 may only be queried if the OSXSAVE bit is set. */
+    xcr0 = OPENSSL_xgetbv(0);
+  }
+  /* See Intel manual, section 14.3. */
+  if ((xcr0 & 6) != 6) {
+    /* YMM registers cannot be used. */
+    ecx &= ~(1 << 28); /* AVX */
+    ecx &= ~(1 << 12); /* FMA */
+    ecx &= ~(1 << 11); /* AMD XOP */
+    extended_features &= ~(1 << 5); /* AVX2 */
+  }
+
+  OPENSSL_ia32cap_P[0] = edx;
+  OPENSSL_ia32cap_P[1] = ecx;
+  OPENSSL_ia32cap_P[2] = extended_features;
+  OPENSSL_ia32cap_P[3] = 0;
+
   const char *env1, *env2;
-
-#if defined(OPENSSL_X86_64)
-  OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-#else
-  uint64_t vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-  /* 1<<10 sets a reserved bit to indicate that the variable
-   * was already initialised. */
-  OPENSSL_ia32cap_P[0] = ((uint32_t)vec) | (1 << 10);
-  OPENSSL_ia32cap_P[1] = vec >> 32;
-#endif
-
   env1 = getenv("OPENSSL_ia32cap");
   if (env1 == NULL) {
     return;
diff --git a/src/crypto/cpu-x86-asm.pl b/src/crypto/cpu-x86-asm.pl
deleted file mode 100644
index 319c436..0000000
--- a/src/crypto/cpu-x86-asm.pl
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/bin/env perl
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC, "${dir}perlasm", "perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],"crypto/cpu-x86-asm");
-
-for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-
-&function_begin("OPENSSL_ia32_cpuid");
-	&xor	("edx","edx");
-	&pushf	();
-	&pop	("eax");
-	&mov	("ecx","eax");
-	&xor	("eax",1<<21);
-	&push	("eax");
-	&popf	();
-	&pushf	();
-	&pop	("eax");
-	&xor	("ecx","eax");
-	&xor	("eax","eax");
-	&bt	("ecx",21);
-	&jnc	(&label("nocpuid"));
-	&mov	("esi",&wparam(0));
-	&mov	(&DWP(8,"esi"),"eax");	# clear 3rd word
-	&cpuid	();
-	&mov	("edi","eax");		# max value for standard query level
-
-	&xor	("eax","eax");
-	&cmp	("ebx",0x756e6547);	# "Genu"
-	&setne	(&LB("eax"));
-	&mov	("ebp","eax");
-	&cmp	("edx",0x49656e69);	# "ineI"
-	&setne	(&LB("eax"));
-	&or	("ebp","eax");
-	&cmp	("ecx",0x6c65746e);	# "ntel"
-	&setne	(&LB("eax"));
-	&or	("ebp","eax");		# 0 indicates Intel CPU
-	&jz	(&label("intel"));
-
-	&cmp	("ebx",0x68747541);	# "Auth"
-	&setne	(&LB("eax"));
-	&mov	("esi","eax");
-	&cmp	("edx",0x69746E65);	# "enti"
-	&setne	(&LB("eax"));
-	&or	("esi","eax");
-	&cmp	("ecx",0x444D4163);	# "cAMD"
-	&setne	(&LB("eax"));
-	&or	("esi","eax");		# 0 indicates AMD CPU
-	&jnz	(&label("intel"));
-
-	# AMD specific
-	&mov	("eax",0x80000000);
-	&cpuid	();
-	&cmp	("eax",0x80000001);
-	&jb	(&label("intel"));
-	&mov	("esi","eax");
-	&mov	("eax",0x80000001);
-	&cpuid	();
-	&or	("ebp","ecx");
-	&and	("ebp",1<<11|1);	# isolate XOP bit
-	&cmp	("esi",0x80000008);
-	&jb	(&label("intel"));
-
-	&mov	("eax",0x80000008);
-	&cpuid	();
-	&movz	("esi",&LB("ecx"));	# number of cores - 1
-	&inc	("esi");		# number of cores
-
-	&mov	("eax",1);
-	&xor	("ecx","ecx");
-	&cpuid	();
-	&bt	("edx",28);
-	&jnc	(&label("generic"));
-	&shr	("ebx",16);
-	&and	("ebx",0xff);
-	&cmp	("ebx","esi");
-	&ja	(&label("generic"));
-	&and	("edx",0xefffffff);	# clear hyper-threading bit
-	&jmp	(&label("generic"));
-	
-&set_label("intel");
-	&cmp	("edi",7);
-	&jb	(&label("cacheinfo"));
-
-	&mov	("esi",&wparam(0));
-	&mov	("eax",7);
-	&xor	("ecx","ecx");
-	&cpuid	();
-	&mov	(&DWP(8,"esi"),"ebx");
-
-&set_label("cacheinfo");
-	&cmp	("edi",4);
-	&mov	("edi",-1);
-	&jb	(&label("nocacheinfo"));
-
-	&mov	("eax",4);
-	&mov	("ecx",0);		# query L1D
-	&cpuid	();
-	&mov	("edi","eax");
-	&shr	("edi",14);
-	&and	("edi",0xfff);		# number of cores -1 per L1D
-
-&set_label("nocacheinfo");
-	&mov	("eax",1);
-	&xor	("ecx","ecx");
-	&cpuid	();
-	&and	("edx",0xbfefffff);	# force reserved bits #20, #30 to 0
-	&cmp	("ebp",0);
-	&jne	(&label("notintel"));
-	&or	("edx",1<<30);		# set reserved bit#30 on Intel CPUs
-&set_label("notintel");
-	&bt	("edx",28);		# test hyper-threading bit
-	&jnc	(&label("generic"));
-	&and	("edx",0xefffffff);
-	&cmp	("edi",0);
-	&je	(&label("generic"));
-
-	&or	("edx",0x10000000);
-	&shr	("ebx",16);
-	&cmp	(&LB("ebx"),1);
-	&ja	(&label("generic"));
-	&and	("edx",0xefffffff);	# clear hyper-threading bit if not
-
-&set_label("generic");
-	&and	("ebp",1<<11);		# isolate AMD XOP flag
-	&and	("ecx",0xfffff7ff);	# force 11th bit to 0
-	&mov	("esi","edx");
-	&or	("ebp","ecx");		# merge AMD XOP flag
-
-	&bt	("ecx",27);		# check OSXSAVE bit
-	&jnc	(&label("clear_avx"));
-	&xor	("ecx","ecx");
-	&data_byte(0x0f,0x01,0xd0);	# xgetbv
-	&and	("eax",6);
-	&cmp	("eax",6);
-	&je	(&label("done"));
-	&cmp	("eax",2);
-	&je	(&label("clear_avx"));
-&set_label("clear_xmm");
-	&and	("ebp",0xfdfffffd);	# clear AESNI and PCLMULQDQ bits
-	&and	("esi",0xfeffffff);	# clear FXSR
-&set_label("clear_avx");
-	&and	("ebp",0xefffe7ff);	# clear AVX, FMA and AMD XOP bits
-	&mov	("edi",&wparam(0));
-	&and	(&DWP(8,"edi"),0xffffffdf);	# clear AVX2
-&set_label("done");
-	&mov	("eax","esi");
-	&mov	("edx","ebp");
-&set_label("nocpuid");
-&function_end("OPENSSL_ia32_cpuid");
-
-&external_label("OPENSSL_ia32cap_P");
-
-&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
-	&xor	("eax","eax");
-	&xor	("edx","edx");
-	&picmeup("ecx","OPENSSL_ia32cap_P");
-	&bt	(&DWP(0,"ecx"),4);
-	&jnc	(&label("notsc"));
-	&rdtsc	();
-&set_label("notsc");
-	&ret	();
-&function_end_B("OPENSSL_rdtsc");
-
-# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
-# but it's safe to call it on any [supported] 32-bit platform...
-# Just check for [non-]zero return value...
-&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
-	&picmeup("ecx","OPENSSL_ia32cap_P");
-	&bt	(&DWP(0,"ecx"),4);
-	&jnc	(&label("nohalt"));	# no TSC
-
-	&data_word(0x9058900e);		# push %cs; pop %eax
-	&and	("eax",3);
-	&jnz	(&label("nohalt"));	# not enough privileges
-
-	&pushf	();
-	&pop	("eax");
-	&bt	("eax",9);
-	&jnc	(&label("nohalt"));	# interrupts are disabled
-
-	&rdtsc	();
-	&push	("edx");
-	&push	("eax");
-	&halt	();
-	&rdtsc	();
-
-	&sub	("eax",&DWP(0,"esp"));
-	&sbb	("edx",&DWP(4,"esp"));
-	&add	("esp",8);
-	&ret	();
-
-&set_label("nohalt");
-	&xor	("eax","eax");
-	&xor	("edx","edx");
-	&ret	();
-&function_end_B("OPENSSL_instrument_halt");
-
-# Essentially there is only one use for this function. Under DJGPP:
-#
-#	#include <go32.h>
-#	...
-#	i=OPENSSL_far_spin(_dos_ds,0x46c);
-#	...
-# to obtain the number of spins till closest timer interrupt.
-
-&function_begin_B("OPENSSL_far_spin");
-	&pushf	();
-	&pop	("eax");
-	&bt	("eax",9);
-	&jnc	(&label("nospin"));	# interrupts are disabled
-
-	&mov	("eax",&DWP(4,"esp"));
-	&mov	("ecx",&DWP(8,"esp"));
-	&data_word (0x90d88e1e);	# push %ds, mov %eax,%ds
-	&xor	("eax","eax");
-	&mov	("edx",&DWP(0,"ecx"));
-	&jmp	(&label("spin"));
-
-	&align	(16);
-&set_label("spin");
-	&inc	("eax");
-	&cmp	("edx",&DWP(0,"ecx"));
-	&je	(&label("spin"));
-
-	&data_word (0x1f909090);	# pop	%ds
-	&ret	();
-
-&set_label("nospin");
-	&xor	("eax","eax");
-	&xor	("edx","edx");
-	&ret	();
-&function_end_B("OPENSSL_far_spin");
-
-&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
-	&xor	("eax","eax");
-	&xor	("edx","edx");
-	&picmeup("ecx","OPENSSL_ia32cap_P");
-	&mov	("ecx",&DWP(0,"ecx"));
-	&bt	(&DWP(0,"ecx"),1);
-	&jnc	(&label("no_x87"));
-	if ($sse2) {
-		&and	("ecx",1<<26|1<<24);	# check SSE2 and FXSR bits
-		&cmp	("ecx",1<<26|1<<24);
-		&jne	(&label("no_sse2"));
-		&pxor	("xmm0","xmm0");
-		&pxor	("xmm1","xmm1");
-		&pxor	("xmm2","xmm2");
-		&pxor	("xmm3","xmm3");
-		&pxor	("xmm4","xmm4");
-		&pxor	("xmm5","xmm5");
-		&pxor	("xmm6","xmm6");
-		&pxor	("xmm7","xmm7");
-	&set_label("no_sse2");
-	}
-	# just a bunch of fldz to zap the fp/mm bank followed by finit...
-	&data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
-&set_label("no_x87");
-	&lea	("eax",&DWP(4,"esp"));
-	&ret	();
-&function_end_B("OPENSSL_wipe_cpu");
-
-&function_begin_B("OPENSSL_atomic_add");
-	&mov	("edx",&DWP(4,"esp"));	# fetch the pointer, 1st arg
-	&mov	("ecx",&DWP(8,"esp"));	# fetch the increment, 2nd arg
-	&push	("ebx");
-	&nop	();
-	&mov	("eax",&DWP(0,"edx"));
-&set_label("spin");
-	&lea	("ebx",&DWP(0,"eax","ecx"));
-	&nop	();
-	&data_word(0x1ab10ff0);	# lock;	cmpxchg	%ebx,(%edx)	# %eax is envolved and is always reloaded
-	&jne	(&label("spin"));
-	&mov	("eax","ebx");	# OpenSSL expects the new value
-	&pop	("ebx");
-	&ret	();
-&function_end_B("OPENSSL_atomic_add");
-
-# This function can become handy under Win32 in situations when
-# we don't know which calling convention, __stdcall or __cdecl(*),
-# indirect callee is using. In C it can be deployed as
-#
-#ifdef OPENSSL_CPUID_OBJ
-#	type OPENSSL_indirect_call(void *f,...);
-#	...
-#	OPENSSL_indirect_call(func,[up to $max arguments]);
-#endif
-#
-# (*)	it's designed to work even for __fastcall if number of
-#	arguments is 1 or 2!
-&function_begin_B("OPENSSL_indirect_call");
-	{
-	my ($max,$i)=(7,);	# $max has to be chosen as 4*n-1
-				# in order to preserve eventual
-				# stack alignment
-	&push	("ebp");
-	&mov	("ebp","esp");
-	&sub	("esp",$max*4);
-	&mov	("ecx",&DWP(12,"ebp"));
-	&mov	(&DWP(0,"esp"),"ecx");
-	&mov	("edx",&DWP(16,"ebp"));
-	&mov	(&DWP(4,"esp"),"edx");
-	for($i=2;$i<$max;$i++)
-		{
-		# Some copies will be redundant/bogus...
-		&mov	("eax",&DWP(12+$i*4,"ebp"));
-		&mov	(&DWP(0+$i*4,"esp"),"eax");
-		}
-	&call_ptr	(&DWP(8,"ebp"));# make the call...
-	&mov	("esp","ebp");	# ... and just restore the stack pointer
-				# without paying attention to what we called,
-				# (__cdecl *func) or (__stdcall *one).
-	&pop	("ebp");
-	&ret	();
-	}
-&function_end_B("OPENSSL_indirect_call");
-
-&function_begin_B("OPENSSL_ia32_rdrand");
-	&mov	("ecx",8);
-&set_label("loop");
-	&rdrand	("eax");
-	&jc	(&label("break"));
-	&loop	(&label("loop"));
-&set_label("break");
-	&cmp	("eax",0);
-	&cmove	("eax","ecx");
-	&ret	();
-&function_end_B("OPENSSL_ia32_rdrand");
-
-&hidden("OPENSSL_ia32cap_P");
-
-&asm_finish();
diff --git a/src/crypto/cpu-x86_64-asm.pl b/src/crypto/cpu-x86_64-asm.pl
deleted file mode 100644
index 89d7a6c..0000000
--- a/src/crypto/cpu-x86_64-asm.pl
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env perl
-
-$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";
-
-open OUT,"| \"$^X\" $xlate $flavour $output";
-*STDOUT=*OUT;
-
-($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") :	# Win64 order
-				 ("%rdi","%rsi","%rdx","%rcx");	# Unix order
-
-print<<___;
-.text
-
-.globl	OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,\@function,1
-.align	16
-OPENSSL_ia32_cpuid:
-	# On Windows, $arg1 is rcx, but that will be clobbered. So make Windows
-	# use the same register as Unix.
-	mov	$arg1,%rdi
-	mov	%rbx,%r8		# save %rbx
-
-	xor	%eax,%eax
-	mov	%eax,8(%rdi)		# clear 3rd word
-	cpuid
-	mov	%eax,%r11d		# max value for standard query level
-
-	xor	%eax,%eax
-	cmp	\$0x756e6547,%ebx	# "Genu"
-	setne	%al
-	mov	%eax,%r9d
-	cmp	\$0x49656e69,%edx	# "ineI"
-	setne	%al
-	or	%eax,%r9d
-	cmp	\$0x6c65746e,%ecx	# "ntel"
-	setne	%al
-	or	%eax,%r9d		# 0 indicates Intel CPU
-	jz	.Lintel
-
-	cmp	\$0x68747541,%ebx	# "Auth"
-	setne	%al
-	mov	%eax,%r10d
-	cmp	\$0x69746E65,%edx	# "enti"
-	setne	%al
-	or	%eax,%r10d
-	cmp	\$0x444D4163,%ecx	# "cAMD"
-	setne	%al
-	or	%eax,%r10d		# 0 indicates AMD CPU
-	jnz	.Lintel
-
-	# AMD specific
-	# See http://developer.amd.com/wordpress/media/2012/10/254811.pdf (1)
-
-	mov	\$0x80000000,%eax
-	cpuid
-	# Returns "The largest CPUID extended function input value supported by
-	# the processor implementation." in EAX.
-	cmp	\$0x80000001,%eax
-	jb	.Lintel
-	mov	%eax,%r10d
-	mov	\$0x80000001,%eax
-	cpuid
-	# Returns feature bits in ECX. See page 20 of [1].
-	# TODO(fork): I think this should be a MOV.
-	or	%ecx,%r9d
-	and	\$0x00000801,%r9d	# isolate AMD XOP bit, 1<<11
-
-	cmp	\$0x80000008,%r10d
-	jb	.Lintel
-
-	mov	\$0x80000008,%eax
-	cpuid
-	# Returns APIC ID and number of cores in ECX. See page 27 of [1].
-	movzb	%cl,%r10		# number of cores - 1
-	inc	%r10			# number of cores
-
-	mov	\$1,%eax
-	cpuid
-	# See page 13 of [1].
-	bt	\$28,%edx		# test hyper-threading bit
-	jnc	.Lgeneric
-	shr	\$16,%ebx		# number of logical processors
-	cmp	%r10b,%bl
-	ja	.Lgeneric
-	and	\$0xefffffff,%edx	# Clear hyper-threading bit.
-	jmp	.Lgeneric
-
-.Lintel:
-	cmp	\$4,%r11d
-	mov	\$-1,%r10d
-	jb	.Lnocacheinfo
-
-	mov	\$4,%eax
-	mov	\$0,%ecx		# query L1D
-	cpuid
-	mov	%eax,%r10d
-	shr	\$14,%r10d
-	and	\$0xfff,%r10d		# number of cores -1 per L1D
-
-	cmp	\$7,%r11d
-	jb	.Lnocacheinfo
-
-	mov	\$7,%eax
-	xor	%ecx,%ecx
-	cpuid
-	mov	%ebx,8(%rdi)
-
-.Lnocacheinfo:
-	mov	\$1,%eax
-	cpuid
-	# Gets feature information. See table 3-21 in the Intel manual.
-	and	\$0xbfefffff,%edx	# force reserved bits to 0
-	cmp	\$0,%r9d
-	jne	.Lnotintel
-	or	\$0x40000000,%edx	# set reserved bit#30 on Intel CPUs
-.Lnotintel:
-	bt	\$28,%edx		# test hyper-threading bit
-	jnc	.Lgeneric
-	and	\$0xefffffff,%edx	# ~(1<<28) - clear hyper-threading.
-	cmp	\$0,%r10d
-	je	.Lgeneric
-
-	or	\$0x10000000,%edx	# 1<<28
-	shr	\$16,%ebx
-	cmp	\$1,%bl			# see if cache is shared
-	ja	.Lgeneric
-	and	\$0xefffffff,%edx	# ~(1<<28)
-.Lgeneric:
-	and	\$0x00000800,%r9d	# isolate AMD XOP flag
-	and	\$0xfffff7ff,%ecx
-	or	%ecx,%r9d		# merge AMD XOP flag
-
-	mov	%edx,%r10d		# %r9d:%r10d is copy of %ecx:%edx
-	bt	\$27,%r9d		# check OSXSAVE bit
-	jnc	.Lclear_avx
-	xor	%ecx,%ecx		# XCR0
-	.byte	0x0f,0x01,0xd0		# xgetbv
-	and	\$6,%eax		# isolate XMM and YMM state support
-	cmp	\$6,%eax
-	je	.Ldone
-.Lclear_avx:
-	mov	\$0xefffe7ff,%eax	# ~(1<<28|1<<12|1<<11)
-	and	%eax,%r9d		# clear AVX, FMA and AMD XOP bits
-	andl	\$0xffffffdf,8(%rdi)	# cleax AVX2, ~(1<<5)
-.Ldone:
-	movl	%r9d,4(%rdi)
-	movl	%r10d,0(%rdi)
-	mov	%r8,%rbx		# restore %rbx
-	ret
-.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-___
-
-close STDOUT;	# flush
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index d9bb07e..34d04b4 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -55,7 +55,7 @@
 uint32_t OPENSSL_ia32cap_P[4] = {0};
 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
 
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 #if defined(__ARM_NEON__)
 uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
diff --git a/src/crypto/des/CMakeLists.txt b/src/crypto/des/CMakeLists.txt
index 7d49ff3..f61fa14 100644
--- a/src/crypto/des/CMakeLists.txt
+++ b/src/crypto/des/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   des
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index 9cd75f5..a5669a6 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -298,10 +298,8 @@
                                   0, 1, 1, 1, 1, 1, 1, 0};
   uint32_t c, d, t, s, t2;
   const uint8_t *in;
-  uint32_t *k;
   int i;
 
-  k = &schedule->ks->deslong[0];
   in = key->bytes;
 
   c2l(in, c);
@@ -344,10 +342,10 @@
 
     /* table contained 0213 4657 */
     t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
-    *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+    schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL;
 
     t2 = ((s >> 16L) | (t & 0xffff0000L));
-    *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+    schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL;
   }
 }
 
@@ -382,7 +380,6 @@
 
 static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
   uint32_t l, r, t, u;
-  const uint32_t *s;
 
   r = data[0];
   l = data[1];
@@ -398,43 +395,42 @@
   r = ROTATE(r, 29) & 0xffffffffL;
   l = ROTATE(l, 29) & 0xffffffffL;
 
-  s = ks->ks->deslong;
   /* I don't know if it is worth the effort of loop unrolling the
    * inner loop */
   if (enc) {
-    D_ENCRYPT(l, r, 0);  /*  1 */
-    D_ENCRYPT(r, l, 2);  /*  2 */
-    D_ENCRYPT(l, r, 4);  /*  3 */
-    D_ENCRYPT(r, l, 6);  /*  4 */
-    D_ENCRYPT(l, r, 8);  /*  5 */
-    D_ENCRYPT(r, l, 10); /*  6 */
-    D_ENCRYPT(l, r, 12); /*  7 */
-    D_ENCRYPT(r, l, 14); /*  8 */
-    D_ENCRYPT(l, r, 16); /*  9 */
-    D_ENCRYPT(r, l, 18); /*  10 */
-    D_ENCRYPT(l, r, 20); /*  11 */
-    D_ENCRYPT(r, l, 22); /*  12 */
-    D_ENCRYPT(l, r, 24); /*  13 */
-    D_ENCRYPT(r, l, 26); /*  14 */
-    D_ENCRYPT(l, r, 28); /*  15 */
-    D_ENCRYPT(r, l, 30); /*  16 */
+    D_ENCRYPT(ks, l, r, 0);
+    D_ENCRYPT(ks, r, l, 1);
+    D_ENCRYPT(ks, l, r, 2);
+    D_ENCRYPT(ks, r, l, 3);
+    D_ENCRYPT(ks, l, r, 4);
+    D_ENCRYPT(ks, r, l, 5);
+    D_ENCRYPT(ks, l, r, 6);
+    D_ENCRYPT(ks, r, l, 7);
+    D_ENCRYPT(ks, l, r, 8);
+    D_ENCRYPT(ks, r, l, 9);
+    D_ENCRYPT(ks, l, r, 10);
+    D_ENCRYPT(ks, r, l, 11);
+    D_ENCRYPT(ks, l, r, 12);
+    D_ENCRYPT(ks, r, l, 13);
+    D_ENCRYPT(ks, l, r, 14);
+    D_ENCRYPT(ks, r, l, 15);
   } else {
-    D_ENCRYPT(l, r, 30); /* 16 */
-    D_ENCRYPT(r, l, 28); /* 15 */
-    D_ENCRYPT(l, r, 26); /* 14 */
-    D_ENCRYPT(r, l, 24); /* 13 */
-    D_ENCRYPT(l, r, 22); /* 12 */
-    D_ENCRYPT(r, l, 20); /* 11 */
-    D_ENCRYPT(l, r, 18); /* 10 */
-    D_ENCRYPT(r, l, 16); /*  9 */
-    D_ENCRYPT(l, r, 14); /*  8 */
-    D_ENCRYPT(r, l, 12); /*  7 */
-    D_ENCRYPT(l, r, 10); /*  6 */
-    D_ENCRYPT(r, l, 8);  /*  5 */
-    D_ENCRYPT(l, r, 6);  /*  4 */
-    D_ENCRYPT(r, l, 4);  /*  3 */
-    D_ENCRYPT(l, r, 2);  /*  2 */
-    D_ENCRYPT(r, l, 0);  /*  1 */
+    D_ENCRYPT(ks, l, r, 15);
+    D_ENCRYPT(ks, r, l, 14);
+    D_ENCRYPT(ks, l, r, 13);
+    D_ENCRYPT(ks, r, l, 12);
+    D_ENCRYPT(ks, l, r, 11);
+    D_ENCRYPT(ks, r, l, 10);
+    D_ENCRYPT(ks, l, r, 9);
+    D_ENCRYPT(ks, r, l, 8);
+    D_ENCRYPT(ks, l, r, 7);
+    D_ENCRYPT(ks, r, l, 6);
+    D_ENCRYPT(ks, l, r, 5);
+    D_ENCRYPT(ks, r, l, 4);
+    D_ENCRYPT(ks, l, r, 3);
+    D_ENCRYPT(ks, r, l, 2);
+    D_ENCRYPT(ks, l, r, 1);
+    D_ENCRYPT(ks, r, l, 0);
   }
 
   /* rotate and clear the top bits on machines with 8byte longs */
@@ -448,7 +444,6 @@
 
 static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
   uint32_t l, r, t, u;
-  const uint32_t *s;
 
   r = data[0];
   l = data[1];
@@ -462,52 +457,51 @@
   r = ROTATE(r, 29) & 0xffffffffL;
   l = ROTATE(l, 29) & 0xffffffffL;
 
-  s = ks->ks->deslong;
   /* I don't know if it is worth the effort of loop unrolling the
    * inner loop */
   if (enc) {
-    D_ENCRYPT(l, r, 0);  /*  1 */
-    D_ENCRYPT(r, l, 2);  /*  2 */
-    D_ENCRYPT(l, r, 4);  /*  3 */
-    D_ENCRYPT(r, l, 6);  /*  4 */
-    D_ENCRYPT(l, r, 8);  /*  5 */
-    D_ENCRYPT(r, l, 10); /*  6 */
-    D_ENCRYPT(l, r, 12); /*  7 */
-    D_ENCRYPT(r, l, 14); /*  8 */
-    D_ENCRYPT(l, r, 16); /*  9 */
-    D_ENCRYPT(r, l, 18); /*  10 */
-    D_ENCRYPT(l, r, 20); /*  11 */
-    D_ENCRYPT(r, l, 22); /*  12 */
-    D_ENCRYPT(l, r, 24); /*  13 */
-    D_ENCRYPT(r, l, 26); /*  14 */
-    D_ENCRYPT(l, r, 28); /*  15 */
-    D_ENCRYPT(r, l, 30); /*  16 */
+    D_ENCRYPT(ks, l, r, 0);
+    D_ENCRYPT(ks, r, l, 1);
+    D_ENCRYPT(ks, l, r, 2);
+    D_ENCRYPT(ks, r, l, 3);
+    D_ENCRYPT(ks, l, r, 4);
+    D_ENCRYPT(ks, r, l, 5);
+    D_ENCRYPT(ks, l, r, 6);
+    D_ENCRYPT(ks, r, l, 7);
+    D_ENCRYPT(ks, l, r, 8);
+    D_ENCRYPT(ks, r, l, 9);
+    D_ENCRYPT(ks, l, r, 10);
+    D_ENCRYPT(ks, r, l, 11);
+    D_ENCRYPT(ks, l, r, 12);
+    D_ENCRYPT(ks, r, l, 13);
+    D_ENCRYPT(ks, l, r, 14);
+    D_ENCRYPT(ks, r, l, 15);
   } else {
-    D_ENCRYPT(l, r, 30); /* 16 */
-    D_ENCRYPT(r, l, 28); /* 15 */
-    D_ENCRYPT(l, r, 26); /* 14 */
-    D_ENCRYPT(r, l, 24); /* 13 */
-    D_ENCRYPT(l, r, 22); /* 12 */
-    D_ENCRYPT(r, l, 20); /* 11 */
-    D_ENCRYPT(l, r, 18); /* 10 */
-    D_ENCRYPT(r, l, 16); /*  9 */
-    D_ENCRYPT(l, r, 14); /*  8 */
-    D_ENCRYPT(r, l, 12); /*  7 */
-    D_ENCRYPT(l, r, 10); /*  6 */
-    D_ENCRYPT(r, l, 8);  /*  5 */
-    D_ENCRYPT(l, r, 6);  /*  4 */
-    D_ENCRYPT(r, l, 4);  /*  3 */
-    D_ENCRYPT(l, r, 2);  /*  2 */
-    D_ENCRYPT(r, l, 0);  /*  1 */
+    D_ENCRYPT(ks, l, r, 15);
+    D_ENCRYPT(ks, r, l, 14);
+    D_ENCRYPT(ks, l, r, 13);
+    D_ENCRYPT(ks, r, l, 12);
+    D_ENCRYPT(ks, l, r, 11);
+    D_ENCRYPT(ks, r, l, 10);
+    D_ENCRYPT(ks, l, r, 9);
+    D_ENCRYPT(ks, r, l, 8);
+    D_ENCRYPT(ks, l, r, 7);
+    D_ENCRYPT(ks, r, l, 6);
+    D_ENCRYPT(ks, l, r, 5);
+    D_ENCRYPT(ks, r, l, 4);
+    D_ENCRYPT(ks, l, r, 3);
+    D_ENCRYPT(ks, r, l, 2);
+    D_ENCRYPT(ks, l, r, 1);
+    D_ENCRYPT(ks, r, l, 0);
   }
   /* rotate and clear the top bits on machines with 8byte longs */
   data[0] = ROTATE(l, 3) & 0xffffffffL;
   data[1] = ROTATE(r, 3) & 0xffffffffL;
 }
 
-static void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
-                         const DES_key_schedule *ks2,
-                         const DES_key_schedule *ks3) {
+/* DES_encrypt3 is not static because it's used in decrepit. */
+void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+                  const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
   uint32_t l, r;
 
   l = data[0];
@@ -525,9 +519,9 @@
   data[1] = r;
 }
 
-static void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
-                         const DES_key_schedule *ks2,
-                         const DES_key_schedule *ks3) {
+/* DES_decrypt3 is not static because it's used in decrepit. */
+void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+                  const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
   uint32_t l, r;
 
   l = data[0];
@@ -770,3 +764,10 @@
                           int enc) {
   DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc);
 }
+
+
+/* Deprecated functions. */
+
+void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) {
+  DES_set_key(key, schedule);
+}
diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h
index d3a5cec..91559ff 100644
--- a/src/crypto/des/internal.h
+++ b/src/crypto/des/internal.h
@@ -183,13 +183,13 @@
     PERM_OP(l, r, tt, 4, 0x0f0f0f0fL);  \
   }
 
-#define LOAD_DATA(R, S, u, t, E0, E1) \
-  u = R ^ s[S];                            \
-  t = R ^ s[S + 1]
+#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
+  u = R ^ ks->subkeys[S][0];              \
+  t = R ^ ks->subkeys[S][1]
 
-#define D_ENCRYPT(LL, R, S)                                                    \
+#define D_ENCRYPT(ks, LL, R, S)                                                \
   {                                                                            \
-    LOAD_DATA(R, S, u, t, E0, E1);                                             \
+    LOAD_DATA(ks, R, S, u, t, E0, E1);                                         \
     t = ROTATE(t, 4);                                                          \
     LL ^=                                                                      \
         DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
diff --git a/src/crypto/dh/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt
index d0c1da7..1a46512 100644
--- a/src/crypto/dh/CMakeLists.txt
+++ b/src/crypto/dh/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   dh
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index 96b85f3..d25f358 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -78,7 +78,7 @@
 DH *DH_new_method(const ENGINE *engine) {
   DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
   if (dh == NULL) {
-    OPENSSL_PUT_ERROR(DH, DH_new_method, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
diff --git a/src/crypto/dh/dh_impl.c b/src/crypto/dh/dh_impl.c
index f269412..6cf0abb 100644
--- a/src/crypto/dh/dh_impl.c
+++ b/src/crypto/dh/dh_impl.c
@@ -117,7 +117,7 @@
   }
 
   if (generator <= 1) {
-    OPENSSL_PUT_ERROR(DH, generate_parameters, DH_R_BAD_GENERATOR);
+    OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
     goto err;
   }
   if (generator == DH_GENERATOR_2) {
@@ -165,7 +165,7 @@
 
 err:
   if (!ok) {
-    OPENSSL_PUT_ERROR(DH, generate_parameters, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
   }
 
   if (ctx != NULL) {
@@ -242,7 +242,7 @@
 
 err:
   if (ok != 1) {
-    OPENSSL_PUT_ERROR(DH, generate_key, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
   }
 
   if (dh->pub_key == NULL) {
@@ -264,7 +264,7 @@
   BIGNUM local_priv;
 
   if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
-    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_MODULUS_TOO_LARGE);
+    OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE);
     goto err;
   }
 
@@ -279,7 +279,7 @@
   }
 
   if (dh->priv_key == NULL) {
-    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_NO_PRIVATE_VALUE);
+    OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE);
     goto err;
   }
 
@@ -290,14 +290,14 @@
   }
 
   if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
-    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_INVALID_PUBKEY);
+    OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
     goto err;
   }
 
   BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
   if (!BN_mod_exp_mont(shared_key, pub_key, &local_priv, dh->p, ctx,
                        mont)) {
-    OPENSSL_PUT_ERROR(DH, compute_key, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
     goto err;
   }
 
diff --git a/src/crypto/digest/CMakeLists.txt b/src/crypto/digest/CMakeLists.txt
index 816d116..856e45a 100644
--- a/src/crypto/digest/CMakeLists.txt
+++ b/src/crypto/digest/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   digest
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index f09948b..eb71b07 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -116,8 +116,7 @@
   uint8_t *tmp_buf = NULL;
 
   if (in == NULL || in->digest == NULL) {
-    OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex,
-                      DIGEST_R_INPUT_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED);
     return 0;
   }
 
@@ -130,15 +129,15 @@
   }
 
   EVP_MD_CTX_cleanup(out);
-  memcpy(out, in, sizeof(EVP_MD_CTX));
 
+  out->digest = in->digest;
   if (in->md_data && in->digest->ctx_size) {
     if (tmp_buf) {
       out->md_data = tmp_buf;
     } else {
       out->md_data = OPENSSL_malloc(in->digest->ctx_size);
       if (!out->md_data) {
-        OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
         return 0;
       }
     }
@@ -146,6 +145,7 @@
   }
 
   assert(in->pctx == NULL || in->pctx_ops != NULL);
+  out->pctx_ops = in->pctx_ops;
   if (in->pctx && in->pctx_ops) {
     out->pctx = in->pctx_ops->dup(in->pctx);
     if (!out->pctx) {
@@ -164,30 +164,20 @@
 
 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) {
   if (ctx->digest != type) {
-    if (ctx->digest && ctx->digest->ctx_size) {
+    if (ctx->digest && ctx->digest->ctx_size > 0) {
       OPENSSL_free(ctx->md_data);
     }
     ctx->digest = type;
-    if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
-      ctx->update = type->update;
+    if (type->ctx_size > 0) {
       ctx->md_data = OPENSSL_malloc(type->ctx_size);
       if (ctx->md_data == NULL) {
-        OPENSSL_PUT_ERROR(DIGEST, EVP_DigestInit_ex, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
         return 0;
       }
     }
   }
 
   assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);
-  if (ctx->pctx_ops) {
-    if (!ctx->pctx_ops->begin_digest(ctx)) {
-      return 0;
-    }
-  }
-
-  if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) {
-    return 1;
-  }
 
   ctx->digest->init(ctx);
   return 1;
@@ -199,7 +189,7 @@
 }
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
-  ctx->update(ctx, data, len);
+  ctx->digest->update(ctx, data, len);
   return 1;
 }
 
@@ -214,7 +204,7 @@
 }
 
 int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) {
-  EVP_DigestFinal_ex(ctx, md, size);
+  (void)EVP_DigestFinal_ex(ctx, md, size);
   EVP_MD_CTX_cleanup(ctx);
   return 1;
 }
@@ -253,10 +243,6 @@
   return EVP_MD_type(EVP_MD_CTX_md(ctx));
 }
 
-void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags) {
-  ctx->flags |= flags;
-}
-
 int EVP_add_digest(const EVP_MD *digest) {
   return 1;
 }
diff --git a/src/crypto/digest/digests.c b/src/crypto/digest/digests.c
index f5eda36..3307f26 100644
--- a/src/crypto/digest/digests.c
+++ b/src/crypto/digest/digests.c
@@ -67,7 +67,7 @@
 #include "internal.h"
 
 #if defined(NDEBUG)
-#define CHECK(x) x
+#define CHECK(x) (void) (x)
 #else
 #define CHECK(x) assert(x)
 #endif
@@ -262,6 +262,7 @@
 };
 
 static const struct nid_to_digest nid_to_digest_mapping[] = {
+  { NID_md4, EVP_md4, SN_md4, LN_md4 },
   { NID_md5, EVP_md5, SN_md5, LN_md5 },
   { NID_sha1, EVP_sha1, SN_sha1, LN_sha1 },
   { NID_sha224, EVP_sha224, SN_sha224, LN_sha224 },
diff --git a/src/crypto/digest/internal.h b/src/crypto/digest/internal.h
index 1572fa8..e3d812a 100644
--- a/src/crypto/digest/internal.h
+++ b/src/crypto/digest/internal.h
@@ -92,7 +92,7 @@
 };
 
 /* evp_md_pctx_ops contains function pointers to allow the |pctx| member of
- * |EVP_MD_CTX| to be manipulated without breaking laying by calling EVP
+ * |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP
  * functions. */
 struct evp_md_pctx_ops {
   /* free is called when an |EVP_MD_CTX| is being freed and the |pctx| also
@@ -102,23 +102,8 @@
   /* dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs
    * to be copied. */
   EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx);
-
-  /* begin_digest is called when a new digest operation is started. It returns
-   * one on success and zero otherwise. */
-  int (*begin_digest) (EVP_MD_CTX *ctx);
 };
 
-/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
-OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
-
-/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
- * called, the |update| member not to be copied from the |EVP_MD| in
- * |EVP_DigestInit_ex| and for |md_data| not to be initialised.
- *
- * TODO(davidben): This is an implementation detail of |EVP_PKEY_HMAC| and can
- * be removed when it is gone. */
-#define EVP_MD_CTX_FLAG_NO_INIT 1
-
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/dsa/CMakeLists.txt b/src/crypto/dsa/CMakeLists.txt
index 1bb8b63..e8b7793 100644
--- a/src/crypto/dsa/CMakeLists.txt
+++ b/src/crypto/dsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   dsa
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index 65444b1..3ff29c4 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -82,7 +82,7 @@
 DSA *DSA_new_method(const ENGINE *engine) {
   DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
   if (dsa == NULL) {
-    OPENSSL_PUT_ERROR(DSA, DSA_new_method, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
diff --git a/src/crypto/dsa/dsa_asn1.c b/src/crypto/dsa/dsa_asn1.c
index 933fba7..b6b3fa4 100644
--- a/src/crypto/dsa/dsa_asn1.c
+++ b/src/crypto/dsa/dsa_asn1.c
@@ -73,7 +73,7 @@
   DSA_SIG *sig;
   sig = OPENSSL_malloc(sizeof(DSA_SIG));
   if (!sig) {
-    OPENSSL_PUT_ERROR(DSA, dsa_sig_cb, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
     return 0;
   }
 
diff --git a/src/crypto/dsa/dsa_impl.c b/src/crypto/dsa/dsa_impl.c
index 2ab8ba8..b10610d 100644
--- a/src/crypto/dsa/dsa_impl.c
+++ b/src/crypto/dsa/dsa_impl.c
@@ -83,7 +83,7 @@
   int ret = 0;
 
   if (!dsa->p || !dsa->q || !dsa->g) {
-    OPENSSL_PUT_ERROR(DSA, sign_setup, DSA_R_MISSING_PARAMETERS);
+    OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
     return 0;
   }
 
@@ -171,7 +171,7 @@
 
 err:
   if (!ret) {
-    OPENSSL_PUT_ERROR(DSA, sign_setup, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
     if (r != NULL) {
       BN_clear_free(r);
     }
@@ -269,7 +269,7 @@
 
 err:
   if (!ret) {
-    OPENSSL_PUT_ERROR(DSA, sign, reason);
+    OPENSSL_PUT_ERROR(DSA, reason);
     BN_free(r);
     BN_free(s);
   }
@@ -292,19 +292,19 @@
   *out_valid = 0;
 
   if (!dsa->p || !dsa->q || !dsa->g) {
-    OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MISSING_PARAMETERS);
+    OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
     return 0;
   }
 
   i = BN_num_bits(dsa->q);
   /* fips 186-3 allows only different sizes for q */
   if (i != 160 && i != 224 && i != 256) {
-    OPENSSL_PUT_ERROR(DSA, verify, DSA_R_BAD_Q_VALUE);
+    OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
     return 0;
   }
 
   if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
-    OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MODULUS_TOO_LARGE);
+    OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
     return 0;
   }
 
@@ -381,7 +381,7 @@
 
 err:
   if (ret != 1) {
-    OPENSSL_PUT_ERROR(DSA, verify, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
   }
   BN_CTX_free(ctx);
   BN_free(&u1);
@@ -487,16 +487,14 @@
 
   bits = (bits + 63) / 64 * 64;
 
-  /* NB: seed_len == 0 is special case: copy generated seed to
-   * seed_in if it is not NULL. */
-  if (seed_len && (seed_len < (size_t)qsize)) {
-    seed_in = NULL; /* seed buffer too small -- ignore */
-  }
-  if (seed_len > (size_t)qsize) {
-    seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
-                       * but our internal buffers are restricted to 160 bits*/
-  }
   if (seed_in != NULL) {
+    if (seed_len < (size_t)qsize) {
+      return 0;
+    }
+    if (seed_len > (size_t)qsize) {
+      /* Only consume as much seed as is expected. */
+      seed_len = qsize;
+    }
     memcpy(seed, seed_in, seed_len);
   }
 
@@ -527,21 +525,19 @@
   for (;;) {
     /* Find q. */
     for (;;) {
-      int seed_is_random;
-
       /* step 1 */
       if (!BN_GENCB_call(cb, 0, m++)) {
         goto err;
       }
 
-      if (!seed_len) {
+      int use_random_seed = (seed_in == NULL);
+      if (use_random_seed) {
         if (!RAND_bytes(seed, qsize)) {
           goto err;
         }
-        seed_is_random = 1;
       } else {
-        seed_is_random = 0;
-        seed_len = 0; /* use random seed if 'seed_in' turns out to be bad*/
+        /* If we come back through, use random seed next time. */
+        seed_in = NULL;
       }
       memcpy(buf, seed, qsize);
       memcpy(buf2, seed, qsize);
@@ -570,7 +566,7 @@
       }
 
       /* step 4 */
-      r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb);
+      r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb);
       if (r > 0) {
         break;
       }
diff --git a/src/crypto/ec/CMakeLists.txt b/src/crypto/ec/CMakeLists.txt
index b5ebefa..38a91f8 100644
--- a/src/crypto/ec/CMakeLists.txt
+++ b/src/crypto/ec/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
 
 add_library(
   ec
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index f38eba6..3117f16 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -222,7 +222,11 @@
     {NID_secp224r1, &P224, 0},
     {
         NID_X9_62_prime256v1, &P256,
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
+    /* MSAN appears to have a bug that causes this P-256 code to be miscompiled
+     * in opt mode. While that is being looked at, don't run the uint128_t
+     * P-256 code under MSAN for now. */
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+    !defined(MEMORY_SANITIZER)
         EC_GFp_nistp256_method,
 #else
         0,
@@ -237,18 +241,18 @@
   EC_GROUP *ret;
 
   if (meth == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
+    OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
     return NULL;
   }
 
   if (meth->group_init == 0) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return NULL;
   }
 
   ret = OPENSSL_malloc(sizeof(EC_GROUP));
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
   memset(ret, 0, sizeof(EC_GROUP));
@@ -276,8 +280,7 @@
   }
 
   if (ret->meth->group_set_curve == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
@@ -329,7 +332,7 @@
   EC_GROUP *group = NULL;
   EC_POINT *P = NULL;
   BN_CTX *ctx = NULL;
-  BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
+  BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
   int ok = 0;
   unsigned param_len;
   const EC_METHOD *meth;
@@ -337,7 +340,7 @@
   const uint8_t *params;
 
   if ((ctx = BN_CTX_new()) == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
@@ -348,7 +351,7 @@
   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
 
@@ -356,45 +359,39 @@
     meth = curve->method();
     if (((group = ec_group_new(meth)) == NULL) ||
         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
-      OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
   } else {
     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
-      OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
   }
 
   if ((P = EC_POINT_new(group)) == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
 
   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
 
   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
-  if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
-      !BN_set_word(x, (BN_ULONG)data->cofactor)) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+  if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
+      !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
 
   group->generator = P;
   P = NULL;
-  if (!BN_copy(&group->order, order) ||
-      !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
-    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
-    goto err;
-  }
-
   ok = 1;
 
 err:
@@ -407,7 +404,6 @@
   BN_free(p);
   BN_free(a);
   BN_free(b);
-  BN_free(order);
   BN_free(x);
   BN_free(y);
   return group;
@@ -427,7 +423,7 @@
   }
 
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
+    OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
     return NULL;
   }
 
@@ -455,11 +451,11 @@
 
 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
   if (dest->meth->group_copy == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (dest->meth != src->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   if (dest == src) {
@@ -554,8 +550,7 @@
 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
                            BIGNUM *out_b, BN_CTX *ctx) {
   if (group->meth->group_get_curve == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
@@ -565,8 +560,7 @@
 
 int EC_GROUP_get_degree(const EC_GROUP *group) {
   if (group->meth->group_get_degree == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   return group->meth->group_get_degree(group);
@@ -602,17 +596,17 @@
   EC_POINT *ret;
 
   if (group == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return NULL;
   }
   if (group->meth->point_init == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return NULL;
   }
 
   ret = OPENSSL_malloc(sizeof *ret);
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -653,11 +647,11 @@
 
 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
   if (dest->meth->point_copy == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (dest->meth != src->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   if (dest == src) {
@@ -676,7 +670,7 @@
 
   t = EC_POINT_new(group);
   if (t == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
   r = EC_POINT_copy(t, a);
@@ -690,12 +684,11 @@
 
 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
   if (group->meth->point_set_to_infinity == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->point_set_to_infinity(group, point);
@@ -703,12 +696,11 @@
 
 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
   if (group->meth->is_at_infinity == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->is_at_infinity(group, point);
@@ -717,12 +709,11 @@
 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
                          BN_CTX *ctx) {
   if (group->meth->is_on_curve == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->is_on_curve(group, point, ctx);
@@ -731,11 +722,11 @@
 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
                  BN_CTX *ctx) {
   if (group->meth->point_cmp == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return -1;
   }
   if ((group->meth != a->meth) || (a->meth != b->meth)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return -1;
   }
   return group->meth->point_cmp(group, a, b, ctx);
@@ -743,12 +734,11 @@
 
 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
   if (group->meth->make_affine == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->make_affine(group, point, ctx);
@@ -759,13 +749,12 @@
   size_t i;
 
   if (group->meth->points_make_affine == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   for (i = 0; i < num; i++) {
     if (group->meth != points[i]->meth) {
-      OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+      OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
       return 0;
     }
   }
@@ -776,13 +765,11 @@
                                         const EC_POINT *point, BIGNUM *x,
                                         BIGNUM *y, BN_CTX *ctx) {
   if (group->meth->point_get_affine_coordinates == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
-                      EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
@@ -792,13 +779,11 @@
                                         const BIGNUM *x, const BIGNUM *y,
                                         BN_CTX *ctx) {
   if (group->meth->point_set_affine_coordinates == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
-                      EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
@@ -807,12 +792,12 @@
 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                  const EC_POINT *b, BN_CTX *ctx) {
   if (group->meth->add == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if ((group->meth != r->meth) || (r->meth != a->meth) ||
       (a->meth != b->meth)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->add(group, r, a, b, ctx);
@@ -822,11 +807,11 @@
 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                  BN_CTX *ctx) {
   if (group->meth->dbl == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if ((group->meth != r->meth) || (r->meth != a->meth)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->dbl(group, r, a, ctx);
@@ -835,11 +820,11 @@
 
 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
   if (group->meth->invert == 0) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != a->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->invert(group, a, ctx);
@@ -874,13 +859,11 @@
                                              const BIGNUM *x, const BIGNUM *y,
                                              const BIGNUM *z, BN_CTX *ctx) {
   if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
-    OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
-                      EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index ff3dca6..31d8944 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -168,7 +168,7 @@
   if (ret == NULL) {
     ret = ECPKPARAMETERS_new();
     if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       return NULL;
     }
   } else {
@@ -196,7 +196,7 @@
   int nid = NID_undef;
 
   if (params == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS);
+    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
     return NULL;
   }
 
@@ -222,14 +222,13 @@
   }
 
   if (nid == NID_undef) {
-    OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE);
+    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_asn1_pkparameters2group,
-                      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+    OPENSSL_PUT_ERROR(EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
     return NULL;
   }
 
@@ -243,14 +242,14 @@
 
   params = d2i_ECPKPARAMETERS(NULL, inp, len);
   if (params == NULL) {
-    OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+    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, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE);
+    OPENSSL_PUT_ERROR(EC, EC_R_PKPARAMETERS2GROUP_FAILURE);
     ECPKPARAMETERS_free(params);
     return NULL;
   }
@@ -268,12 +267,12 @@
   int ret = 0;
   ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
   if (tmp == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE);
+    OPENSSL_PUT_ERROR(EC, EC_R_GROUP2PKPARAMETERS_FAILURE);
     return 0;
   }
   ret = i2d_ECPKPARAMETERS(tmp, outp);
   if (ret == 0) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+    OPENSSL_PUT_ERROR(EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
     ECPKPARAMETERS_free(tmp);
     return 0;
   }
@@ -288,14 +287,14 @@
 
   priv_key = d2i_EC_PRIVATEKEY(NULL, in, len);
   if (priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+    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, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       goto err;
     }
   } else {
@@ -308,7 +307,7 @@
   }
 
   if (ret->group == NULL) {
-    OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
 
@@ -319,18 +318,18 @@
         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, d2i_ECPrivateKey, ERR_R_BN_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
       goto err;
     }
   } else {
-    OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY);
+    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PRIVATE_KEY);
     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, d2i_ECPrivateKey, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
 
@@ -342,20 +341,20 @@
     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, d2i_ECPrivateKey, EC_R_BUFFER_TOO_SMALL);
+      OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
       goto err;
     }
     /* Save the point conversion form. */
     ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
     if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
                             NULL)) {
-      OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
   } else {
     if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
                       NULL)) {
-      OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
     /* Remember the original private-key-only encoding. */
@@ -387,13 +386,13 @@
   EC_PRIVATEKEY *priv_key = NULL;
 
   if (key == NULL || key->group == NULL || key->priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     goto err;
   }
 
   priv_key = EC_PRIVATEKEY_new();
   if (priv_key == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
@@ -402,17 +401,17 @@
   buf_len = BN_num_bytes(&key->group->order);
   buffer = OPENSSL_malloc(buf_len);
   if (buffer == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     goto err;
   }
 
   if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
 
   if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
     goto err;
   }
 
@@ -420,7 +419,7 @@
   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, i2d_ECPrivateKey, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
   }
@@ -429,7 +428,7 @@
   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, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       goto err;
     }
 
@@ -439,7 +438,7 @@
     if (tmp_len > buf_len) {
       uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
       if (!tmp_buffer) {
-        OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+        OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
         goto err;
       }
       buffer = tmp_buffer;
@@ -448,21 +447,21 @@
 
     if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
                             buf_len, NULL)) {
-      OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+      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, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
       goto err;
     }
   }
 
   ret = i2d_EC_PRIVATEKEY(priv_key, outp);
   if (ret == 0) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
   ok = 1;
@@ -475,7 +474,7 @@
 
 int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
   if (key == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
   return i2d_ECPKParameters(key->group, outp);
@@ -485,14 +484,14 @@
   EC_KEY *ret;
 
   if (inp == NULL || *inp == NULL) {
-    OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return NULL;
   }
 
   if (key == NULL || *key == NULL) {
     ret = EC_KEY_new();
     if (ret == NULL) {
-      OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       return NULL;
     }
   } else {
@@ -500,7 +499,7 @@
   }
 
   if (!d2i_ECPKParameters(&ret->group, inp, len)) {
-    OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     if (key == NULL || *key == NULL) {
       EC_KEY_free(ret);
     }
@@ -517,17 +516,17 @@
   EC_KEY *ret = NULL;
 
   if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
-    OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
   ret = *keyp;
   if (ret->pub_key == NULL &&
       (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
-    OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return 0;
   }
   if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
-    OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     return 0;
   }
   /* save the point conversion form */
@@ -541,7 +540,7 @@
   int new_buffer = 0;
 
   if (key == NULL) {
-    OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
 
@@ -556,14 +555,14 @@
   if (*outp == NULL) {
     *outp = OPENSSL_malloc(buf_len);
     if (*outp == NULL) {
-      OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE);
+      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
       return 0;
     }
     new_buffer = 1;
   }
   if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
                           buf_len, NULL)) {
-    OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     if (new_buffer) {
       OPENSSL_free(*outp);
       *outp = NULL;
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index e5cbfed..0defa98 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -87,7 +87,7 @@
 EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
   EC_KEY *ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_new_method, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
@@ -127,7 +127,7 @@
 EC_KEY *EC_KEY_new_by_curve_name(int nid) {
   EC_KEY *ret = EC_KEY_new();
   if (ret == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_new_by_curve_name, ERR_R_MALLOC_FAILURE);
+    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
   ret->group = EC_GROUP_new_by_curve_name(nid);
@@ -166,7 +166,7 @@
 
 EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) {
   if (dest == NULL || src == NULL) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_copy, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return NULL;
   }
   /* Copy the parameters. */
@@ -300,12 +300,12 @@
   EC_POINT *point = NULL;
 
   if (!eckey || !eckey->group || !eckey->pub_key) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
 
   if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_AT_INFINITY);
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
     goto err;
   }
 
@@ -319,7 +319,7 @@
 
   /* testing whether the pub_key is on the elliptic curve */
   if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_IS_NOT_ON_CURVE);
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
     goto err;
   }
   /* testing whether pub_key * order is the point at infinity */
@@ -327,15 +327,15 @@
    * to check the private key, below? */
   order = &eckey->group->order;
   if (BN_is_zero(order)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_GROUP_ORDER);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
     goto err;
   }
   if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
     goto err;
   }
   if (!EC_POINT_is_at_infinity(eckey->group, point)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+    OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
     goto err;
   }
   /* in case the priv_key is present :
@@ -343,15 +343,15 @@
    */
   if (eckey->priv_key) {
     if (BN_cmp(eckey->priv_key, order) >= 0) {
-      OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+      OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
       goto err;
     }
     if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
-      OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
       goto err;
     }
     if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
-      OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_PRIVATE_KEY);
+      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY);
       goto err;
     }
   }
@@ -371,8 +371,7 @@
   int ok = 0;
 
   if (!key || !key->group || !x || !y) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
-                      ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
   ctx = BN_CTX_new();
@@ -394,8 +393,7 @@
   /* Check if retrieved coordinates match originals: if not values
    * are out of range. */
   if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
-                      EC_R_COORDINATES_OUT_OF_RANGE);
+    OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
     goto err;
   }
 
@@ -422,7 +420,7 @@
   EC_POINT *pub_key = NULL;
 
   if (!eckey || !eckey->group) {
-    OPENSSL_PUT_ERROR(EC, EC_KEY_generate_key, ERR_R_PASSED_NULL_PARAMETER);
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
     return 0;
   }
 
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 74dbc6c..b897000 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -200,7 +200,7 @@
     goto err;
   }
   if (!BN_MONT_CTX_set(mont, p, ctx)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_group_set_curve, ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     goto err;
   }
   one = BN_new();
@@ -232,7 +232,7 @@
 int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                           const BIGNUM *b, BN_CTX *ctx) {
   if (group->mont == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_mul, EC_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
     return 0;
   }
 
@@ -242,7 +242,7 @@
 int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                           BN_CTX *ctx) {
   if (group->mont == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_sqr, EC_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
     return 0;
   }
 
@@ -252,7 +252,7 @@
 int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                              BN_CTX *ctx) {
   if (group->mont == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_encode, EC_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
     return 0;
   }
 
@@ -262,7 +262,7 @@
 int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                              BN_CTX *ctx) {
   if (group->mont == NULL) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_decode, EC_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
     return 0;
   }
 
@@ -272,7 +272,7 @@
 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_GFp_mont_field_set_to_one, EC_R_NOT_INITIALIZED);
+    OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
     return 0;
   }
 
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index 816a42f..cb50e17 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -85,7 +85,7 @@
 
   if ((form != POINT_CONVERSION_COMPRESSED) &&
       (form != POINT_CONVERSION_UNCOMPRESSED)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_INVALID_FORM);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
     goto err;
   }
 
@@ -93,7 +93,7 @@
     /* encodes to a single 0 octet */
     if (buf != NULL) {
       if (len < 1) {
-        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL);
+        OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
         return 0;
       }
       buf[0] = 0;
@@ -110,7 +110,7 @@
   /* if 'buf' is NULL, just return required length */
   if (buf != NULL) {
     if (len < ret) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL);
+      OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
       goto err;
     }
 
@@ -142,21 +142,21 @@
     i = 1;
 
     if (!BN_bn2bin_padded(buf + i, field_len, x)) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+      OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
       goto err;
     }
     i += field_len;
 
     if (form == POINT_CONVERSION_UNCOMPRESSED) {
       if (!BN_bn2bin_padded(buf + i, field_len, y)) {
-        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+        OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
         goto err;
       }
       i += field_len;
     }
 
     if (i != ret) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+      OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
       goto err;
     }
   }
@@ -187,7 +187,7 @@
   int ret = 0;
 
   if (len == 0) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_BUFFER_TOO_SMALL);
+    OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
     return 0;
   }
   form = buf[0];
@@ -195,17 +195,17 @@
   form = form & ~1U;
   if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
       (form != POINT_CONVERSION_UNCOMPRESSED)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
     return 0;
   }
   if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
     return 0;
   }
 
   if (form == 0) {
     if (len != 1) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
       return 0;
     }
 
@@ -217,7 +217,7 @@
       (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
 
   if (len != enc_len) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
     return 0;
   }
 
@@ -231,7 +231,7 @@
   BN_CTX_start(ctx);
   x = BN_CTX_get(ctx);
   y = BN_CTX_get(ctx);
-  if (y == NULL) {
+  if (x == NULL || y == NULL) {
     goto err;
   }
 
@@ -239,7 +239,7 @@
     goto err;
   }
   if (BN_ucmp(x, &group->field) >= 0) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
     goto err;
   }
 
@@ -252,7 +252,7 @@
       goto err;
     }
     if (BN_ucmp(y, &group->field) >= 0) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
       goto err;
     }
 
@@ -263,7 +263,7 @@
 
   /* test required by X9.62 */
   if (!EC_POINT_is_on_curve(group, point, ctx)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_POINT_IS_NOT_ON_CURVE);
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
     goto err;
   }
 
@@ -279,12 +279,11 @@
                        const uint8_t *buf, size_t len, BN_CTX *ctx) {
   if (group->meth->oct2point == 0 &&
       !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
@@ -299,12 +298,11 @@
                           size_t len, BN_CTX *ctx) {
   if (group->meth->point2oct == 0 &&
       !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct, EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
@@ -406,9 +404,9 @@
     if (ERR_GET_LIB(err) == ERR_LIB_BN &&
         ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
       ERR_clear_error();
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, EC_R_INVALID_COMPRESSED_POINT);
+      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
     } else {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, ERR_R_BN_LIB);
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     }
     goto err;
   }
@@ -423,12 +421,10 @@
       }
 
       if (kron == 1) {
-        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
-                          EC_R_INVALID_COMPRESSION_BIT);
+        OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
       } else {
         /* BN_mod_sqrt() should have cought this error (not a square) */
-        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
-                          EC_R_INVALID_COMPRESSED_POINT);
+        OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
       }
       goto err;
     }
@@ -437,8 +433,7 @@
     }
   }
   if (y_bit != BN_is_odd(y)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
-                      ERR_R_INTERNAL_ERROR);
+    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
     goto err;
   }
 
@@ -459,13 +454,11 @@
                                             int y_bit, BN_CTX *ctx) {
   if (group->meth->point_set_compressed_coordinates == 0 &&
       !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
-                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return 0;
   }
   if (group->meth != point->meth) {
-    OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
-                      EC_R_INCOMPATIBLE_OBJECTS);
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
     return 0;
   }
   if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index fdb942c..3946b29 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -125,7 +125,7 @@
 /* BN_to_felem converts an OpenSSL BIGNUM into an felem. */
 static int BN_to_felem(felem out, const BIGNUM *bn) {
   if (BN_is_negative(bn)) {
-    OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+    OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
     return 0;
   }
 
@@ -134,7 +134,7 @@
   memset(b_out, 0, sizeof(b_out));
   unsigned num_bytes = BN_num_bytes(bn);
   if (num_bytes > sizeof(b_out)) {
-    OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+    OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
     return 0;
   }
 
@@ -1638,8 +1638,7 @@
   if (BN_cmp(curve_p, p) ||
       BN_cmp(curve_a, a) ||
       BN_cmp(curve_b, b)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_group_set_curve,
-                      EC_R_WRONG_CURVE_PARAMETERS);
+    OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
     goto err;
   }
   ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
@@ -1661,8 +1660,7 @@
   longfelem tmp;
 
   if (EC_POINT_is_at_infinity(group, point)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
-                      EC_R_POINT_AT_INFINITY);
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
     return 0;
   }
   if (!BN_to_felem(x_in, &point->X) ||
@@ -1677,8 +1675,7 @@
   felem_reduce(x_in, tmp);
   felem_contract(x_out, x_in);
   if (x != NULL && !smallfelem_to_BN(x, x_out)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
-                      ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     return 0;
   }
   felem_mul(tmp, z1, z2);
@@ -1687,8 +1684,7 @@
   felem_reduce(y_in, tmp);
   felem_contract(y_out, y_in);
   if (y != NULL && !smallfelem_to_BN(y, y_out)) {
-    OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
-                      ERR_R_BN_LIB);
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
     return 0;
   }
   return 1;
@@ -1763,7 +1759,7 @@
     if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
         !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
         !smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
-      OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+      OPENSSL_PUT_ERROR(EC,