Add visibility rules.

This change marks public symbols as dynamically exported. This means
that it becomes viable to build a shared library of libcrypto and libssl
with -fvisibility=hidden.

On Windows, one not only needs to mark functions for export in a
component, but also for import when using them from a different
component. Because of this we have to build with
|BORINGSSL_IMPLEMENTATION| defined when building the code. Other
components, when including our headers, won't have that defined and then
the |OPENSSL_EXPORT| tag becomes an import tag instead. See the #defines
in base.h

In the asm code, symbols are now hidden by default and those that need
to be exported are wrapped by a C function.

In order to support Chromium, a couple of libssl functions were moved to
ssl.h from ssl_locl.h: ssl_get_new_session and ssl_update_cache.

Change-Id: Ib4b76e2f1983ee066e7806c24721e8626d08a261
Reviewed-on: https://boringssl-review.googlesource.com/1350
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/BUILDING b/BUILDING
index b8cd5f6..68184dd 100644
--- a/BUILDING
+++ b/BUILDING
@@ -22,4 +22,11 @@
 
 cmake -DCMAKE_TOOLCHAIN_FILE=../util/arm-toolchain.cmake -GNinja ..
 
+If you want to build as a shared library you need to tweak the STATIC tags in
+the CMakeLists.txts and also define BORINGSSL_SHARED_LIBRARY and
+BORINGSSL_IMPLEMENTATION. On Windows, where functions need to be tagged with
+"dllimport" when coming from a shared library, you need just
+BORINGSSL_SHARED_LIBRARY defined in the code which #includes the BoringSSL
+headers.
+
 [1] http://martine.github.io/ninja/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1e0ab07..d8a4e1b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,6 +10,8 @@
 	set(CMAKE_C_FLAGS "/wd4267")
 endif()
 
+add_definitions(-DBORINGSSL_IMPLEMENTATION)
+
 if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
 	set(ARCH "x86_64")
 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
diff --git a/crypto/aes/aes.c b/crypto/aes/aes.c
index cdeaef7..c47fe88 100644
--- a/crypto/aes/aes.c
+++ b/crypto/aes/aes.c
@@ -1073,4 +1073,31 @@
   PUTU32(out + 12, s3);
 }
 
-#endif
+#else
+
+/* In this case several functions are provided by asm code. However, one cannot
+ * control asm symbol visibility with command line flags and such so they are
+ * always hidden and wrapped by these C functions, which can be so
+ * controlled. */
+
+void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+  asm_AES_encrypt(in, out, key);
+}
+
+void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+  asm_AES_decrypt(in, out, key);
+}
+
+int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
+int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  return asm_AES_set_encrypt_key(key, bits, aeskey);
+}
+
+int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
+int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  return asm_AES_set_decrypt_key(key, bits, aeskey);
+}
+
+#endif  /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */
diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl
index 1c1e23e..07fb94c 100755
--- a/crypto/aes/asm/aes-586.pl
+++ b/crypto/aes/asm/aes-586.pl
@@ -1161,8 +1161,8 @@
 	&data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
 &function_end_B("_x86_AES_encrypt");
 
-# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-&function_begin("AES_encrypt");
+# void asm_AES_encrypt (const void *inp,void *out,const AES_KEY *key);
+&function_begin("asm_AES_encrypt");
 	&mov	($acc,&wparam(0));		# load inp
 	&mov	($key,&wparam(2));		# load key
 
@@ -1218,7 +1218,7 @@
 	&mov	(&DWP(4,$acc),$s1);
 	&mov	(&DWP(8,$acc),$s2);
 	&mov	(&DWP(12,$acc),$s3);
-&function_end("AES_encrypt");
+&function_end("asm_AES_encrypt");
 
 #--------------------------------------------------------------------#
 
@@ -1952,8 +1952,8 @@
 	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
 &function_end_B("_x86_AES_decrypt");
 
-# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-&function_begin("AES_decrypt");
+# void asm_AES_decrypt (const void *inp,void *out,const AES_KEY *key);
+&function_begin("asm_AES_decrypt");
 	&mov	($acc,&wparam(0));		# load inp
 	&mov	($key,&wparam(2));		# load key
 
@@ -2009,11 +2009,11 @@
 	&mov	(&DWP(4,$acc),$s1);
 	&mov	(&DWP(8,$acc),$s2);
 	&mov	(&DWP(12,$acc),$s3);
-&function_end("AES_decrypt");
+&function_end("asm_AES_decrypt");
 
-# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-#			size_t length, const AES_KEY *key,
-#			unsigned char *ivp,const int enc);
+# void asm_AES_cbc_encrypt (const void char *inp, unsigned char *out,
+#			    size_t length, const AES_KEY *key,
+#			    unsigned char *ivp,const int enc);
 {
 # stack frame layout
 #             -4(%esp)		# return address	 0(%esp)
@@ -2036,7 +2036,7 @@
 my $aes_key=&DWP(76,"esp");	# copy of aes_key
 my $mark=&DWP(76+240,"esp");	# copy of aes_key->rounds
 
-&function_begin("AES_cbc_encrypt");
+&function_begin("asm_AES_cbc_encrypt");
 	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
 	&cmp	($s2,0);
 	&je	(&label("drop_out"));
@@ -2627,7 +2627,7 @@
 
 	&mov	("esp",$_esp);
 	&popf	();
-&function_end("AES_cbc_encrypt");
+&function_end("asm_AES_cbc_encrypt");
 }
 
 #------------------------------------------------------------------#
@@ -2861,12 +2861,12 @@
     &set_label("exit");
 &function_end("_x86_AES_set_encrypt_key");
 
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-&function_begin_B("AES_set_encrypt_key");
+# int asm_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+#                             AES_KEY *key)
+&function_begin_B("asm_AES_set_encrypt_key");
 	&call	("_x86_AES_set_encrypt_key");
 	&ret	();
-&function_end_B("AES_set_encrypt_key");
+&function_end_B("asm_AES_set_encrypt_key");
 
 sub deckey()
 { my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
@@ -2923,9 +2923,9 @@
 	&mov	(&DWP(4*$i,$key),$tp1);
 }
 
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-&function_begin_B("AES_set_decrypt_key");
+# int asm_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+#                             AES_KEY *key)
+&function_begin_B("asm_AES_set_decrypt_key");
 	&call	("_x86_AES_set_encrypt_key");
 	&cmp	("eax",0);
 	&je	(&label("proceed"));
@@ -2981,7 +2981,7 @@
 	&jb	(&label("permute"));
 
 	&xor	("eax","eax");			# return success
-&function_end("AES_set_decrypt_key");
+&function_end("asm_AES_set_decrypt_key");
 &asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
 
 &asm_finish();
diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl
index 38a3f6a..3bd9a6d 100644
--- a/crypto/aes/asm/aes-armv4.pl
+++ b/crypto/aes/asm/aes-armv4.pl
@@ -176,21 +176,22 @@
 .word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
 .size	AES_Te,.-AES_Te
 
-@ void AES_encrypt(const unsigned char *in, unsigned char *out,
-@ 		 const AES_KEY *key) {
-.global AES_encrypt
-.type   AES_encrypt,%function
+@ void asm_AES_encrypt(const unsigned char *in, unsigned char *out,
+@ 		       const AES_KEY *key) {
+.global asm_AES_encrypt
+.hidden asm_AES_encrypt
+.type   asm_AES_encrypt,%function
 .align	5
-AES_encrypt:
+asm_AES_encrypt:
 #if __ARM_ARCH__<7
-	sub	r3,pc,#8		@ AES_encrypt
+	sub	r3,pc,#8		@ asm_AES_encrypt
 #else
-	adr	r3,AES_encrypt
+	adr	r3,asm_AES_encrypt
 #endif
 	stmdb   sp!,{r1,r4-r12,lr}
 	mov	$rounds,r0		@ inp
 	mov	$key,r2
-	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
+	sub	$tbl,r3,#asm_AES_encrypt-AES_Te	@ Te
 #if __ARM_ARCH__<7
 	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
 	ldrb	$t1,[$rounds,#2]	@ manner...
@@ -284,7 +285,7 @@
 	moveq	pc,lr			@ be binary compatible with V4, yet
 	bx	lr			@ interoperable with Thumb ISA:-)
 #endif
-.size	AES_encrypt,.-AES_encrypt
+.size	asm_AES_encrypt,.-asm_AES_encrypt
 
 .type   _armv4_AES_encrypt,%function
 .align	2
@@ -423,15 +424,16 @@
 	ldr	pc,[sp],#4		@ pop and return
 .size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
 
-.global AES_set_encrypt_key
-.type   AES_set_encrypt_key,%function
+.global asm_AES_set_encrypt_key
+.hidden asm_AES_set_encrypt_key
+.type   asm_AES_set_encrypt_key,%function
 .align	5
-AES_set_encrypt_key:
+asm_AES_set_encrypt_key:
 _armv4_AES_set_encrypt_key:
 #if __ARM_ARCH__<7
-	sub	r3,pc,#8		@ AES_set_encrypt_key
+	sub	r3,pc,#8		@ asm_AES_set_encrypt_key
 #else
-	adr	r3,AES_set_encrypt_key
+	adr	r3,asm_AES_set_encrypt_key
 #endif
 	teq	r0,#0
 #if __ARM_ARCH__>=7
@@ -723,25 +725,27 @@
 	moveq	pc,lr			@ be binary compatible with V4, yet
 	bx	lr			@ interoperable with Thumb ISA:-)
 #endif
-.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+.size	asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
 
-.global AES_set_decrypt_key
-.type   AES_set_decrypt_key,%function
+.global asm_AES_set_decrypt_key
+.hidden asm_AES_set_decrypt_key
+.type   asm_AES_set_decrypt_key,%function
 .align	5
-AES_set_decrypt_key:
+asm_AES_set_decrypt_key:
 	str	lr,[sp,#-4]!            @ push lr
 	bl	_armv4_AES_set_encrypt_key
 	teq	r0,#0
 	ldr	lr,[sp],#4              @ pop lr
 	bne	.Labrt
 
-	mov	r0,r2			@ AES_set_encrypt_key preserves r2,
+	mov	r0,r2			@ asm_AES_set_encrypt_key preserves r2,
 	mov	r1,r2			@ which is AES_KEY *key
 	b	_armv4_AES_set_enc2dec_key
-.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+.size	asm_AES_set_decrypt_key,.-asm_AES_set_decrypt_key
 
 @ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
 .global	AES_set_enc2dec_key
+.hidden	AES_set_enc2dec_key
 .type	AES_set_enc2dec_key,%function
 .align	5
 AES_set_enc2dec_key:
@@ -944,21 +948,22 @@
 .byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
 .size	AES_Td,.-AES_Td
 
-@ void AES_decrypt(const unsigned char *in, unsigned char *out,
-@ 		 const AES_KEY *key) {
-.global AES_decrypt
-.type   AES_decrypt,%function
+@ void asm_AES_decrypt(const unsigned char *in, unsigned char *out,
+@ 		       const AES_KEY *key) {
+.global asm_AES_decrypt
+.hidden asm_AES_decrypt
+.type   asm_AES_decrypt,%function
 .align	5
-AES_decrypt:
+asm_AES_decrypt:
 #if __ARM_ARCH__<7
-	sub	r3,pc,#8		@ AES_decrypt
+	sub	r3,pc,#8		@ asm_AES_decrypt
 #else
-	adr	r3,AES_decrypt
+	adr	r3,asm_AES_decrypt
 #endif
 	stmdb   sp!,{r1,r4-r12,lr}
 	mov	$rounds,r0		@ inp
 	mov	$key,r2
-	sub	$tbl,r3,#AES_decrypt-AES_Td		@ Td
+	sub	$tbl,r3,#asm_AES_decrypt-AES_Td		@ Td
 #if __ARM_ARCH__<7
 	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
 	ldrb	$t1,[$rounds,#2]	@ manner...
@@ -1052,7 +1057,7 @@
 	moveq	pc,lr			@ be binary compatible with V4, yet
 	bx	lr			@ interoperable with Thumb ISA:-)
 #endif
-.size	AES_decrypt,.-AES_decrypt
+.size	asm_AES_decrypt,.-asm_AES_decrypt
 
 .type   _armv4_AES_decrypt,%function
 .align	2
diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl
index e2a1246..08785fe 100644
--- a/crypto/aes/asm/aes-x86_64.pl
+++ b/crypto/aes/asm/aes-x86_64.pl
@@ -583,15 +583,12 @@
 .size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
 ___
 
-# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
+# void asm_AES_encrypt (const void *inp,void *out,const AES_KEY *key);
 $code.=<<___;
-.globl	AES_encrypt
-.type	AES_encrypt,\@function,3
 .align	16
 .globl	asm_AES_encrypt
 .hidden	asm_AES_encrypt
 asm_AES_encrypt:
-AES_encrypt:
 	push	%rbx
 	push	%rbp
 	push	%r12
@@ -651,7 +648,7 @@
 	lea	48(%rsi),%rsp
 .Lenc_epilogue:
 	ret
-.size	AES_encrypt,.-AES_encrypt
+.size	asm_AES_encrypt,.-asm_AES_encrypt
 ___
 
 #------------------------------------------------------------------#
@@ -1181,15 +1178,12 @@
 .size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
 ___
 
-# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
+# void asm_AES_decrypt (const void *inp,void *out,const AES_KEY *key);
 $code.=<<___;
-.globl	AES_decrypt
-.type	AES_decrypt,\@function,3
 .align	16
 .globl	asm_AES_decrypt
 .hidden	asm_AES_decrypt
 asm_AES_decrypt:
-AES_decrypt:
 	push	%rbx
 	push	%rbp
 	push	%r12
@@ -1251,7 +1245,7 @@
 	lea	48(%rsi),%rsp
 .Ldec_epilogue:
 	ret
-.size	AES_decrypt,.-AES_decrypt
+.size	asm_AES_decrypt,.-asm_AES_decrypt
 ___
 #------------------------------------------------------------------#
 
@@ -1282,12 +1276,11 @@
 ___
 }
 
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
+# int asm_AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
 $code.=<<___;
-.globl	AES_set_encrypt_key
-.type	AES_set_encrypt_key,\@function,3
 .align	16
-AES_set_encrypt_key:
+.globl asm_AES_set_encrypt_key
+asm_AES_set_encrypt_key:
 	push	%rbx
 	push	%rbp
 	push	%r12			# redundant, but allows to share 
@@ -1304,7 +1297,7 @@
 	add	\$56,%rsp
 .Lenc_key_epilogue:
 	ret
-.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+.size asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
 
 .type	_x86_64_AES_set_encrypt_key,\@abi-omnipotent
 .align	16
@@ -1547,12 +1540,11 @@
 ___
 }
 
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
+# int asm_AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
 $code.=<<___;
-.globl	AES_set_decrypt_key
-.type	AES_set_decrypt_key,\@function,3
 .align	16
-AES_set_decrypt_key:
+.globl asm_AES_set_decrypt_key
+asm_AES_set_decrypt_key:
 	push	%rbx
 	push	%rbp
 	push	%r12
@@ -1621,12 +1613,12 @@
 	add	\$56,%rsp
 .Ldec_key_epilogue:
 	ret
-.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+.size	asm_AES_set_decrypt_key,.-asm_AES_set_decrypt_key
 ___
 
-# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-#			size_t length, const AES_KEY *key,
-#			unsigned char *ivp,const int enc);
+# void asm_AES_cbc_encrypt (const void char *inp, unsigned char *out,
+#			    size_t length, const AES_KEY *key,
+#			    unsigned char *ivp,const int enc);
 {
 # stack frame layout
 # -8(%rsp)		return address
@@ -1643,14 +1635,11 @@
 my $mark="80+240(%rsp)";	# copy of aes_key->rounds
 
 $code.=<<___;
-.globl	AES_cbc_encrypt
-.type	AES_cbc_encrypt,\@function,6
 .align	16
 .extern	OPENSSL_ia32cap_P
 .globl	asm_AES_cbc_encrypt
 .hidden	asm_AES_cbc_encrypt
 asm_AES_cbc_encrypt:
-AES_cbc_encrypt:
 	cmp	\$0,%rdx	# check length
 	je	.Lcbc_epilogue
 	pushfq
@@ -2099,7 +2088,7 @@
 	popfq
 .Lcbc_epilogue:
 	ret
-.size	AES_cbc_encrypt,.-AES_cbc_encrypt
+.size	asm_AES_cbc_encrypt,.-asm_AES_cbc_encrypt
 ___
 }
 
diff --git a/crypto/aes/asm/bsaes-armv7.pl b/crypto/aes/asm/bsaes-armv7.pl
index 3da8542..d70f3ea 100644
--- a/crypto/aes/asm/bsaes-armv7.pl
+++ b/crypto/aes/asm/bsaes-armv7.pl
@@ -981,6 +981,7 @@
 			# used for benchmarking...
 $code.=<<___;
 .globl	bsaes_enc_key_convert
+.hidden	bsaes_enc_key_convert
 .type	bsaes_enc_key_convert,%function
 .align	4
 bsaes_enc_key_convert:
@@ -999,6 +1000,7 @@
 .size	bsaes_enc_key_convert,.-bsaes_enc_key_convert
 
 .globl	bsaes_encrypt_128
+.hidden	bsaes_encrypt_128
 .type	bsaes_encrypt_128,%function
 .align	4
 bsaes_encrypt_128:
@@ -1029,6 +1031,7 @@
 .size	bsaes_encrypt_128,.-bsaes_encrypt_128
 
 .globl	bsaes_dec_key_convert
+.hidden	bsaes_dec_key_convert
 .type	bsaes_dec_key_convert,%function
 .align	4
 bsaes_dec_key_convert:
@@ -1049,6 +1052,7 @@
 .size	bsaes_dec_key_convert,.-bsaes_dec_key_convert
 
 .globl	bsaes_decrypt_128
+.hidden	bsaes_decrypt_128
 .type	bsaes_decrypt_128,%function
 .align	4
 bsaes_decrypt_128:
@@ -1088,6 +1092,7 @@
 .extern AES_decrypt
 
 .global	bsaes_cbc_encrypt
+.hidden	bsaes_cbc_encrypt
 .type	bsaes_cbc_encrypt,%function
 .align	5
 bsaes_cbc_encrypt:
@@ -1363,6 +1368,7 @@
 $code.=<<___;
 .extern	AES_encrypt
 .global	bsaes_ctr32_encrypt_blocks
+.hidden	bsaes_ctr32_encrypt_blocks
 .type	bsaes_ctr32_encrypt_blocks,%function
 .align	5
 bsaes_ctr32_encrypt_blocks:
@@ -1594,6 +1600,7 @@
 
 $code.=<<___;
 .globl	bsaes_xts_encrypt
+.hidden	bsaes_xts_encrypt
 .type	bsaes_xts_encrypt,%function
 .align	4
 bsaes_xts_encrypt:
@@ -2008,6 +2015,7 @@
 .size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
 
 .globl	bsaes_xts_decrypt
+.hidden	bsaes_xts_decrypt
 .type	bsaes_xts_decrypt,%function
 .align	4
 bsaes_xts_decrypt:
diff --git a/crypto/aes/mode_wrappers.c b/crypto/aes/mode_wrappers.c
index 0ee2326..c706896 100644
--- a/crypto/aes/mode_wrappers.c
+++ b/crypto/aes/mode_wrappers.c
@@ -83,7 +83,16 @@
     CRYPTO_cbc128_decrypt(in, out, len, key, ivec, (block128_f)AES_decrypt);
   }
 }
-#endif
+#else
+
+void asm_AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+                         const AES_KEY *key, uint8_t *ivec, const int enc);
+void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+                     const AES_KEY *key, uint8_t *ivec, const int enc) {
+  asm_AES_cbc_encrypt(in, out, len, key, ivec, enc);
+}
+
+#endif  /* OPENSSL_NO_ASM || (!OPENSSL_X86_64 && !OPENSSL_X86) */
 
 void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
                         const AES_KEY *key, uint8_t *ivec, int *num) {
diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index f4dcb09..83816c9 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -58,6 +58,7 @@
 
 #include <limits.h>
 
+#include <openssl/asn1_mac.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
diff --git a/crypto/bn/asm/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl
index fe81f9b..5cc1328 100644
--- a/crypto/bn/asm/armv4-mont.pl
+++ b/crypto/bn/asm/armv4-mont.pl
@@ -79,6 +79,7 @@
 #endif
 
 .global	bn_mul_mont
+.hidden	bn_mul_mont
 .type	bn_mul_mont,%function
 
 .align	5
diff --git a/crypto/chacha/chacha_vec_arm.S b/crypto/chacha/chacha_vec_arm.S
index d82e6ee..be87ab3 100644
--- a/crypto/chacha/chacha_vec_arm.S
+++ b/crypto/chacha/chacha_vec_arm.S
@@ -51,6 +51,7 @@
 	.text
 	.align	2
 	.global	CRYPTO_chacha_20_neon
+	.hidden	CRYPTO_chacha_20_neon
 	.thumb
 	.thumb_func
 	.type	CRYPTO_chacha_20_neon, %function
diff --git a/crypto/directory.h b/crypto/directory.h
index e54df3c..29123ea 100644
--- a/crypto/directory.h
+++ b/crypto/directory.h
@@ -51,11 +51,12 @@
  * same |*ctx| will return subsequent file names until it returns NULL to
  * indicate EOF. The strings returned reference a buffer internal to the
  * |OPENSSL_DIR_CTX| and will be overridden by subsequent calls. */
-const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory);
+OPENSSL_EXPORT const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
+                                            const char *directory);
 
 /* OPENSSL_DIR_end closes |*ctx|. It returns one on success and zero on
  * error. */
-int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
+OPENSSL_EXPORT int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
 
 
 #if defined(__cplusplus)
diff --git a/crypto/modes/asm/ghash-armv4.pl b/crypto/modes/asm/ghash-armv4.pl
index cf5fe8d..a8d6b2e 100644
--- a/crypto/modes/asm/ghash-armv4.pl
+++ b/crypto/modes/asm/ghash-armv4.pl
@@ -145,6 +145,7 @@
 .size	rem_4bit_get,.-rem_4bit_get
 
 .global	gcm_ghash_4bit
+.hidden	gcm_ghash_4bit
 .type	gcm_ghash_4bit,%function
 gcm_ghash_4bit:
 	sub	r12,pc,#8
@@ -241,6 +242,7 @@
 .size	gcm_ghash_4bit,.-gcm_ghash_4bit
 
 .global	gcm_gmult_4bit
+.hidden	gcm_gmult_4bit
 .type	gcm_gmult_4bit,%function
 gcm_gmult_4bit:
 	stmdb	sp!,{r4-r11,lr}
@@ -370,6 +372,7 @@
 .fpu	neon
 
 .global	gcm_init_neon
+.hidden	gcm_init_neon
 .type	gcm_init_neon,%function
 .align	4
 gcm_init_neon:
@@ -391,6 +394,7 @@
 .size	gcm_init_neon,.-gcm_init_neon
 
 .global	gcm_gmult_neon
+.hidden	gcm_gmult_neon
 .type	gcm_gmult_neon,%function
 .align	4
 gcm_gmult_neon:
@@ -409,6 +413,7 @@
 .size	gcm_gmult_neon,.-gcm_gmult_neon
 
 .global	gcm_ghash_neon
+.hidden	gcm_ghash_neon
 .type	gcm_ghash_neon,%function
 .align	4
 gcm_ghash_neon:
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 686809b..e0695e0 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -521,6 +521,12 @@
 		    }
 		} elsif ($dir =~ /\.(text|data)/) {
 		    $current_segment=".$1";
+		} elsif ($dir =~ /\.global|\.globl|\.extern/) {
+		    if ($flavour eq "macosx") {
+		        $self->{value} .= "\n.private_extern $line";
+		    } else {
+		        $self->{value} .= "\n.hidden $line";
+		    }
 		} elsif ($dir =~ /\.hidden/) {
 		    if    ($flavour eq "macosx")  { $self->{value} = ".private_extern\t$prefix$line"; }
 		    elsif ($flavour eq "mingw64") { $self->{value} = ""; }
diff --git a/crypto/perlasm/x86gas.pl b/crypto/perlasm/x86gas.pl
index 167c615..99d7c1b 100644
--- a/crypto/perlasm/x86gas.pl
+++ b/crypto/perlasm/x86gas.pl
@@ -108,6 +108,11 @@
     $func=$nmdecor.$func;
 
     push(@out,".globl\t$func\n")	if ($global);
+    if ($::macosx) {
+      push(@out,".private_extern\t$func\n");
+    } else {
+      push(@out,".hidden\t$func\n");
+    }
     if ($::coff)
     {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
     elsif (($::aout and !$::pic) or $::macosx)
diff --git a/crypto/poly1305/poly1305_arm_asm.S b/crypto/poly1305/poly1305_arm_asm.S
index e196e57..9cf7656 100644
--- a/crypto/poly1305/poly1305_arm_asm.S
+++ b/crypto/poly1305/poly1305_arm_asm.S
@@ -154,6 +154,7 @@
 # qhasm: qpushenter crypto_onetimeauth_poly1305_neon2_blocks
 .align 4
 .global openssl_poly1305_neon2_blocks
+.hidden openssl_poly1305_neon2_blocks
 .type openssl_poly1305_neon2_blocks STT_FUNC
 openssl_poly1305_neon2_blocks:
 vpush {q4,q5,q6,q7}
@@ -1612,6 +1613,7 @@
 # qhasm: enter crypto_onetimeauth_poly1305_neon2_addmulmod
 .align 2
 .global openssl_poly1305_neon2_addmulmod
+.hidden openssl_poly1305_neon2_addmulmod
 .type openssl_poly1305_neon2_addmulmod STT_FUNC
 openssl_poly1305_neon2_addmulmod:
 sub sp,sp,#0
diff --git a/crypto/rc4/asm/rc4-586.pl b/crypto/rc4/asm/rc4-586.pl
index e3f3b04..fc860ae 100644
--- a/crypto/rc4/asm/rc4-586.pl
+++ b/crypto/rc4/asm/rc4-586.pl
@@ -152,8 +152,8 @@
 
 &external_label("OPENSSL_ia32cap_P");
 
-# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
-&function_begin("RC4");
+# void asm_RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
+&function_begin("asm_RC4");
 	&mov	($dat,&wparam(0));	# load key schedule pointer
 	&mov	($ty, &wparam(1));	# load len
 	&mov	($inp,&wparam(2));	# load inp
@@ -293,7 +293,7 @@
 	&mov	(&DWP(-4,$dat),$yy);		# save key->y
 	&mov	(&BP(-8,$dat),&LB($xx));	# save key->x
 &set_label("abort");
-&function_end("RC4");
+&function_end("asm_RC4");
 
 ########################################################################
 
@@ -303,8 +303,8 @@
 $ido="ecx";
 $idx="edx";
 
-# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
-&function_begin("RC4_set_key");
+# void asm_RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
+&function_begin("asm_RC4_set_key");
 	&mov	($out,&wparam(0));		# load key
 	&mov	($idi,&wparam(1));		# load len
 	&mov	($inp,&wparam(2));		# load data
@@ -382,7 +382,7 @@
 	&xor	("eax","eax");
 	&mov	(&DWP(-8,$out),"eax");		# key->x=0;
 	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
-&function_end("RC4_set_key");
+&function_end("asm_RC4_set_key");
 
 # const char *RC4_options(void);
 &function_begin_B("RC4_options");
diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl
index a5b2216..797ae13 100644
--- a/crypto/rc4/asm/rc4-x86_64.pl
+++ b/crypto/rc4/asm/rc4-x86_64.pl
@@ -125,10 +125,11 @@
 .text
 .extern	OPENSSL_ia32cap_P
 
-.globl	RC4
-.type	RC4,\@function,4
+.globl	asm_RC4
+.type	asm_RC4,\@function,4
 .align	16
-RC4:	or	$len,$len
+asm_RC4:
+	or	$len,$len
 	jne	.Lentry
 	ret
 .Lentry:
@@ -423,7 +424,7 @@
 	add	\$24,%rsp
 .Lepilogue:
 	ret
-.size	RC4,.-RC4
+.size	asm_RC4,.-asm_RC4
 ___
 }
 
@@ -431,10 +432,10 @@
 $ido="%r9";
 
 $code.=<<___;
-.globl	RC4_set_key
-.type	RC4_set_key,\@function,3
+.globl	asm_RC4_set_key
+.type	asm_RC4_set_key,\@function,3
 .align	16
-RC4_set_key:
+asm_RC4_set_key:
 	lea	8($dat),$dat
 	lea	($inp,$len),$inp
 	neg	$len
@@ -502,7 +503,7 @@
 	mov	%eax,-8($dat)
 	mov	%eax,-4($dat)
 	ret
-.size	RC4_set_key,.-RC4_set_key
+.size	asm_RC4_set_key,.-asm_RC4_set_key
 
 .globl	RC4_options
 .type	RC4_options,\@abi-omnipotent
diff --git a/crypto/rc4/rc4.c b/crypto/rc4/rc4.c
index a93f96e..ec3de23 100644
--- a/crypto/rc4/rc4.c
+++ b/crypto/rc4/rc4.c
@@ -345,4 +345,21 @@
   }
 }
 
-#endif
+#else
+
+/* In this case several functions are provided by asm code. However, one cannot
+ * control asm symbol visibility with command line flags and such so they are
+ * always hidden and wrapped by these C functions, which can be so
+ * controlled. */
+
+void asm_RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out);
+void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) {
+  asm_RC4(key, len, in, out);
+}
+
+void asm_RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key);
+void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) {
+  RC4_set_key(rc4key, len, key);
+}
+
+#endif  /* OPENSSL_NO_ASM || (!OPENSSL_X86_64 && !OPENSSL_X86) */
diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl
index 6643731..c84b548 100644
--- a/crypto/sha/asm/sha1-armv4-large.pl
+++ b/crypto/sha/asm/sha1-armv4-large.pl
@@ -156,6 +156,7 @@
 .text
 
 .global	sha1_block_data_order
+.hidden	sha1_block_data_order
 .type	sha1_block_data_order,%function
 
 .align	2
diff --git a/crypto/sha/asm/sha256-armv4.pl b/crypto/sha/asm/sha256-armv4.pl
index 1b2a098..ff99037 100644
--- a/crypto/sha/asm/sha256-armv4.pl
+++ b/crypto/sha/asm/sha256-armv4.pl
@@ -179,6 +179,7 @@
 .align	5
 
 .global	sha256_block_data_order
+.hidden	sha256_block_data_order
 .type	sha256_block_data_order,%function
 sha256_block_data_order:
 	sub	r3,pc,#8		@ sha256_block_data_order
diff --git a/crypto/sha/asm/sha512-armv4.pl b/crypto/sha/asm/sha512-armv4.pl
index ae2cbfc..0524b8e 100644
--- a/crypto/sha/asm/sha512-armv4.pl
+++ b/crypto/sha/asm/sha512-armv4.pl
@@ -243,6 +243,7 @@
 .skip	32-4
 
 .global	sha512_block_data_order
+.hidden	sha512_block_data_order
 .type	sha512_block_data_order,%function
 sha512_block_data_order:
 	sub	r3,pc,#8		@ sha512_block_data_order
diff --git a/include/openssl/aead.h b/include/openssl/aead.h
index 0531ad9..eb2194a 100644
--- a/include/openssl/aead.h
+++ b/include/openssl/aead.h
@@ -93,13 +93,13 @@
 /* AEAD algorithms. */
 
 /* EVP_aes_128_gcm is AES-128 in Galois Counter Mode. */
-const EVP_AEAD *EVP_aead_aes_128_gcm(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
 
 /* EVP_aes_256_gcm is AES-256 in Galois Counter Mode. */
-const EVP_AEAD *EVP_aead_aes_256_gcm(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
 
 /* EVP_aead_chacha20_poly1305 is an AEAD built from ChaCha20 and Poly1305. */
-const EVP_AEAD *EVP_aead_chacha20_poly1305();
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305();
 
 /* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
  * used except to interoperate with existing systems that use this mode.
@@ -107,13 +107,13 @@
  * If the nonce is emtpy then the default nonce will be used, otherwise it must
  * be eight bytes long. The input must be a multiple of eight bytes long. No
  * additional data can be given to this mode. */
-const EVP_AEAD *EVP_aead_aes_128_key_wrap();
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_key_wrap();
 
 /* EVP_aead_aes_256_key_wrap is AES-256 in Key Wrap mode. This should never be
  * used except to interoperate with existing systems that use this mode.
  *
  * See |EVP_aead_aes_128_key_wrap| for details. */
-const EVP_AEAD *EVP_aead_aes_256_key_wrap();
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_key_wrap();
 
 
 /* TLS specific AEAD algorithms.
@@ -125,27 +125,27 @@
 /* EVP_aead_rc4_md5_tls uses RC4 and HMAC(MD5) in MAC-then-encrypt mode. Unlike
  * a standard AEAD, this is stateful as the RC4 state is carried from operation
  * to operation. */
-const EVP_AEAD *EVP_aead_rc4_md5_tls();
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls();
 
 
 /* Utility functions. */
 
 /* EVP_AEAD_key_length returns the length, in bytes, of the keys used by
  * |aead|. */
-size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
+OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
 
 /* EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce
  * for |aead|. */
-size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead);
+OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead);
 
 /* EVP_AEAD_max_overhead returns the maximum number of additional bytes added
  * by the act of sealing data with |aead|. */
-size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead);
+OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead);
 
 /* EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This
  * is the largest value that can be passed as |tag_len| to
  * |EVP_AEAD_CTX_init|. */
-size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead);
+OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead);
 
 
 /* AEAD operations. */
@@ -174,12 +174,12 @@
  * |tag_len| of zero indicates the default tag length and this is defined as
  * EVP_AEAD_DEFAULT_TAG_LENGTH for readability.
  * Returns 1 on success. Otherwise returns 0 and pushes to the error stack. */
-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);
+OPENSSL_EXPORT 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);
 
 /* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. */
-void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
+OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
 
 /* EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and
  * authenticates |ad_len| bytes from |ad| and writes the result to |out|. It
@@ -201,10 +201,11 @@
  * zero.)
  *
  * If |in| and |out| alias then |out| must be <= |in|. */
-int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
-                      size_t max_out_len, const uint8_t *nonce,
-                      size_t nonce_len, const uint8_t *in, size_t in_len,
-                      const uint8_t *ad, size_t ad_len);
+OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
+                                     size_t *out_len, size_t max_out_len,
+                                     const uint8_t *nonce, size_t nonce_len,
+                                     const uint8_t *in, size_t in_len,
+                                     const uint8_t *ad, size_t ad_len);
 
 /* EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes
  * from |ad| and decrypts at most |in_len| bytes into |out|. It returns one on
@@ -225,10 +226,11 @@
  * zero.)
  *
  * If |in| and |out| alias then |out| must be <= |in|. */
-int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
-                      size_t max_out_len, const uint8_t *nonce,
-                      size_t nonce_len, const uint8_t *in, size_t in_len,
-                      const uint8_t *ad, size_t ad_len);
+OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
+                                     size_t *out_len, size_t max_out_len,
+                                     const uint8_t *nonce, size_t nonce_len,
+                                     const uint8_t *in, size_t in_len,
+                                     const uint8_t *ad, size_t ad_len);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/aes.h b/include/openssl/aes.h
index 8156964..11d83bb 100644
--- a/include/openssl/aes.h
+++ b/include/openssl/aes.h
@@ -80,22 +80,26 @@
  *
  * WARNING: unlike other OpenSSL functions, this returns zero on success and a
  * negative number on error. */
-int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
+OPENSSL_EXPORT int AES_set_encrypt_key(const uint8_t *key, unsigned bits,
+                                       AES_KEY *aeskey);
 
 /* AES_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit key,
  * |key|.
  *
  * WARNING: unlike other OpenSSL functions, this returns zero on success and a
  * negative number on error. */
-int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
+OPENSSL_EXPORT int AES_set_decrypt_key(const uint8_t *key, unsigned bits,
+                                       AES_KEY *aeskey);
 
 /* AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in|
  * and |out| pointers may overlap. */
-void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+OPENSSL_EXPORT void AES_encrypt(const uint8_t *in, uint8_t *out,
+                                const AES_KEY *key);
 
 /* AES_decrypt decrypts a single block from |in| to |out| with |key|. The |in|
  * and |out| pointers may overlap. */
-void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out,
+                                const AES_KEY *key);
 
 
 /* Block cipher modes. */
@@ -103,32 +107,36 @@
 /* AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
  * bytes from |in| to |out|. The |num| parameter must be set to zero on the
  * first call and |ivec| will be incremented. */
-void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                        const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE],
-                        uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num);
+OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out,
+                                       size_t len, const AES_KEY *key,
+                                       uint8_t ivec[AES_BLOCK_SIZE],
+                                       uint8_t ecount_buf[AES_BLOCK_SIZE],
+                                       unsigned int *num);
 
 /* AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single,
  * 16 byte block from |in| to |out|. */
-void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key,
-                     const int enc);
+OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out,
+                                    const AES_KEY *key, const int enc);
 
 /* AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
  * bytes from |in| to |out|. The length must be a multiple of the block size. */
-void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                     const AES_KEY *key, uint8_t *ivec, const int enc);
+OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+                                    const AES_KEY *key, uint8_t *ivec,
+                                    const int enc);
 
 /* AES_ofb128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
  * bytes from |in| to |out|. The |num| parameter must be set to zero on the
  * first call. */
-void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                        const AES_KEY *key, uint8_t *ivec, int *num);
+OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
+                                       size_t len, const AES_KEY *key,
+                                       uint8_t *ivec, int *num);
 
 /* AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
  * bytes from |in| to |out|. The |num| parameter must be set to zero on the
  * first call. */
-void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                        const AES_KEY *key, uint8_t *ivec, int *num,
-                        int enc);
+OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out,
+                                       size_t len, const AES_KEY *key,
+                                       uint8_t *ivec, int *num, int enc);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 79635bb..eddaed4 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -299,31 +299,31 @@
 	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
 
 #define	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
-	type *d2i_##name(type **a, const unsigned char **in, long len); \
-	int i2d_##name(type *a, unsigned char **out); \
+	OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \
+	OPENSSL_EXPORT int i2d_##name(type *a, unsigned char **out); \
 	DECLARE_ASN1_ITEM(itname)
 
 #define	DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
-	type *d2i_##name(type **a, const unsigned char **in, long len); \
-	int i2d_##name(const type *a, unsigned char **out); \
+	OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \
+	OPENSSL_EXPORT int i2d_##name(const type *a, unsigned char **out); \
 	DECLARE_ASN1_ITEM(name)
 
 #define	DECLARE_ASN1_NDEF_FUNCTION(name) \
-	int i2d_##name##_NDEF(name *a, unsigned char **out);
+	OPENSSL_EXPORT int i2d_##name##_NDEF(name *a, unsigned char **out);
 
 #define DECLARE_ASN1_FUNCTIONS_const(name) \
 	DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
 	DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
 
 #define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
-	type *name##_new(void); \
-	void name##_free(type *a);
+	OPENSSL_EXPORT type *name##_new(void); \
+	OPENSSL_EXPORT void name##_free(type *a);
 
 #define DECLARE_ASN1_PRINT_FUNCTION(stname) \
 	DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
 
 #define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
-	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+	OPENSSL_EXPORT int fname##_print_ctx(BIO *out, stname *x, int indent, \
 					 const ASN1_PCTX *pctx);
 
 #define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
@@ -414,7 +414,7 @@
 #define ASN1_ITEM_rptr(ref) (ref##_it())
 
 #define DECLARE_ASN1_ITEM(name) \
-	const ASN1_ITEM * name##_it(void);
+	OPENSSL_EXPORT const ASN1_ITEM * name##_it(void);
 
 #endif
 
@@ -762,93 +762,83 @@
 
 DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
 
-int ASN1_TYPE_get(ASN1_TYPE *a);
-void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
-int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
-int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
+OPENSSL_EXPORT int ASN1_TYPE_get(ASN1_TYPE *a);
+OPENSSL_EXPORT void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+OPENSSL_EXPORT int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+OPENSSL_EXPORT int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
 
-ASN1_OBJECT *	ASN1_OBJECT_new(void );
-void		ASN1_OBJECT_free(ASN1_OBJECT *a);
-int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
-ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
-			long length);
-ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
-			long length);
+OPENSSL_EXPORT ASN1_OBJECT *	ASN1_OBJECT_new(void );
+OPENSSL_EXPORT void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+OPENSSL_EXPORT int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+OPENSSL_EXPORT ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+						long length);
+OPENSSL_EXPORT ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+						long length);
 
 DECLARE_ASN1_ITEM(ASN1_OBJECT)
 
 DECLARE_ASN1_SET_OF(ASN1_OBJECT)
 
-ASN1_STRING *	ASN1_STRING_new(void);
-void		ASN1_STRING_free(ASN1_STRING *a);
-int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
-ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
-ASN1_STRING *	ASN1_STRING_type_new(int type );
-int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+OPENSSL_EXPORT ASN1_STRING *	ASN1_STRING_new(void);
+OPENSSL_EXPORT void		ASN1_STRING_free(ASN1_STRING *a);
+OPENSSL_EXPORT int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+OPENSSL_EXPORT ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
+OPENSSL_EXPORT ASN1_STRING *	ASN1_STRING_type_new(int type );
+OPENSSL_EXPORT int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
   /* Since this is used to store all sorts of things, via macros, for now, make
      its data void * */
-int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
-void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
-int ASN1_STRING_length(const ASN1_STRING *x);
-void ASN1_STRING_length_set(ASN1_STRING *x, int n);
-int ASN1_STRING_type(ASN1_STRING *x);
-unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+OPENSSL_EXPORT int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+OPENSSL_EXPORT void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *x);
+OPENSSL_EXPORT void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+OPENSSL_EXPORT int ASN1_STRING_type(ASN1_STRING *x);
+OPENSSL_EXPORT unsigned char * ASN1_STRING_data(ASN1_STRING *x);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
-int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
-ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
-			long length);
-int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
-			int length );
-int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
-int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
-int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
-                                     unsigned char *flags, int flags_len);
+OPENSSL_EXPORT int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, long length);
+OPENSSL_EXPORT int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length );
+OPENSSL_EXPORT int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+OPENSSL_EXPORT int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+OPENSSL_EXPORT int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len);
 
 #ifndef OPENSSL_NO_BIO
-int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
-				BIT_STRING_BITNAME *tbl, int indent);
+OPENSSL_EXPORT int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, BIT_STRING_BITNAME *tbl, int indent);
 #endif
-int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
-int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
-				BIT_STRING_BITNAME *tbl);
+OPENSSL_EXPORT int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+OPENSSL_EXPORT int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, BIT_STRING_BITNAME *tbl);
 
-int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
-int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
+OPENSSL_EXPORT int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+OPENSSL_EXPORT int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
-int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
-ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
-			long length);
-ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
-			long length);
-ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
-int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+OPENSSL_EXPORT int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length);
+OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length);
+OPENSSL_EXPORT ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+OPENSSL_EXPORT int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
 
-int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
-ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
-ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
-				int offset_day, long offset_sec);
-int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
-int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
+OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec);
+OPENSSL_EXPORT int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+OPENSSL_EXPORT int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
 #if 0
 time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
 #endif
 
-int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
-ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
-ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
-	     time_t t, int offset_day, long offset_sec);
-int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
-int ASN1_TIME_diff(int *pday, int *psec,
-			const ASN1_TIME *from, const ASN1_TIME *to);
+OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
+OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec);
+OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+OPENSSL_EXPORT int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
-ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
-int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
-int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
+OPENSSL_EXPORT ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+OPENSSL_EXPORT int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
+OPENSSL_EXPORT int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
 DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
@@ -856,8 +846,8 @@
 DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
 DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
 
-int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
-int UTF8_putc(unsigned char *str, int len, unsigned long value);
+OPENSSL_EXPORT int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+OPENSSL_EXPORT int UTF8_putc(unsigned char *str, int len, unsigned long value);
 
 DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
 
@@ -873,75 +863,67 @@
 
 DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
 
-ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
-ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
-				int offset_day, long offset_sec);
-int ASN1_TIME_check(ASN1_TIME *t);
-ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
-int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, int offset_day, long offset_sec);
+OPENSSL_EXPORT int ASN1_TIME_check(ASN1_TIME *t);
+OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
 
-int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
-		 i2d_of_void *i2d, int ex_tag, int ex_class,
-		 int is_set);
-STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+OPENSSL_EXPORT int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
+OPENSSL_EXPORT STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
 			      const unsigned char **pp,
 			      long length, d2i_of_void *d2i,
 			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
 			      int ex_class);
 
 #ifndef OPENSSL_NO_BIO
-int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
-int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
-int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
-int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
-int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
-int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
-int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+OPENSSL_EXPORT int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+OPENSSL_EXPORT int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+OPENSSL_EXPORT int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
 #endif
-int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
 
-int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
-ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
-	const char *sn, const char *ln);
+OPENSSL_EXPORT int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, const char *sn, const char *ln);
 
-int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
-long ASN1_INTEGER_get(const ASN1_INTEGER *a);
-ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
-BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
+OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+OPENSSL_EXPORT ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+OPENSSL_EXPORT BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
 
-int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
-long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
-ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
-BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+OPENSSL_EXPORT long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
 
 /* General */
 /* given a string, return the correct type, max is the maximum length */
-int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int max);
 
-int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
-ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
-	long length, int Ptag, int Pclass);
-unsigned long ASN1_tag2bit(int tag);
+OPENSSL_EXPORT int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+OPENSSL_EXPORT ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int Ptag, int Pclass);
+OPENSSL_EXPORT unsigned long ASN1_tag2bit(int tag);
 /* type is one or more of the B_ASN1_ values. */
-ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
-		long length,int type);
+OPENSSL_EXPORT ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp, long length,int type);
 
 /* PARSING */
-int asn1_Finish(ASN1_CTX *c);
-int asn1_const_Finish(ASN1_const_CTX *c);
+OPENSSL_EXPORT int asn1_Finish(ASN1_CTX *c);
+OPENSSL_EXPORT int asn1_const_Finish(ASN1_const_CTX *c);
 
 /* SPECIALS */
-int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
-	int *pclass, long omax);
-int ASN1_check_infinite_end(unsigned char **p,long len);
-int ASN1_const_check_infinite_end(const unsigned char **p,long len);
-void ASN1_put_object(unsigned char **pp, int constructed, int length,
-	int tag, int xclass);
-int ASN1_put_eoc(unsigned char **pp);
-int ASN1_object_size(int constructed, int length, int tag);
+OPENSSL_EXPORT int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax);
+OPENSSL_EXPORT int ASN1_check_infinite_end(unsigned char **p,long len);
+OPENSSL_EXPORT int ASN1_const_check_infinite_end(const unsigned char **p,long len);
+OPENSSL_EXPORT void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass);
+OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp);
+OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag);
 
 /* Used to implement other functions */
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+OPENSSL_EXPORT void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
 
 #define ASN1_dup_of(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
@@ -953,7 +935,7 @@
 		     CHECKED_D2I_OF(type, d2i), \
 		     CHECKED_PTR_OF(const type, x)))
 
-void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
 
 /* ASN1 alloc/free macros for when a type is only used internally */
 
@@ -962,7 +944,7 @@
 		ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
 
 #ifndef OPENSSL_NO_FP_API
-void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+OPENSSL_EXPORT void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
 
 #define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
     ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
@@ -970,8 +952,8 @@
 			in, \
 			CHECKED_PPTR_OF(type, x)))
 
-void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
-int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+OPENSSL_EXPORT int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
 
 #define ASN1_i2d_fp_of(type,i2d,out,x) \
     (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
@@ -983,14 +965,14 @@
 		 out, \
 		 CHECKED_PTR_OF(const type, x)))
 
-int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
-int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
 #endif
 
-int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
 
 #ifndef OPENSSL_NO_BIO
-void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+OPENSSL_EXPORT void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
 
 #define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
     ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
@@ -998,8 +980,8 @@
 			  in, \
 			  CHECKED_PPTR_OF(type, x)))
 
-void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
-int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
 
 #define ASN1_i2d_bio_of(type,i2d,out,x) \
     (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
@@ -1011,18 +993,17 @@
 		  out, \
 		  CHECKED_PTR_OF(const type, x)))
 
-int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
-int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
-int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
-int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
-int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
-int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
-int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
-				unsigned char *buf, int off);
-int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
-int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
+OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+OPENSSL_EXPORT int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, int off);
+OPENSSL_EXPORT int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
+OPENSSL_EXPORT int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
 #endif
-const char *ASN1_tag2str(int tag);
+OPENSSL_EXPORT const char *ASN1_tag2str(int tag);
 
 /* Used to load and write netscape format cert */
 
@@ -1030,50 +1011,43 @@
 
 int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
 
-STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
-				 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
-unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
-			     unsigned char **buf, int *len );
-void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
-void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
-ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
-			      ASN1_OCTET_STRING **oct);
+OPENSSL_EXPORT STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
+OPENSSL_EXPORT unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, unsigned char **buf, int *len );
+OPENSSL_EXPORT void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+OPENSSL_EXPORT void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+OPENSSL_EXPORT ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_OCTET_STRING **oct);
 
 #define ASN1_pack_string_of(type,obj,i2d,oct) \
     (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
 		      CHECKED_I2D_OF(type, i2d), \
 		      oct))
 
-ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
+OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
 
-void ASN1_STRING_set_default_mask(unsigned long mask);
-int ASN1_STRING_set_default_mask_asc(const char *p);
-unsigned long ASN1_STRING_get_default_mask(void);
-int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
-					int inform, unsigned long mask);
-int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
-					int inform, unsigned long mask, 
-					long minsize, long maxsize);
+OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask);
+OPENSSL_EXPORT int ASN1_STRING_set_default_mask_asc(const char *p);
+OPENSSL_EXPORT unsigned long ASN1_STRING_get_default_mask(void);
+OPENSSL_EXPORT int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask);
+OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask, long minsize, long maxsize);
 
-ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
-		const unsigned char *in, int inlen, int inform, int nid);
-ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
-int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
-void ASN1_STRING_TABLE_cleanup(void);
+OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen, int inform, int nid);
+OPENSSL_EXPORT ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+OPENSSL_EXPORT int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+OPENSSL_EXPORT void ASN1_STRING_TABLE_cleanup(void);
 
 /* ASN1 template functions */
 
 /* Old API compatible functions */
-ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
-void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
-ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
-int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
-int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+OPENSSL_EXPORT ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
+OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+OPENSSL_EXPORT int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
 
-void ASN1_add_oid_module(void);
+OPENSSL_EXPORT void ASN1_add_oid_module(void);
 
-ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
-ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
 
 /* ASN1 Print flags */
 
@@ -1096,33 +1070,29 @@
 /* Don't show structure name even at top level */
 #define ASN1_PCTX_FLAGS_NO_STRUCT_NAME		0x100
 
-int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
-				const ASN1_ITEM *it, const ASN1_PCTX *pctx);
-ASN1_PCTX *ASN1_PCTX_new(void);
-void ASN1_PCTX_free(ASN1_PCTX *p);
-unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+OPENSSL_EXPORT int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+OPENSSL_EXPORT ASN1_PCTX *ASN1_PCTX_new(void);
+OPENSSL_EXPORT void ASN1_PCTX_free(ASN1_PCTX *p);
+OPENSSL_EXPORT unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+OPENSSL_EXPORT void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+OPENSSL_EXPORT unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+OPENSSL_EXPORT void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+OPENSSL_EXPORT unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+OPENSSL_EXPORT void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+OPENSSL_EXPORT unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+OPENSSL_EXPORT void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+OPENSSL_EXPORT unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+OPENSSL_EXPORT void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
 
-BIO_METHOD *BIO_f_asn1(void);
+OPENSSL_EXPORT BIO_METHOD *BIO_f_asn1(void);
 
-BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+OPENSSL_EXPORT BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
 
-int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
-				const ASN1_ITEM *it);
-int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
-				const char *hdr,
-				const ASN1_ITEM *it);
-ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
-int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
-int SMIME_text(BIO *in, BIO *out);
+OPENSSL_EXPORT int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, const ASN1_ITEM *it);
+OPENSSL_EXPORT int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, const char *hdr, const ASN1_ITEM *it);
+OPENSSL_EXPORT ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+OPENSSL_EXPORT int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+OPENSSL_EXPORT int SMIME_text(BIO *in, BIO *out);
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -1131,14 +1101,10 @@
 void ERR_load_ASN1_strings(void);
 
 typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
-					asn1_ps_func *prefix_free);
-int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
-					asn1_ps_func **pprefix_free);
-int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
-					asn1_ps_func *suffix_free);
-int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
-					asn1_ps_func **psuffix_free);
+OPENSSL_EXPORT int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free);
+OPENSSL_EXPORT int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free);
+OPENSSL_EXPORT int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free);
+OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free);
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/asn1_mac.h b/include/openssl/asn1_mac.h
index a69bea4..3e8eebb 100644
--- a/include/openssl/asn1_mac.h
+++ b/include/openssl/asn1_mac.h
@@ -569,8 +569,8 @@
 #define M_ASN1_I2D_finish()	*pp=p; \
 				return(r);
 
-int asn1_GetSequence(ASN1_const_CTX *c, long *length);
-void asn1_add_error(const unsigned char *address,int offset);
+OPENSSL_EXPORT int asn1_GetSequence(ASN1_const_CTX *c, long *length);
+OPENSSL_EXPORT void asn1_add_error(const unsigned char *address, int offset);
 #ifdef  __cplusplus
 }
 #endif
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 25329c9..4bc10e5 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -53,6 +53,9 @@
 #ifndef OPENSSL_HEADER_BASE_H
 #define OPENSSL_HEADER_BASE_H
 
+
+/* This file should be the first included by all BoringSSL headers. */
+
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -86,11 +89,38 @@
 #define OPENSSL_APPLE
 #endif
 
+#if defined(WIN32)
+#define OPENSSL_WINDOWS
+#endif
+
 #define OPENSSL_IS_BORINGSSL
 #define OPENSSL_VERSION_NUMBER 0x10002000
 
+#if defined(BORINGSSL_SHARED_LIBRARY)
 
-/* This file should be the first included by all BoringSSL headers. */
+#if defined(OPENSSL_WINDOWS)
+
+#if defined(BORINGSSL_IMPLEMENTATION)
+#define OPENSSL_EXPORT __declspec(dllexport)
+#else
+#define OPENSSL_EXPORT __declspec(dllimport)
+#endif
+
+#else  /* defined(OPENSSL_WINDOWS) */
+
+#if defined(BORINGSSL_IMPLEMENTATION)
+#define OPENSSL_EXPORT __attribute__((visibility("default")))
+#else
+#define OPENSSL_EXPORT
+#endif
+
+#endif  /* defined(OPENSSL_WINDOWS) */
+
+#else  /* defined(BORINGSSL_SHARED_LIBRARY) */
+
+#define OPENSSL_EXPORT
+
+#endif  /* defined(BORINGSSL_SHARED_LIBRARY) */
 
 typedef int ASN1_BOOLEAN;
 typedef int ASN1_NULL;
diff --git a/include/openssl/base64.h b/include/openssl/base64.h
index 52dfd6d..606d5ab 100644
--- a/include/openssl/base64.h
+++ b/include/openssl/base64.h
@@ -81,23 +81,26 @@
  * NOTE: The encoding operation breaks its output with newlines every
  * 64 characters of output (48 characters of input). Use
  * EVP_EncodeBlock to encode raw base64. */
-void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
 
 /* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
  * version of them to |out| and sets |*out_len| to the number of bytes written.
  * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
  * flush it before using the encoded data. */
-void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
-                      const uint8_t *in, size_t in_len);
+OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
+                                     int *out_len, const uint8_t *in,
+                                     size_t in_len);
 
 /* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
  * sets |*out_len| to the number of bytes written. */
-void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len);
+OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
+                                    int *out_len);
 
 /* EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the
  * result to |dst| with a trailing NUL. It returns the number of bytes
  * written, not including this trailing NUL. */
-size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
+OPENSSL_EXPORT size_t
+    EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
 
 
 /* Decoding */
@@ -107,7 +110,7 @@
  *
  * TODO(davidben): This isn't a straight-up base64 decode either. Document
  * and/or fix exactly what's going on here; maximum line length and such. */
-void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+OPENSSL_EXPORT void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
 
 /* EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded
  * data to |out| and sets |*out_len| to the number of bytes written. Some state
@@ -116,20 +119,23 @@
  *
  * It returns -1 on error, one if a full line of input was processed and zero
  * if the line was short (i.e. it was the last line). */
-int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
-                     const uint8_t *in, size_t in_len);
+OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
+                                    int *out_len, const uint8_t *in,
+                                    size_t in_len);
 
 /* EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and
  * sets |*out_len| to the number of bytes written. It returns one on success
  * and minus one on error. */
-int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len);
+OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
+                                   int *out_len);
 
 /* EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to
  * |dst|. It returns the number of bytes written or -1 on error.
  *
  * WARNING: EVP_DecodeBlock's return value does not take padding into
  * account. TODO(davidben): Possible or worth it to fix or add new API? */
-ssize_t EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
+OPENSSL_EXPORT ssize_t
+    EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
 
 
 struct evp_encode_ctx_st {
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index 1e433d3..962b2cf 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -79,7 +79,7 @@
 
 /* BIO_new creates a new BIO with the given type and a reference count of one.
  * It returns the fresh |BIO|, or NULL on error. */
-BIO *BIO_new(const BIO_METHOD *type);
+OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *type);
 
 /* BIO_free decrements the reference count of |bio|. If the reference count
  * drops to zero, it (optionally) calls the BIO's callback with |BIO_CB_FREE|,
@@ -88,20 +88,20 @@
  * the next BIO in the chain, if any.
  *
  * It returns one on success or zero otherwise. */
-int BIO_free(BIO *bio);
+OPENSSL_EXPORT int BIO_free(BIO *bio);
 
 /* BIO_vfree performs the same actions as |BIO_free|, but has a void return
  * value. This is provided for API-compat.
  *
  * TODO(fork): remove. */
-void BIO_vfree(BIO *bio);
+OPENSSL_EXPORT void BIO_vfree(BIO *bio);
 
 
 /* Basic I/O. */
 
 /* BIO_read attempts to read |len| bytes into |data|. It returns the number of
  * bytes read, zero on EOF, or a negative number on error. */
-int BIO_read(BIO *bio, void *data, int len);
+OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len);
 
 /* BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|.
  * It returns the number of bytes read or a negative number on error. The
@@ -111,19 +111,19 @@
  *
  * TODO(fork): audit the set of BIOs that we end up needing. If all actually
  * return a line for this call, remove the warning above. */
-int BIO_gets(BIO *bio, char *buf, int size);
+OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size);
 
 /* BIO_write writes |len| bytes from |data| to BIO. It returns the number of
  * bytes written or a negative number on error. */
-int BIO_write(BIO *bio, const void *data, int len);
+OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len);
 
 /* BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the
  * number of bytes written or a negative number on error. */
-int BIO_puts(BIO *bio, const char *buf);
+OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf);
 
 /* BIO_flush flushes any buffered output. It returns one on success and zero
  * otherwise. */
-int BIO_flush(BIO *bio);
+OPENSSL_EXPORT int BIO_flush(BIO *bio);
 
 
 /* Low-level control functions.
@@ -133,48 +133,48 @@
 
 /* BIO_ctrl sends the control request |cmd| to |bio|. The |cmd| argument should
  * be one of the |BIO_C_*| values. */
-long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg);
+OPENSSL_EXPORT long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg);
 
 /* BIO_ptr_ctrl acts like |BIO_ctrl| but passes the address of a |void*|
  * pointer as |parg| and returns the value that is written to it, or NULL if
  * the control request returns <= 0. */
-char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
+OPENSSL_EXPORT char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
 
 /* BIO_int_ctrl acts like |BIO_ctrl| but passes the address of a copy of |iarg|
  * as |parg|. */
-long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
+OPENSSL_EXPORT long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
 
 /* BIO_reset resets |bio| to its initial state, the precise meaning of which
  * depends on the concrete type of |bio|. It returns one on success and zero
  * otherwise. */
-int BIO_reset(BIO *bio);
+OPENSSL_EXPORT int BIO_reset(BIO *bio);
 
 /* BIO_set_flags ORs |flags| with |bio->flags|. */
-void BIO_set_flags(BIO *bio, int flags);
+OPENSSL_EXPORT void BIO_set_flags(BIO *bio, int flags);
 
 /* BIO_test_flags returns |bio->flags| AND |flags|. */
-int BIO_test_flags(const BIO *bio, int flags);
+OPENSSL_EXPORT int BIO_test_flags(const BIO *bio, int flags);
 
 /* BIO_should_read returns non-zero if |bio| encountered a temporary error
  * while reading (i.e. EAGAIN), indicating that the caller should retry the
  * read. */
-int BIO_should_read(const BIO *bio);
+OPENSSL_EXPORT int BIO_should_read(const BIO *bio);
 
 /* BIO_should_write returns non-zero if |bio| encountered a temporary error
  * while writing (i.e. EAGAIN), indicating that the caller should retry the
  * write. */
-int BIO_should_write(const BIO *bio);
+OPENSSL_EXPORT int BIO_should_write(const BIO *bio);
 
 /* BIO_should_retry returns non-zero if the reason that caused a failed I/O
  * operation is temporary and thus the operation should be retried. Otherwise,
  * it was a permanent error and it returns zero. */
-int BIO_should_retry(const BIO *bio);
+OPENSSL_EXPORT int BIO_should_retry(const BIO *bio);
 
 /* BIO_should_io_special returns non-zero if |bio| encountered a temporary
  * error while performing a special I/O operation, indicating that the caller
  * should retry. The operation that caused the error is returned by
  * |BIO_get_retry_reason|. */
-int BIO_should_io_special(const BIO *bio);
+OPENSSL_EXPORT int BIO_should_io_special(const BIO *bio);
 
 /* BIO_RR_SSL_X509_LOOKUP indicates that an SSL BIO blocked because the SSL
  * library returned with SSL_ERROR_WANT_X509_LOOKUP.
@@ -194,30 +194,30 @@
 
 /* BIO_get_retry_reason returns the special I/O operation that needs to be
  * retried. The return value is one of the |BIO_RR_*| values. */
-int BIO_get_retry_reason(const BIO *bio);
+OPENSSL_EXPORT int BIO_get_retry_reason(const BIO *bio);
 
 /* BIO_clear_flags ANDs |bio->flags| with the bitwise-complement of |flags|. */
-void BIO_clear_flags(BIO *bio, int flags);
+OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags);
 
 /* BIO_set_retry_read sets the |BIO_FLAGS_READ| and |BIO_FLAGS_SHOULD_RETRY|
  * flags on |bio|. */
-void BIO_set_retry_read(BIO *bio);
+OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio);
 
 /* BIO_set_retry_read sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
  * flags on |bio|. */
-void BIO_set_retry_write(BIO *bio);
+OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio);
 
 /* BIO_get_retry_flags gets the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|,
  * |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. */
-int BIO_get_retry_flags(BIO *bio);
+OPENSSL_EXPORT int BIO_get_retry_flags(BIO *bio);
 
 /* BIO_clear_retry_flags clears the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|,
  * |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. */
-void BIO_clear_retry_flags(BIO *bio);
+OPENSSL_EXPORT void BIO_clear_retry_flags(BIO *bio);
 
 /* BIO_method_type returns the type of |bio|, which is one of the |BIO_TYPE_*|
  * values. */
-int BIO_method_type(const BIO *bio);
+OPENSSL_EXPORT int BIO_method_type(const BIO *bio);
 
 /* bio_info_cb is the type of a callback function that can be called for most
  * BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed
@@ -230,31 +230,31 @@
 /* BIO_callback_ctrl allows the callback function to be manipulated. The |cmd|
  * arg will generally be |BIO_CTRL_SET_CALLBACK| but arbitary command values
  * can be interpreted by the |BIO|. */
-long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp);
+OPENSSL_EXPORT long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp);
 
 /* BIO_pending returns the number of bytes pending to be read. */
-size_t BIO_pending(const BIO *bio);
+OPENSSL_EXPORT size_t BIO_pending(const BIO *bio);
 
 /* BIO_wpending returns the number of bytes pending to be written. */
-size_t BIO_wpending(const BIO *bio);
+OPENSSL_EXPORT size_t BIO_wpending(const BIO *bio);
 
 /* BIO_set_close sets the close flag for |bio|. The meaning of which depends on
  * the type of |bio| but, for example, a memory BIO interprets the close flag
  * as meaning that it owns its buffer. It returns one on success and zero
  * otherwise. */
-int BIO_set_close(BIO *bio, int close_flag);
+OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag);
 
 /* BIO_set_callback sets a callback function that will be called before and
  * after most operations. See the comment above |bio_info_cb|. */
-void BIO_set_callback(BIO *bio, bio_info_cb callback_func);
+OPENSSL_EXPORT void BIO_set_callback(BIO *bio, bio_info_cb callback_func);
 
 /* BIO_set_callback_arg sets the opaque pointer value that can be read within a
  * callback with |BIO_get_callback_arg|. */
-void BIO_set_callback_arg(BIO *bio, char *arg);
+OPENSSL_EXPORT void BIO_set_callback_arg(BIO *bio, char *arg);
 
 /* BIO_get_callback_arg returns the last value of the opaque callback pointer
  * set by |BIO_set_callback_arg|. */
-char *BIO_get_callback_arg(const BIO *bio);
+OPENSSL_EXPORT char *BIO_get_callback_arg(const BIO *bio);
 
 
 /* Managing chains of BIOs.
@@ -268,30 +268,30 @@
  * and thus this function can be used to join two chains.
  *
  * BIO_push takes ownership of the caller's reference to |appended_bio|. */
-BIO *BIO_push(BIO *bio, BIO *appended_bio);
+OPENSSL_EXPORT BIO *BIO_push(BIO *bio, BIO *appended_bio);
 
 /* BIO_pop removes |bio| from the head of a chain and returns the next BIO in
  * the chain, or NULL if there is no next BIO.
  *
  * The caller takes ownership of the chain's reference to |bio|. */
-BIO *BIO_pop(BIO *bio);
+OPENSSL_EXPORT BIO *BIO_pop(BIO *bio);
 
 /* BIO_next returns the next BIO in the chain after |bio|, or NULL if there is
  * no such BIO. */
-BIO *BIO_next(BIO *bio);
+OPENSSL_EXPORT BIO *BIO_next(BIO *bio);
 
 /* BIO_free_all calls |BIO_free|.
  *
  * TODO(fork): update callers and remove. */
-void BIO_free_all(BIO *bio);
+OPENSSL_EXPORT void BIO_free_all(BIO *bio);
 
 /* BIO_find_type walks a chain of BIOs and returns the first that matches
  * |type|, which is one of the |BIO_TYPE_*| values. */
-BIO *BIO_find_type(BIO *bio, int type);
+OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type);
 
 /* BIO_copy_next_retry sets the retry flags and |retry_reason| of |bio| from
  * the next BIO in the chain. */
-void BIO_copy_next_retry(BIO *bio);
+OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio);
 
 
 /* Printf functions.
@@ -303,10 +303,10 @@
 #else
 #define __bio_h__attr__(x)
 #endif
-int BIO_printf(BIO *bio, const char *format, ...)
+OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...)
     __bio_h__attr__((__format__(__printf__, 2, 3)));
 
-int BIO_vprintf(BIO *bio, const char *format, va_list args)
+OPENSSL_EXPORT int BIO_vprintf(BIO *bio, const char *format, va_list args)
     __bio_h__attr__((__format__(__printf__, 2, 0)));
 #undef __bio_h__attr__
 
@@ -315,19 +315,20 @@
 
 /* BIO_indent prints min(|indent|, |max_indent|) spaces. It returns one on
  * success and zero otherwise. */
-int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent);
+OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent);
 
 /* BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented
  * by |indent| spaces. */
-int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent);
+OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len,
+                               unsigned indent);
 
 /* BIO_print_errors_fp prints the current contents of the error stack to |out|
  * using human readable strings where possible. */
-void BIO_print_errors_fp(FILE *out);
+OPENSSL_EXPORT void BIO_print_errors_fp(FILE *out);
 
 /* BIO_print_errors prints the current contents of the error stack to |bio|
  * using human readable strings where possible. */
-void BIO_print_errors(BIO *bio);
+OPENSSL_EXPORT void BIO_print_errors(BIO *bio);
 
 
 /* Memory BIOs.
@@ -349,20 +350,21 @@
  * |BIO_ctrl_pending| returns the number of bytes currently stored. */
 
 /* BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. */
-const BIO_METHOD *BIO_s_mem(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void);
 
 /* BIO_new_mem_buf creates BIO that reads and writes from |len| bytes at |buf|.
  * It does not take ownership of |buf|. It returns the BIO or NULL on error.
  *
  * If |len| is negative, then |buf| is treated as a NUL-terminated string, but
  * don't depend on this in new code. */
-BIO *BIO_new_mem_buf(void *buf, int len);
+OPENSSL_EXPORT BIO *BIO_new_mem_buf(void *buf, int len);
 
 /* BIO_mem_contents sets |*out_contents| to point to the current contents of
  * |bio| and |*out_len| to contain the length of that data. It returns one on
  * success and zero otherwise. */
-int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
-                     size_t *out_len);
+OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio,
+                                    const uint8_t **out_contents,
+                                    size_t *out_len);
 
 /* BIO_get_mem_data sets |*contents| to point to the current contents of |bio|
  * and returns the length of the data.
@@ -370,16 +372,16 @@
  * WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from
  * this function can mean either that it failed or that the memory buffer is
  * empty. */
-long BIO_get_mem_data(BIO *bio, char **contents);
+OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents);
 
 /* BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of
  * |bio|. It returns one on success or zero on error. */
-int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out);
+OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out);
 
 /* BIO_set_mem_buf sets |b| as the contents of |bio|. If |take_ownership| is
  * non-zero, then |b| will be freed when |bio| is closed. Returns one on
  * success or zero otherwise. */
-int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership);
+OPENSSL_EXPORT int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership);
 
 /* BIO_set_mem_eof_return sets the value that will be returned from reading
  * |bio| when empty. If |eof_value| is zero then an empty memory BIO will
@@ -391,7 +393,7 @@
  *
  * For a read-only BIO, the default is zero (EOF). For a writable BIO, the
  * default is -1 so that additional data can be written once exhausted. */
-int BIO_set_mem_eof_return(BIO *bio, int eof_value);
+OPENSSL_EXPORT int BIO_set_mem_eof_return(BIO *bio, int eof_value);
 
 
 /* File descriptor BIOs.
@@ -409,20 +411,20 @@
  * |BIO_tell| returns the current file position. */
 
 /* BIO_s_fd returns a |BIO_METHOD| for file descriptor fds. */
-const BIO_METHOD *BIO_s_fd(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_fd(void);
 
 /* BIO_new_fd creates a new file descriptor BIO wrapping |fd|. If |close_flag|
  * is non-zero, then |fd| will be closed when the BIO is. */
-BIO *BIO_new_fd(int fd, int close_flag);
+OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag);
 
 /* BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is
  * non-zero then |fd| will be closed when |bio| is. It returns one on success
  * or zero on error. */
-int BIO_set_fd(BIO *bio, int fd, int close_flag);
+OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
 
 /* BIO_get_fd sets |*out_fd| to the file descriptor currently in use by |bio|.
  * It returns one on success and zero on error. */
-int BIO_get_fd(BIO *bio, int *out_fd);
+OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
 
 
 /* File BIOs.
@@ -443,45 +445,45 @@
  * BIO is freed. */
 
 /* BIO_s_file returns a BIO_METHOD that wraps a |FILE|. */
-const BIO_METHOD *BIO_s_file(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void);
 
 /* BIO_new_file creates a file BIO by opening |filename| with the given mode.
  * See the |fopen| manual page for details of the mode argument. */
-BIO *BIO_new_file(const char *filename, const char *mode);
+OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode);
 
 /* BIO_new_fp creates a new file BIO that wraps the given |FILE|. If
  * |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when
  * the BIO is closed. */
-BIO *BIO_new_fp(FILE *stream, int close_flag);
+OPENSSL_EXPORT BIO *BIO_new_fp(FILE *stream, int close_flag);
 
 /* BIO_get_fp sets |*out_file| to the current |FILE| for |bio|. It returns one
  * on success and zero otherwise. */
-int BIO_get_fp(BIO *bio, FILE **out_file);
+OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file);
 
 /* BIO_set_fp sets the |FILE| for |bio|. If |close_flag| is |BIO_CLOSE| then
  * |fclose| will be called on |file| when |bio| is closed. It returns one on
  * sucess and zero otherwise. */
-int BIO_set_fp(BIO *bio, FILE *file, int close_flag);
+OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag);
 
 /* BIO_read_filename opens |filename| for reading and sets the result as the
  * |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
  * will be closed when |bio| is freed. */
-int BIO_read_filename(BIO *bio, const char *filename);
+OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename);
 
 /* BIO_write_filename opens |filename| for writing and sets the result as the
  * |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
  * will be closed when |bio| is freed. */
-int BIO_write_filename(BIO *bio, const char *filename);
+OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename);
 
 /* BIO_append_filename opens |filename| for appending and sets the result as
  * the |FILE| for |bio|. It returns one on success and zero otherwise. The
  * |FILE| will be closed when |bio| is freed. */
-int BIO_append_filename(BIO *bio, const char *filename);
+OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename);
 
 /* BIO_rw_filename opens |filename| for reading and writing and sets the result
  * as the |FILE| for |bio|. It returns one on success and zero otherwise. The
  * |FILE| will be closed when |bio| is freed. */
-int BIO_rw_filename(BIO *bio, const char *filename);
+OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename);
 
 
 /* Buffer BIOs.
@@ -490,25 +492,25 @@
  * chain of BIOs. They provide buffering to reduce the number of operations on
  * the underlying BIOs. */
 
-const BIO_METHOD *BIO_f_buffer(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_f_buffer(void);
 
 /* BIO_set_read_buffer_size sets the size, in bytes, of the read buffer and
  * clears it. It returns one on success and zero on failure. */
-int BIO_set_read_buffer_size(BIO *bio, int buffer_size);
+OPENSSL_EXPORT int BIO_set_read_buffer_size(BIO *bio, int buffer_size);
 
 /* BIO_set_write_buffer_size sets the size, in bytes, of the write buffer and
  * clears it. It returns one on success and zero on failure. */
-int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
+OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
 
 
 /* Socket BIOs. */
 
-const BIO_METHOD *BIO_s_socket(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void);
 
 /* BIO_new_socket allocates and initialises a fresh BIO which will read and
  * write to the socket |fd|. If |close_flag| is |BIO_CLOSE| then closing the
  * BIO will close |fd|. It returns the fresh |BIO| or NULL on error. */
-BIO *BIO_new_socket(int fd, int close_flag);
+OPENSSL_EXPORT BIO *BIO_new_socket(int fd, int close_flag);
 
 
 /* Connect BIOs.
@@ -516,7 +518,7 @@
  * A connection BIO creates a network connection and transfers data over the
  * resulting socket. */
 
-const BIO_METHOD *BIO_s_connect(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_connect(void);
 
 /* BIO_new_connect returns a BIO that connects to the given hostname and port.
  * The |host_and_optional_port| argument should be of the form
@@ -524,22 +526,23 @@
  * be provided with |BIO_set_conn_port|.
  *
  * It returns the new BIO on success, or NULL on error. */
-BIO *BIO_new_connect(const char *host_and_optional_port);
+OPENSSL_EXPORT BIO *BIO_new_connect(const char *host_and_optional_port);
 
 /* BIO_set_conn_hostname sets |host_and_optional_port| as the hostname and
  * optional port that |bio| will connect to. If the port is omitted, it must be
  * provided with |BIO_set_conn_port|.
  *
  * It returns one on success and zero otherwise. */
-int BIO_set_conn_hostname(BIO *bio, const char *host_and_optional_port);
+OPENSSL_EXPORT int BIO_set_conn_hostname(BIO *bio,
+                                         const char *host_and_optional_port);
 
 /* BIO_set_conn_port sets |port_str| as the port or service name that |bio|
  * will connect to. It returns one on success and zero otherwise. */
-int BIO_set_conn_port(BIO *bio, const char *port_str);
+OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str);
 
 /* BIO_set_nbio sets whether |bio| will use non-blocking I/O operations. It
  * returns one on success and zero otherwise. */
-int BIO_set_nbio(BIO *bio, int on);
+OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on);
 
 
 /* Datagram BIOs.
@@ -571,25 +574,25 @@
  * data written to one can be read from the other and vice versa. The
  * |writebuf1| argument gives the size of the buffer used in |*out1| and
  * |writebuf2| for |*out2|. It returns one on success and zero on error. */
-int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2,
-                     size_t writebuf2);
+OPENSSL_EXPORT int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2,
+                                    size_t writebuf2);
 
 /* BIO_s_bio returns the method for a BIO pair. */
-const BIO_METHOD *BIO_s_bio(void);
+OPENSSL_EXPORT const BIO_METHOD *BIO_s_bio(void);
 
 /* BIO_ctrl_get_read_request returns the number of bytes that the other side of
  * |bio| tried (unsuccessfully) to read. */
-size_t BIO_ctrl_get_read_request(BIO *bio);
+OPENSSL_EXPORT size_t BIO_ctrl_get_read_request(BIO *bio);
 
 /* BIO_ctrl_get_write_guarantee returns the number of bytes that |bio| (which
  * must have been returned by |BIO_new_bio_pair|) will accept on the next
  * |BIO_write| call. */
-size_t BIO_ctrl_get_write_guarantee(BIO *bio);
+OPENSSL_EXPORT size_t BIO_ctrl_get_write_guarantee(BIO *bio);
 
 /* BIO_shutdown_wr marks |bio| as closed, from the point of view of the other
  * side of the pair. Future |BIO_write| calls on |bio| will fail. It returns
  * one on success and zero otherwise. */
-int BIO_shutdown_wr(BIO *bio);
+OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio);
 
 
 /* BIO_NOCLOSE and |BIO_CLOSE| can be used as symbolic arguments when a "close
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index 1635aab..d986394 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -152,72 +152,72 @@
 /* Allocation and freeing. */
 
 /* BN_new creates a new, allocated BIGNUM and initialises it. */
-BIGNUM *BN_new(void);
+OPENSSL_EXPORT BIGNUM *BN_new(void);
 
 /* BN_init initialises a stack allocated |BIGNUM|. */
-void BN_init(BIGNUM *bn);
+OPENSSL_EXPORT void BN_init(BIGNUM *bn);
 
 /* BN_free frees the data referenced by |bn| and, if |bn| was originally
  * allocated on the heap, frees |bn| also. */
-void BN_free(BIGNUM *bn);
+OPENSSL_EXPORT void BN_free(BIGNUM *bn);
 
 /* BN_clear_free erases and frees the data referenced by |bn| and, if |bn| was
  * originally allocated on the heap, frees |bn| also. */
-void BN_clear_free(BIGNUM *bn);
+OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn);
 
 /* BN_dup allocates a new BIGNUM and sets it equal to |src|. It returns the
  * allocated BIGNUM on success or NULL otherwise. */
-BIGNUM *BN_dup(const BIGNUM *src);
+OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src);
 
 /* BN_copy sets |dest| equal to |src| and returns |dest|. */
-BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src);
+OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src);
 
 /* BN_clear sets |bn| to zero and erases the old data. */
-void BN_clear(BIGNUM *bn);
+OPENSSL_EXPORT void BN_clear(BIGNUM *bn);
 
 /* BN_value_one returns a static BIGNUM with value 1. */
-const BIGNUM *BN_value_one(void);
+OPENSSL_EXPORT const BIGNUM *BN_value_one(void);
 
 /* BN_with_flags initialises a stack allocated |BIGNUM| with pointers to the
  * contents of |in| but with |flags| ORed into the flags field.
  *
  * Note: the two BIGNUMs share state and so |out| should /not/ be passed to
  * |BN_free|. */
-void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags);
+OPENSSL_EXPORT void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags);
 
 
 /* Basic functions. */
 
 /* BN_num_bits returns the minimum number of bits needed to represent the
  * absolute value of |bn|. */
-unsigned BN_num_bits(const BIGNUM *bn);
+OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn);
 
 /* BN_num_bytes returns the minimum number of bytes needed to represent the
  * absolute value of |bn|. */
-unsigned BN_num_bytes(const BIGNUM *bn);
+OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn);
 
 /* BN_zero sets |bn| to zero. */
-void BN_zero(BIGNUM *bn);
+OPENSSL_EXPORT void BN_zero(BIGNUM *bn);
 
 /* BN_one sets |bn| to one. It returns one on success or zero on allocation
  * failure. */
-int BN_one(BIGNUM *bn);
+OPENSSL_EXPORT int BN_one(BIGNUM *bn);
 
 /* BN_set_word sets |bn| to |value|. It returns one on success or zero on
  * allocation failure. */
-int BN_set_word(BIGNUM *bn, BN_ULONG value);
+OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value);
 
 /* BN_set_negative sets the sign of |bn|. */
-void BN_set_negative(BIGNUM *bn, int sign);
+OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign);
 
 /* BN_is_negative returns one if |bn| is negative and zero otherwise. */
-int BN_is_negative(const BIGNUM *bn);
+OPENSSL_EXPORT int BN_is_negative(const BIGNUM *bn);
 
 /* BN_get_flags returns |bn->flags| & |flags|. */
-int BN_get_flags(const BIGNUM *bn, int flags);
+OPENSSL_EXPORT int BN_get_flags(const BIGNUM *bn, int flags);
 
 /* BN_set_flags sets |flags| on |bn|. */
-void BN_set_flags(BIGNUM *bn, int flags);
+OPENSSL_EXPORT void BN_set_flags(BIGNUM *bn, int flags);
 
 
 /* Conversion functions. */
@@ -226,23 +226,23 @@
  * a big-endian number, and returns |ret|. If |ret| is NULL then a fresh
  * |BIGNUM| is allocated and returned. It returns NULL on allocation
  * failure. */
-BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret);
+OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret);
 
 /* BN_bn2bin serialises the absolute value of |in| to |out| as a big-endian
  * integer, which must have |BN_num_bytes| of space available. It returns the
  * number of bytes written. */
-size_t BN_bn2bin(const BIGNUM *in, uint8_t *out);
+OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out);
 
 /* BN_bn2bin_padded serialises the absolute value of |in| to |out| as a
  * big-endian integer. The integer is padded with leading zeros up to size
  * |len|. If |len| is smaller than |BN_num_bytes|, the function fails and
  * returns 0. Otherwise, it returns 1. */
-int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in);
+OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in);
 
 /* BN_bn2hex returns an allocated string that contains a NUL-terminated, hex
  * representation of |bn|. If |bn| is negative, the first char in the resulting
  * string will be '-'. Returns NULL on allocation failure. */
-char *BN_bn2hex(const BIGNUM *bn);
+OPENSSL_EXPORT char *BN_bn2hex(const BIGNUM *bn);
 
 /* BN_hex2bn parses the leading hex number from |in|, which may be proceeded by
  * a '-' to indicate a negative number and may contain trailing, non-hex data.
@@ -250,12 +250,12 @@
  * stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and
  * updates |*outp|. It returns the number of bytes of |in| processed or zero on
  * error. */
-int BN_hex2bn(BIGNUM **outp, const char *in);
+OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in);
 
 /* BN_bn2dec returns an allocated string that contains a NUL-terminated,
  * decimal representation of |bn|. If |bn| is negative, the first char in the
  * resulting string will be '-'. Returns NULL on allocation failure. */
-char *BN_bn2dec(const BIGNUM *a);
+OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a);
 
 /* BN_dec2bn parses the leading decimal number from |in|, which may be
  * proceeded by a '-' to indicate a negative number and may contain trailing,
@@ -263,25 +263,25 @@
  * decimal number and stores it in |*outp|. If |*outp| is NULL then it
  * allocates a new BIGNUM and updates |*outp|. It returns the number of bytes
  * of |in| processed or zero on error. */
-int BN_dec2bn(BIGNUM **outp, const char *in);
+OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in);
 
 /* BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in|
  * begins with "0X" or "0x" (indicating hex) or not (indicating decimal). A
  * leading '-' is still permitted and comes before the optional 0X/0x. It
  * returns one on success or zero on error. */
-int BN_asc2bn(BIGNUM **outp, const char *in);
+OPENSSL_EXPORT int BN_asc2bn(BIGNUM **outp, const char *in);
 
 /* BN_print writes a hex encoding of |a| to |bio|. It returns one on success
  * and zero on error. */
-int BN_print(BIO *bio, const BIGNUM *a);
+OPENSSL_EXPORT int BN_print(BIO *bio, const BIGNUM *a);
 
 /* BN_print_fp acts like |BIO_print|, but wraps |fp| in a |BIO| first. */
-int BN_print_fp(FILE *fp, const BIGNUM *a);
+OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a);
 
 /* BN_get_word returns the absolute value of |bn| as a single word. If |bn| is
  * too large to be represented as a single word, the maximum possible value
  * will be returned. */
-BN_ULONG BN_get_word(const BIGNUM *bn);
+OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn);
 
 
 /* BIGNUM pools.
@@ -301,154 +301,156 @@
  * |BN_CTX_get| become invalid. */
 
 /* BN_CTX_new returns a new, empty BN_CTX or NULL on allocation failure. */
-BN_CTX *BN_CTX_new(void);
+OPENSSL_EXPORT BN_CTX *BN_CTX_new(void);
 
 /* BN_CTX_free frees all BIGNUMs contained in |ctx| and then frees |ctx|
  * itself. */
-void BN_CTX_free(BN_CTX *ctx);
+OPENSSL_EXPORT void BN_CTX_free(BN_CTX *ctx);
 
 /* BN_CTX_start "pushes" a new entry onto the |ctx| stack and allows future
  * calls to |BN_CTX_get|. */
-void BN_CTX_start(BN_CTX *ctx);
+OPENSSL_EXPORT void BN_CTX_start(BN_CTX *ctx);
 
 /* BN_CTX_get returns a new |BIGNUM|, or NULL on allocation failure. Once
  * |BN_CTX_get| has returned NULL, all future calls will also return NULL until
  * |BN_CTX_end| is called. */
-BIGNUM *BN_CTX_get(BN_CTX *ctx);
+OPENSSL_EXPORT BIGNUM *BN_CTX_get(BN_CTX *ctx);
 
 /* BN_CTX_end invalidates all |BIGNUM|s returned from |BN_CTX_get| since the
  * matching |BN_CTX_start| call. */
-void BN_CTX_end(BN_CTX *ctx);
+OPENSSL_EXPORT void BN_CTX_end(BN_CTX *ctx);
 
 
 /* Simple arithmetic */
 
 /* BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a|
  * or |b|. It returns one on success and zero on allocation failure. */
-int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
 
 /* BN_uadd sets |r| = |a| + |b|, where |a| and |b| are non-negative and |r| may
  * be the same pointer as either |a| or |b|. It returns one on success and zero
  * on allocation failure. */
-int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
 
 /* BN_add_word adds |w| to |a|. It returns one on success and zero otherwise. */
-int BN_add_word(BIGNUM *a, BN_ULONG w);
+OPENSSL_EXPORT int BN_add_word(BIGNUM *a, BN_ULONG w);
 
 /* BN_sub sets |r| = |a| + |b|, where |r| must be a distinct pointer from |a|
  * and |b|. It returns one on success and zero on allocation failure. */
-int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
 
 /* BN_usub sets |r| = |a| + |b|, where |a| and |b| are non-negative integers,
  * |b| < |a| and |r| must be a distinct pointer from |a| and |b|. It returns
  * one on success and zero on allocation failure. */
-int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
 
 /* BN_sub_word subtracts |w| from |a|. It returns one on success and zero on
  * allocation failure. */
-int BN_sub_word(BIGNUM *a, BN_ULONG w);
+OPENSSL_EXPORT int BN_sub_word(BIGNUM *a, BN_ULONG w);
 
 /* BN_mul sets |r| = |a| * |b|, where |r| may be the same pointer as |a| or
  * |b|. Returns one on success and zero otherwise. */
-int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                          BN_CTX *ctx);
 
 /* BN_mul_word sets |bn| = |bn| * |w|. It returns one on success or zero on
  * allocation failure. */
-int BN_mul_word(BIGNUM *bn, BN_ULONG w);
+OPENSSL_EXPORT int BN_mul_word(BIGNUM *bn, BN_ULONG w);
 
 /* BN_sqr sets |r| = |a|^2 (i.e. squares), where |r| may be the same pointer as
  * |a|. Returns one on success and zero otherwise. This is more efficient than
  * BN_mul(r, a, a, ctx). */
-int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
 
 /* BN_div divides |numerator| by |divisor| and places the result in |quotient|
  * and the remainder in |rem|. Either of |quotient| or |rem| may be NULL, in
  * which case the respective value is not returned. The result is rounded
  * towards zero; thus if |numerator| is negative, the remainder will be zero or
  * negative. It returns one on success or zero on error. */
-int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
-           const BIGNUM *divisor, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_div(BIGNUM *quotient, BIGNUM *rem,
+                          const BIGNUM *numerator, const BIGNUM *divisor,
+                          BN_CTX *ctx);
 
 /* BN_div_word sets |numerator| = |numerator|/|divisor| and returns the
  * remainder or (BN_ULONG)-1 on error. */
-BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor);
+OPENSSL_EXPORT BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor);
 
 /* BN_sqrt sets |*out_sqrt| (which may be the same |BIGNUM| as |in|) to the
  * square root of |in|, using |ctx|. It returns one on success or zero on
  * error. Negative numbers and non-square numbers will result in an error with
  * appropriate errors on the error queue. */
-int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx);
 
 
 /* Comparison functions */
 
 /* BN_cmp returns a value less than, equal to or greater than zero if |a| is
  * less than, equal to or greater than |b|, respectively. */
-int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_cmp(const BIGNUM *a, const BIGNUM *b);
 
 /* BN_ucmp returns a value less than, equal to or greater than zero if the
  * absolute value of |a| is less than, equal to or greater than the absolute
  * value of |b|, respectively. */
-int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+OPENSSL_EXPORT int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
 
 /* BN_abs_is_word returns one if the absolute value of |bn| equals |w| and zero
  * otherwise. */
-int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w);
+OPENSSL_EXPORT int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w);
 
 /* BN_is_zero returns one if |bn| is zero and zero otherwise. */
-int BN_is_zero(const BIGNUM *bn);
+OPENSSL_EXPORT int BN_is_zero(const BIGNUM *bn);
 
 /* BN_is_one returns one if |bn| equals one and zero otherwise. */
-int BN_is_one(const BIGNUM *bn);
+OPENSSL_EXPORT int BN_is_one(const BIGNUM *bn);
 
 /* BN_is_word returns one if |bn| is exactly |w| and zero otherwise. */
-int BN_is_word(const BIGNUM *bn, BN_ULONG w);
+OPENSSL_EXPORT int BN_is_word(const BIGNUM *bn, BN_ULONG w);
 
 /* BN_is_odd returns one if |bn| is odd and zero otherwise. */
-int BN_is_odd(const BIGNUM *bn);
+OPENSSL_EXPORT int BN_is_odd(const BIGNUM *bn);
 
 
 /* Bitwise operations. */
 
 /* BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the
  * same |BIGNUM|. It returns one on success and zero on allocation failure. */
-int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
 
 /* BN_lshift1 sets |r| equal to |a| << 1, where |r| and |a| may be the same
  * pointer. It returns one on success and zero on allocation failure. */
-int BN_lshift1(BIGNUM *r, const BIGNUM *a);
+OPENSSL_EXPORT int BN_lshift1(BIGNUM *r, const BIGNUM *a);
 
 /* BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same
  * pointer. It returns one on success and zero on allocation failure. */
-int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
 
 /* BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same
  * pointer. It returns one on success and zero on allocation failure. */
-int BN_rshift1(BIGNUM *r, const BIGNUM *a);
+OPENSSL_EXPORT int BN_rshift1(BIGNUM *r, const BIGNUM *a);
 
 /* BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if |a|
  * is 2 then setting bit zero will make it 3. It returns one on success or zero
  * on allocation failure. */
-int BN_set_bit(BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_set_bit(BIGNUM *a, int n);
 
 /* BN_clear_bit clears the |n|th, least-significant bit in |a|. For example, if
  * |a| is 3, clearing bit zero will make it two. It returns one on success or
  * zero on allocation failure. */
-int BN_clear_bit(BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_clear_bit(BIGNUM *a, int n);
 
 /* BN_is_bit_set returns the value of the |n|th, least-significant bit in |a|,
  * or zero if the bit doesn't exist. */
-int BN_is_bit_set(const BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_is_bit_set(const BIGNUM *a, int n);
 
 /* BN_mask_bits truncates |a| so that it is only |n| bits long. It returns one
  * on success or zero if |n| is greater than the length of |a| already. */
-int BN_mask_bits(BIGNUM *a, int n);
+OPENSSL_EXPORT int BN_mask_bits(BIGNUM *a, int n);
 
 
 /* Modulo arithmetic. */
 
 /* BN_mod_word returns |a| mod |w|. */
-BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
 
 /* BN_mod is a helper macro that calls |BN_div| and discards the quotient. */
 #define BN_mod(rem, numerator, divisor, ctx) \
@@ -456,57 +458,62 @@
 
 /* BN_nnmod is a non-negative modulo function. It acts like |BN_mod|, but 0 <=
  * |rem| < |divisor| is always true. */
-int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator, const BIGNUM *divisor,
-             BN_CTX *ctx);
+OPENSSL_EXPORT int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator,
+                            const BIGNUM *divisor, BN_CTX *ctx);
 
 /* BN_mod_add sets |r| = |a| + |b| mod |m|. It returns one on success and zero
  * on error. */
-int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-               BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                              const BIGNUM *m, BN_CTX *ctx);
 
 /* BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be
  * non-negative and less than |m|. */
-int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-                     const BIGNUM *m);
+OPENSSL_EXPORT int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                                    const BIGNUM *m);
 
 /* BN_mod_sub sets |r| = |a| - |b| mod |m|. It returns one on success and zero
  * on error. */
-int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-               BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                              const BIGNUM *m, BN_CTX *ctx);
 
 /* BN_mod_sub_quick acts like |BN_mod_sub| but requires that |a| and |b| be
  * non-negative and less than |m|. */
-int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-                     const BIGNUM *m);
+OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                                    const BIGNUM *m);
 
 /* BN_mod_mul sets |r| = |a|*|b| mod |m|. It returns one on success and zero
  * on error. */
-int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-               BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                              const BIGNUM *m, BN_CTX *ctx);
 
 /* BN_mod_mul sets |r| = |a|^2 mod |m|. It returns one on success and zero
  * on error. */
-int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
+                              BN_CTX *ctx);
 
 /* BN_mod_lshift sets |r| = (|a| << n) mod |m|, where |r| and |a| may be the
  * same pointer. It returns one on success and zero on error. */
-int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
-                  BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n,
+                                 const BIGNUM *m, BN_CTX *ctx);
 
 /* BN_mod_lshift_quick acts like |BN_mod_lshift| but requires that |a| be
  * non-negative and less than |m|. */
-int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+OPENSSL_EXPORT int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n,
+                                       const BIGNUM *m);
 
 /* BN_mod_lshift1 sets |r| = (|a| << 1) mod |m|, where |r| and |a| may be the
  * same pointer. It returns one on success and zero on error. */
-int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
+                                  BN_CTX *ctx);
 
 /* BN_mod_lshift1_quick acts like |BN_mod_lshift1| but requires that |a| be
  * non-negative and less than |m|. */
-int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a,
+                                        const BIGNUM *m);
 
 /* BN_mod_sqrt returns a |BIGNUM|, r, such that r^2 == a (mod p). */
-BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p,
+                                   BN_CTX *ctx);
 
 
 /* Random and prime number generation. */
@@ -520,17 +527,17 @@
  *
  * If |bottom| is non-zero, the least-significant bit will be set. The function
  * returns one on success or zero otherwise. */
-int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
 
 /* BN_pseudo_rand is an alias for |BN_rand|. */
-int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+OPENSSL_EXPORT int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
 
 /* BN_rand_range sets |rnd| to a random value [0..range). It returns one on
  * success and zero otherwise. */
-int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+OPENSSL_EXPORT int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
 
 /* BN_pseudo_rand_range is an alias for BN_rand_range. */
-int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+OPENSSL_EXPORT int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
 
 /* BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike
  * BN_rand_range, it also includes the contents of |priv| and |message| in the
@@ -538,9 +545,10 @@
  * secret. This is intended for use in DSA and ECDSA where an RNG weakness
  * leads directly to private key exposure unless this function is used.
  * It returns one on success and zero on error. */
-int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
-                          const uint8_t *message, size_t message_len,
-                          BN_CTX *ctx);
+OPENSSL_EXPORT int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
+                                         const BIGNUM *priv,
+                                         const uint8_t *message,
+                                         size_t message_len, BN_CTX *ctx);
 
 /* BN_GENCB holds a callback function that is used by generation functions that
  * can take a very long time to complete. Use |BN_GENCB_set| to initialise a
@@ -570,13 +578,14 @@
 
 /* BN_GENCB_set configures |callback| to call |f| and sets |callout->arg| to
  * |arg|. */
-void BN_GENCB_set(BN_GENCB *callback,
-                  int (*f)(int event, int n, struct bn_gencb_st *),
-                  void *arg);
+OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback,
+                                 int (*f)(int event, int n,
+                                          struct bn_gencb_st *),
+                                 void *arg);
 
 /* BN_GENCB_call calls |callback|, if not NULL, and returns the return value of
  * the callback, or 1 if |callback| is NULL. */
-int BN_GENCB_call(BN_GENCB *callback, int event, int n);
+OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n);
 
 /* BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe
  * is non-zero then the prime will be such that (ret-1)/2 is also a prime.
@@ -590,8 +599,9 @@
  * If |cb| is not NULL, it will be called during processing to give an
  * indication of progress. See the comments for |BN_GENCB|. It returns one on
  * success and zero otherwise. */
-int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
-                         const BIGNUM *rem, BN_GENCB *cb);
+OPENSSL_EXPORT int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
+                                        const BIGNUM *add, const BIGNUM *rem,
+                                        BN_GENCB *cb);
 
 /* BN_prime_checks is magic value that can be used as the |checks| argument to
  * the primality testing functions in order to automatically select a number of
@@ -612,9 +622,10 @@
  * The function returns one on success and zero on error.
  *
  * (If you are unsure whether you want |do_trial_division|, don't set it.) */
-int BN_primality_test(int *is_probably_prime, const BIGNUM *candidate,
-                      int checks, BN_CTX *ctx, int do_trial_division,
-                      BN_GENCB *cb);
+OPENSSL_EXPORT int BN_primality_test(int *is_probably_prime,
+                                     const BIGNUM *candidate, int checks,
+                                     BN_CTX *ctx, int do_trial_division,
+                                     BN_GENCB *cb);
 
 /* BN_is_prime_fasttest_ex returns one if |candidate| is probably a prime
  * number by the Miller-Rabin test, zero if it's certainly not and -1 on error.
@@ -627,33 +638,35 @@
  * called during the checking process. See the comment above |BN_GENCB|.
  *
  * WARNING: deprecated. Use |BN_primality_test|. */
-int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx,
-                            int do_trial_division, BN_GENCB *cb);
+OPENSSL_EXPORT int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks,
+                                           BN_CTX *ctx, int do_trial_division,
+                                           BN_GENCB *cb);
 
 /* BN_is_prime_ex acts the same as |BN_is_prime_fasttest_ex| with
  * |do_trial_division| set to zero.
  *
  * WARNING: deprecated: Use |BN_primality_test|. */
-int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx,
-                   BN_GENCB *cb);
+OPENSSL_EXPORT int BN_is_prime_ex(const BIGNUM *candidate, int checks,
+                                  BN_CTX *ctx, BN_GENCB *cb);
 
 
 /* Number theory functions */
 
 /* BN_gcd sets |r| = gcd(|a|, |b|). It returns one on success and zero
  * otherwise. */
-int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                          BN_CTX *ctx);
 
 /* BN_mod_inverse sets |out| equal to |a|^-1, mod |n|. If either of |a| or |n|
  * have |BN_FLG_CONSTTIME| set then the operation is performed in constant
  * time. If |out| is NULL, a fresh BIGNUM is allocated. It returns the result
  * or NULL on error. */
-BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
-                       BN_CTX *ctx);
+OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a,
+                                      const BIGNUM *n, BN_CTX *ctx);
 
 /* BN_kronecker returns the Kronecker symbol of |a| and |b| (which is -1, 0 or
  * 1), or -2 on error. */
-int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
 
 
 /* Montgomery arithmetic. */
@@ -662,22 +675,24 @@
  * Montgomery domain. */
 
 /* BN_MONT_CTX_new returns a fresh BN_MONT_CTX or NULL on allocation failure. */
-BN_MONT_CTX *BN_MONT_CTX_new(void);
+OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void);
 
 /* BN_MONT_CTX_init initialises a stack allocated |BN_MONT_CTX|. */
-void BN_MONT_CTX_init(BN_MONT_CTX *mont);
+OPENSSL_EXPORT void BN_MONT_CTX_init(BN_MONT_CTX *mont);
 
 /* BN_MONT_CTX_free frees the contexts of |mont| and, if it was originally
  * allocated with |BN_MONT_CTX_new|, |mont| itself. */
-void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont);
 
 /* BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or
  * NULL on error. */
-BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,
+                                             BN_MONT_CTX *from);
 
 /* BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It
  * returns one on success and zero on error. */
-int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod,
+                                   BN_CTX *ctx);
 
 /* BN_MONT_CTX_set_locked takes the lock indicated by |lock| and checks whether
  * |*pmont| is NULL. If so, it creates a new |BN_MONT_CTX| and sets the modulus
@@ -685,24 +700,26 @@
  * error.
  *
  * If |*pmont| is already non-NULL then the existing value is returned. */
-BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
-                                    const BIGNUM *mod, BN_CTX *ctx);
+OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont,
+                                                   int lock, const BIGNUM *mod,
+                                                   BN_CTX *ctx);
 
 /* BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. It
  * returns one on success and zero on error. */
-int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
-                     BN_CTX *ctx);
+OPENSSL_EXPORT int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a,
+                                    const BN_MONT_CTX *mont, BN_CTX *ctx);
 
 /* BN_from_montgomery sets |ret| equal to |a| * R^-1, i.e. translates values
  * out of the Montgomery domain. It returns one on success or zero on error. */
-int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
-                       BN_CTX *ctx);
+OPENSSL_EXPORT int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a,
+                                      const BN_MONT_CTX *mont, BN_CTX *ctx);
 
 /* BN_mod_mul_montgomery set |r| equal to |a| * |b|, in the Montgomery domain.
  * Both |a| and |b| must already be in the Montgomery domain (by
  * |BN_to_montgomery|). It returns one on success or zero on error. */
-int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-                          const BN_MONT_CTX *mont, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a,
+                                         const BIGNUM *b,
+                                         const BN_MONT_CTX *mont, BN_CTX *ctx);
 
 
 /* Exponentiation. */
@@ -710,27 +727,31 @@
 /* BN_exp sets |r| equal to |a|^{|p|}. It does so with a square-and-multiply
  * algorithm that leaks side-channel information. It returns one on success or
  * zero otherwise. */
-int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+OPENSSL_EXPORT int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                          BN_CTX *ctx);
 
 /* BN_mod_exp sets |r| equal to |a|^{|p|} mod |m|. It does so with the best
  * algorithm for the values provided and can run in constant time if
  * |BN_FLG_CONSTTIME| is set for |p|. It returns one on success or zero
  * otherwise. */
-int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
-               BN_CTX *ctx);
+OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                              const BIGNUM *m, BN_CTX *ctx);
 
-int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                                   const BIGNUM *m, BN_CTX *ctx,
+                                   BN_MONT_CTX *m_ctx);
 
-int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-                              const BIGNUM *m, BN_CTX *ctx,
-                              BN_MONT_CTX *in_mont);
+OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a,
+                                             const BIGNUM *p, const BIGNUM *m,
+                                             BN_CTX *ctx, BN_MONT_CTX *in_mont);
 
-int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
-                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
-                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
-                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+                                        const BIGNUM *m, BN_CTX *ctx,
+                                        BN_MONT_CTX *m_ctx);
+OPENSSL_EXPORT int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1,
+                                    const BIGNUM *p1, const BIGNUM *a2,
+                                    const BIGNUM *p2, const BIGNUM *m,
+                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 
 
 /* Private functions */
diff --git a/include/openssl/buf.h b/include/openssl/buf.h
index d1e63f2..1248214 100644
--- a/include/openssl/buf.h
+++ b/include/openssl/buf.h
@@ -72,40 +72,40 @@
 };
 
 /* BUF_MEM_new creates a new BUF_MEM which has no allocated data buffer. */
-BUF_MEM *BUF_MEM_new(void);
+OPENSSL_EXPORT BUF_MEM *BUF_MEM_new(void);
 
 /* BUF_MEM_free frees |buf->data| if needed and then frees |buf| itself. */
-void BUF_MEM_free(BUF_MEM *buf);
+OPENSSL_EXPORT void BUF_MEM_free(BUF_MEM *buf);
 
 /* BUF_MEM_grow ensures that |buf| has length |len| and allocates memory if
  * needed. If the length of |buf| increased, the new bytes are filled with
  * zeros. It returns the length of |buf|, or zero if there's an error. */
-size_t BUF_MEM_grow(BUF_MEM *buf, size_t len);
+OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len);
 
 /* BUF_MEM_grow_clean acts the same as |BUF_MEM_grow|, but clears the previous
  * contents of memory if reallocing. */
-size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
 
 /* BUF_strdup returns an allocated, duplicate of |str|. */
-char *BUF_strdup(const char *str);
+OPENSSL_EXPORT char *BUF_strdup(const char *str);
 
 /* BUF_strnlen returns the number of characters in |str|, excluding the NUL
  * byte, but at most |max_len|. This function never reads more than |max_len|
  * bytes from |str|. */
-size_t BUF_strnlen(const char *str, size_t max_len);
+OPENSSL_EXPORT size_t BUF_strnlen(const char *str, size_t max_len);
 
 /* BUF_strndup returns an allocated, duplicate of |str|, which is, at most,
  * |size| bytes. The result is always NUL terminated. */
-char *BUF_strndup(const char *str, size_t size);
+OPENSSL_EXPORT char *BUF_strndup(const char *str, size_t size);
 
 /* BUF_memdup returns an allocated, duplicate of |size| bytes from |data|. */
-void *BUF_memdup(const void *data, size_t size);
+OPENSSL_EXPORT void *BUF_memdup(const void *data, size_t size);
 
 /* BUF_strlcpy acts like strlcpy(3). */
-size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size);
+OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size);
 
 /* BUF_strlcat acts like strlcat(3). */
-size_t BUF_strlcat(char *dst, const char *src, size_t size);
+OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t size);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h
index 544a5d5..510ef7e 100644
--- a/include/openssl/bytestring.h
+++ b/include/openssl/bytestring.h
@@ -41,24 +41,24 @@
 
 /* CBS_init sets |cbs| to point to |data|. It does not take ownership of
  * |data|. */
-void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
+OPENSSL_EXPORT void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
 
 /* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
  * otherwise. */
-int CBS_skip(CBS *cbs, size_t len);
+OPENSSL_EXPORT int CBS_skip(CBS *cbs, size_t len);
 
 /* CBS_data returns a pointer to the contains of |cbs|. */
-const uint8_t *CBS_data(const CBS *cbs);
+OPENSSL_EXPORT const uint8_t *CBS_data(const CBS *cbs);
 
 /* CBS_len returns the number of bytes remaining in |cbs|. */
-size_t CBS_len(const CBS *cbs);
+OPENSSL_EXPORT size_t CBS_len(const CBS *cbs);
 
 /* CBS_stow copies the current contents of |cbs| into |*out_ptr| and
  * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
  * OPENSSL_free. It returns one on success and zero on allocation failure. On
  * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty,
  * |*out_ptr| will be NULL. */
-int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
+OPENSSL_EXPORT int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
 
 /* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
  * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
@@ -67,51 +67,52 @@
  *
  * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
  * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. */
-int CBS_strdup(const CBS *cbs, char **out_ptr);
+OPENSSL_EXPORT int CBS_strdup(const CBS *cbs, char **out_ptr);
 
 /* CBS_contains_zero_byte returns one if the current contents of |cbs| contains
  * a NUL byte and zero otherwise. */
-int CBS_contains_zero_byte(const CBS *cbs);
+OPENSSL_EXPORT int CBS_contains_zero_byte(const CBS *cbs);
 
 /* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
  * starting at |data|. If they're equal, it returns one, otherwise zero. If the
  * lengths match, it uses a constant-time comparison. */
-int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len);
+OPENSSL_EXPORT int CBS_mem_equal(const CBS *cbs, const uint8_t *data,
+                                 size_t len);
 
 /* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
  * returns one on success and zero on error. */
-int CBS_get_u8(CBS *cbs, uint8_t *out);
+OPENSSL_EXPORT int CBS_get_u8(CBS *cbs, uint8_t *out);
 
 /* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
  * advances |cbs|. It returns one on success and zero on error. */
-int CBS_get_u16(CBS *cbs, uint16_t *out);
+OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
 
 /* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
  * advances |cbs|. It returns one on success and zero on error. */
-int CBS_get_u24(CBS *cbs, uint32_t *out);
+OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out);
 
 /* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
  * and advances |cbs|. It returns one on success and zero on error. */
-int CBS_get_u32(CBS *cbs, uint32_t *out);
+OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out);
 
 /* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
  * |cbs|. It returns one on success and zero on error. */
-int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
+OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
 
 /* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
  * length-prefixed value from |cbs| and advances |cbs| over it. It returns one
  * on success and zero on error. */
-int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
+OPENSSL_EXPORT int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
 
 /* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
  * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
  * returns one on success and zero on error. */
-int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
+OPENSSL_EXPORT int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
 
 /* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
  * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
  * returns one on success and zero on error. */
-int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
+OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
 
 
 /* Parsing ASN.1 */
@@ -135,7 +136,7 @@
  * on error.
  *
  * Tag numbers greater than 31 are not supported. */
-int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
+OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
 
 /* CBS_get_asn1_ber sets |*out| to the contents of BER-encoded, ASN.1 element
  * (not including tag and length bytes) and advances |cbs| over it. The ASN.1
@@ -145,11 +146,11 @@
  * indefinite-length elements may be processed by this function.
  *
  * Tag numbers greater than 31 are not supported. */
-int CBS_get_asn1_ber(CBS *cbs, CBS *out, unsigned tag_value);
+OPENSSL_EXPORT int CBS_get_asn1_ber(CBS *cbs, CBS *out, unsigned tag_value);
 
 /* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
  * ASN.1 header bytes too. */
-int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
+OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
 
 
 /* CRYPTO ByteBuilder.
@@ -193,17 +194,17 @@
 /* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
  * needed, the |initial_capacity| is just a hint. It returns one on success or
  * zero on error. */
-int CBB_init(CBB *cbb, size_t initial_capacity);
+OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity);
 
 /* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
  * |buf| cannot grow, trying to write more than |len| bytes will cause CBB
  * functions to fail. It returns one on success or zero on error. */
-int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
+OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
 
 /* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
  * writing to the same buffer. This should be used in an error case where a
  * serialisation is abandoned. */
-void CBB_cleanup(CBB *cbb);
+OPENSSL_EXPORT void CBB_cleanup(CBB *cbb);
 
 /* CBB_finish completes any pending length prefix and sets |*out_data| to a
  * malloced buffer and |*out_len| to the length of that buffer. The caller
@@ -213,48 +214,48 @@
  * It can only be called on a "top level" |CBB|, i.e. one initialised with
  * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
  * error. */
-int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
+OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
 
 /* CBB_flush causes any pending length prefixes to be written out and any child
  * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
  * on error. */
-int CBB_flush(CBB *cbb);
+OPENSSL_EXPORT int CBB_flush(CBB *cbb);
 
 /* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
  * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
  * length. It returns one on success or zero on error. */
-int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
+OPENSSL_EXPORT int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
 
 /* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
  * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
  * big-endian length. It returns one on success or zero on error. */
-int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
+OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
 
 /* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
  * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
  * big-endian length. It returns one on success or zero on error. */
-int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
+OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
 
 /* 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. */
-int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
 
 /* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
  * success and zero otherwise. */
-int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
+OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
 
 /* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
  * success and zero otherwise. */
-int CBB_add_u8(CBB *cbb, uint8_t value);
+OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value);
 
 /* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
  * returns one on success and zero otherwise. */
-int CBB_add_u16(CBB *cbb, uint16_t value);
+OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
 
 /* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
  * returns one on success and zero otherwise. */
-int CBB_add_u24(CBB *cbb, uint32_t value);
+OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 19988aa..92cec76 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -72,28 +72,28 @@
  * The following functions return |EVP_CIPHER| objects that implement the named
  * cipher algorithm. */
 
-const EVP_CIPHER *EVP_rc4(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void);
 
-const EVP_CIPHER *EVP_des_cbc(void);
-const EVP_CIPHER *EVP_des_ede3_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void);
 
-const EVP_CIPHER *EVP_aes_128_ecb(void);
-const EVP_CIPHER *EVP_aes_128_cbc(void);
-const EVP_CIPHER *EVP_aes_128_ctr(void);
-const EVP_CIPHER *EVP_aes_128_gcm(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ctr(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void);
 
-const EVP_CIPHER *EVP_aes_256_ecb(void);
-const EVP_CIPHER *EVP_aes_256_cbc(void);
-const EVP_CIPHER *EVP_aes_256_ctr(void);
-const EVP_CIPHER *EVP_aes_256_gcm(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void);
 
 /* EVP_enc_null returns a 'cipher' that passes plaintext through as
  * ciphertext. */
-const EVP_CIPHER *EVP_enc_null(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void);
 
 /* EVP_get_cipherbynid returns the cipher corresponding to the given NID, or
  * NULL if no such cipher is known. */
-const EVP_CIPHER *EVP_get_cipherbynid(int nid);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbynid(int nid);
 
 
 /* Cipher context allocation.
@@ -102,23 +102,24 @@
  * progress. */
 
 /* EVP_CIPHER_CTX_init initialises an, already allocated, |EVP_CIPHER_CTX|. */
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_new allocates a fresh |EVP_CIPHER_CTX|, calls
  * |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. */
-EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+OPENSSL_EXPORT EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
 
 /* EVP_CIPHER_CTX_cleanup frees any memory referenced by |ctx|. It returns one
  * on success and zero otherwise. */
-int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_free calls |EVP_CIPHER_CTX_cleanup| on |ctx| and then frees
  * |ctx| itself. */
-void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_copy sets |out| to be a duplicate of the current state of
  * |in|. The |out| argument must have been previously initialised. */
-int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
+OPENSSL_EXPORT int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out,
+                                       const EVP_CIPHER_CTX *in);
 
 
 /* Cipher context configuration. */
@@ -130,17 +131,20 @@
  * as the key and |iv| as the IV (if any). These should have the correct
  * lengths given by |EVP_CIPHER_key_length| and |EVP_CIPHER_iv_length|. It
  * returns one on success and zero on error. */
-int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-                      ENGINE *engine, const uint8_t *key, const uint8_t *iv,
-                      int enc);
+OPENSSL_EXPORT int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,
+                                     const EVP_CIPHER *cipher, ENGINE *engine,
+                                     const uint8_t *key, const uint8_t *iv,
+                                     int enc);
 
 /* EVP_EncryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to one. */
-int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-                       ENGINE *impl, const uint8_t *key, const uint8_t *iv);
+OPENSSL_EXPORT int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
+                                      const EVP_CIPHER *cipher, ENGINE *impl,
+                                      const uint8_t *key, const uint8_t *iv);
 
 /* EVP_DecryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to zero. */
-int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-                       ENGINE *impl, const uint8_t *key, const uint8_t *iv);
+OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
+                                      const EVP_CIPHER *cipher, ENGINE *impl,
+                                      const uint8_t *key, const uint8_t *iv);
 
 
 /* Cipher operations. */
@@ -149,8 +153,9 @@
  * of output bytes may be up to |in_len| plus the block length minus one and
  * |out| must have sufficient space. The number of bytes actually output is
  * written to |*out_len|. It returns one on success and zero otherwise. */
-int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
-                      const uint8_t *in, int in_len);
+OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                                     int *out_len, const uint8_t *in,
+                                     int in_len);
 
 /* EVP_EncryptFinal_ex writes at most a block of ciphertext to |out| and sets
  * |*out_len| to the number of bytes written. If padding is enabled (the
@@ -158,14 +163,16 @@
  * padding is disabled (with |EVP_CIPHER_CTX_set_padding|) then any partial
  * block remaining will cause an error. The function returns one on success and
  * zero otherwise. */
-int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len);
+OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                                       int *out_len);
 
 /* EVP_DecryptUpdate decrypts |in_len| bytes from |in| to |out|. The number of
  * output bytes may be up to |in_len| plus the block length minus one and |out|
  * must have sufficient space. The number of bytes actually output is written
  * to |*out_len|. It returns one on success and zero otherwise. */
-int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
-                      const uint8_t *in, int in_len);
+OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                                     int *out_len, const uint8_t *in,
+                                     int in_len);
 
 /* EVP_DecryptFinal_ex writes at most a block of ciphertext to |out| and sets
  * |*out_len| to the number of bytes written. If padding is enabled (the
@@ -173,106 +180,112 @@
  *
  * WARNING: it is unsafe to call this function with unauthenticted
  * ciphertext if padding is enabled. */
-int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len);
+OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                       int *out_len);
 
 /* EVP_Cipher performs a one-shot encryption/decryption operation. No partial
  * blocks etc are maintained between calls. It returns the number of bytes
  * written or -1 on error.
  *
  * WARNING: this differs from the usual return value convention. */
-int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
-               size_t in_len);
+OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                              const uint8_t *in, size_t in_len);
 
 /* EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate|
  * depending on how |ctx| has been setup. */
-int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
-                     const uint8_t *in, int in_len);
+OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                                    int *out_len, const uint8_t *in,
+                                    int in_len);
 
 /* EVP_CipherFinal_ex calls either |EVP_EncryptFinal_ex| or
  * |EVP_DecryptFinal_ex| depending on how |ctx| has been setup. */
-int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len);
+OPENSSL_EXPORT int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out,
+                                      int *out_len);
 
 
 /* Cipher context accessors. */
 
 /* EVP_CIPHER_CTX_cipher returns the |EVP_CIPHER| underlying |ctx|, or NULL if
  * none has been set. */
-const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_CIPHER_CTX_cipher(
+    const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_nid returns a NID identifying the |EVP_CIPHER| underlying
  * |ctx| (e.g. |NID_rc4|). It will crash if no cipher has been configured. */
-int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher
  * underlying |ctx|, or one if the cipher is a stream cipher. It will crash if
  * no cipher has been configured. */
-unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_key_length returns the key size, in bytes, of the cipher
  * underlying |ctx| or zero if no cipher has been configured. */
-unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_iv_length returns the IV size, in bytes, of the cipher
  * underlying |ctx|. It will crash if no cipher has been configured. */
-unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_get_app_data returns the opaque, application data pointer for
  * |ctx|, or NULL if none has been set. */
-void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_set_app_data sets the opaque, application data pointer for
  * |ctx| to |data|. */
-void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+OPENSSL_EXPORT void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx,
+                                                void *data);
 
 /* EVP_CIPHER_CTX_flags returns a value which is the OR of zero or more
  * |EVP_CIPH_*| flags. It will crash if no cipher has been configured. */
-uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_mode returns one of the |EVP_CIPH_*| cipher mode values
  * enumerated below. It will crash if no cipher has been configured. */
-uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx);
+OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx);
 
 /* EVP_CIPHER_CTX_ctrl is an |ioctl| like function. The |command| argument
  * should be one of the |EVP_CTRL_*| values. The |arg| and |ptr| arguments are
  * specific to the command in question. */
-int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr);
+OPENSSL_EXPORT int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command,
+                                       int arg, void *ptr);
 
 /* EVP_CIPHER_CTX_set_padding sets whether padding is enabled for |ctx| and
  * returns one. Pass a non-zero |pad| to enable padding (the default) or zero
  * to disable. */
-int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad);
+OPENSSL_EXPORT int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad);
 
 
 /* Cipher accessors. */
 
 /* EVP_CIPHER_nid returns a NID identifing |cipher|. (For example,
  * |NID_rc4|.) */
-int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_name returns the short name for |cipher| or NULL if no name is
  * known. */
-const char *EVP_CIPHER_name(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT const char *EVP_CIPHER_name(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_block_size returns the block size, in bytes, for |cipher|, or one
  * if |cipher| is a stream cipher. */
-unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_key_length returns the key size, in bytes, for |cipher|. If
  * |cipher| can take a variable key length then this function returns the
  * default key length and |EVP_CIPHER_flags| will return a value with
  * |EVP_CIPH_VARIABLE_LENGTH| set. */
-unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_iv_length returns the IV size, in bytes, of |cipher|, or zero if
  * |cipher| doesn't take an IV. */
-unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_flags returns a value which is the OR of zero or more
  * |EVP_CIPH_*| flags. */
-uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher);
 
 /* EVP_CIPHER_mode returns one of the cipher mode values enumerated below. */
-uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher);
+OPENSSL_EXPORT uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher);
 
 
 /* Key derivation. */
@@ -281,9 +294,10 @@
  * |md| |count| times using |data| and |salt|. On entry, the |key| and |iv|
  * buffers must have enough space to hold a key and IV for |type|. It returns
  * the length of the key on success or zero on error. */
-int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
-                   const uint8_t *salt, const uint8_t *data, size_t data_len,
-                   unsigned count, uint8_t *key, uint8_t *iv);
+OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+                                  const uint8_t *salt, const uint8_t *data,
+                                  size_t data_len, unsigned count, uint8_t *key,
+                                  uint8_t *iv);
 
 
 /* Cipher modes (for |EVP_CIPHER_mode|). */
diff --git a/include/openssl/cpu.h b/include/openssl/cpu.h
index 02f6da2..7423338 100644
--- a/include/openssl/cpu.h
+++ b/include/openssl/cpu.h
@@ -87,12 +87,12 @@
 /* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. Note
  * that |OPENSSL_armcap_P| also exists and contains the same information in a
  * form that's easier for assembly to use. */
-char CRYPTO_is_NEON_capable();
+OPENSSL_EXPORT char CRYPTO_is_NEON_capable();
 
 /* CRYPTO_set_NEON_capable sets the return value of |CRYPTO_is_NEON_capable|.
  * By default, unless the code was compiled with |-mfpu=neon|, NEON is assumed
  * not to be present. It is not autodetected. */
-void CRYPTO_set_NEON_capable(char neon_capable);
+OPENSSL_EXPORT void CRYPTO_set_NEON_capable(char neon_capable);
 #endif  /* OPENSSL_ARM */
 
 
diff --git a/include/openssl/des.h b/include/openssl/des.h
index a43e1d6..748f1c8 100644
--- a/include/openssl/des.h
+++ b/include/openssl/des.h
@@ -88,28 +88,32 @@
 #define DES_PCBC_MODE 1
 
 /* DES_set_key performs a key schedule and initialises |schedule| with |key|. */
-void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule);
+OPENSSL_EXPORT void DES_set_key(const DES_cblock *key,
+                                DES_key_schedule *schedule);
 
 /* DES_ecb_encrypt encrypts (or decrypts, if |is_encrypt| is |DES_DECRYPT|) a
  * single DES block (8 bytes) from in to out, using the key configured in
  * |schedule|. */
-void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out,
-                     const DES_key_schedule *schedule, int is_encrypt);
+OPENSSL_EXPORT void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out,
+                                    const DES_key_schedule *schedule,
+                                    int is_encrypt);
 
 /* DES_ncbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
  * bytes from |in| to |out| with DES in CBC mode. */
-void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                      const DES_key_schedule *schedule, DES_cblock *ivec,
-                      int enc);
+OPENSSL_EXPORT void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out,
+                                     size_t len,
+                                     const DES_key_schedule *schedule,
+                                     DES_cblock *ivec, int enc);
 
 /* DES_ede3_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
  * bytes from |in| to |out| with 3DES in CBC mode. 3DES uses three keys, thus
  * the function takes three different |DES_key_schedule|s. */
-void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
-                          const DES_key_schedule *ks1,
-                          const DES_key_schedule *ks2,
-                          const DES_key_schedule *ks3, DES_cblock *ivec,
-                          int enc);
+OPENSSL_EXPORT void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out,
+                                         size_t len,
+                                         const DES_key_schedule *ks1,
+                                         const DES_key_schedule *ks2,
+                                         const DES_key_schedule *ks3,
+                                         DES_cblock *ivec, int enc);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index d1b84f9..84fb456 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -74,17 +74,17 @@
 /* Allocation and destruction. */
 
 /* DH_new returns a new, empty DH object or NULL on error. */
-DH *DH_new(void);
+OPENSSL_EXPORT DH *DH_new(void);
 
 /* DH_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
-DH *DH_new_method(const ENGINE *engine);
+OPENSSL_EXPORT DH *DH_new_method(const ENGINE *engine);
 
 /* DH_free decrements the reference count of |dh| and frees it if the reference
  * count drops to zero. */
-void DH_free(DH *dh);
+OPENSSL_EXPORT void DH_free(DH *dh);
 
 /* DH_up_ref increments the reference count of |dh|. */
-int DH_up_ref(DH *dh);
+OPENSSL_EXPORT int DH_up_ref(DH *dh);
 
 
 /* Standard parameters.
@@ -95,9 +95,9 @@
 
 /* These parameters are taken from RFC 5114. */
 
-DH *DH_get_1024_160(const ENGINE *engine);
-DH *DH_get_2048_224(const ENGINE *engine);
-DH *DH_get_2048_256(const ENGINE *engine);
+OPENSSL_EXPORT DH *DH_get_1024_160(const ENGINE *engine);
+OPENSSL_EXPORT DH *DH_get_2048_224(const ENGINE *engine);
+OPENSSL_EXPORT DH *DH_get_2048_256(const ENGINE *engine);
 
 
 /* Parameter generation. */
@@ -113,27 +113,28 @@
  * |bn.h| about this. In addition to the callback invocations from |BN|, |cb|
  * will also be called with |event| equal to three when the generation is
  * complete. */
-int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator,
-                              BN_GENCB *cb);
+OPENSSL_EXPORT int DH_generate_parameters_ex(DH *dh, int prime_bits,
+                                             int generator, BN_GENCB *cb);
 
 
 /* Diffie-Hellman operations. */
 
 /* DH_generate_key generates a new, random, private key and stores it in
  * |dh|. It returns one on success and zero on error. */
-int DH_generate_key(DH *dh);
+OPENSSL_EXPORT int DH_generate_key(DH *dh);
 
 /* DH_compute_key calculates the shared key between |dh| and |peers_key| and
  * writes it as a big-endian integer into |out|, which must have |DH_size|
  * bytes of space. It returns the number of bytes written, or a negative number
  * on error. */
-ssize_t DH_compute_key(uint8_t *out, const BIGNUM *peers_key, DH *dh);
+OPENSSL_EXPORT ssize_t
+    DH_compute_key(uint8_t *out, const BIGNUM *peers_key, DH *dh);
 
 
 /* Utility functions. */
 
 /* DH_size returns the number of bytes in the DH group's prime. */
-int DH_size(const DH *dh);
+OPENSSL_EXPORT int DH_size(const DH *dh);
 
 #define DH_CHECK_P_NOT_PRIME 0x01
 #define DH_CHECK_P_NOT_SAFE_PRIME 0x02
@@ -148,7 +149,7 @@
  * |*out_flags| was successfully set and zero on error.
  *
  * Note: these checks may be quite computationally expensive. */
-int DH_check(const DH *dh, int *out_flags);
+OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags);
 
 #define DH_CHECK_PUBKEY_TOO_SMALL 1
 #define DH_CHECK_PUBKEY_TOO_LARGE 2
@@ -157,11 +158,12 @@
  * DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it
  * finds any errors. It returns one if |*out_flags| was successfully set and
  * zero on error. */
-int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags);
+OPENSSL_EXPORT int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key,
+                                    int *out_flags);
 
 /* DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into
  * it. It returns the new |DH| or NULL on error. */
-DH *DHparams_dup(const DH *dh);
+OPENSSL_EXPORT DH *DHparams_dup(const DH *dh);
 
 
 /* ASN.1 functions. */
@@ -172,23 +174,25 @@
  * then the result is written directly into |*ret|, otherwise a fresh |DH| is
  * allocated. On successful exit, |*inp| is advanced past the DER structure. It
  * returns the result or NULL on error. */
-DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len);
+OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len);
 
 /* i2d_DHparams marshals |in| to an ASN.1, DER structure. If |outp| is not NULL
  * then the result is written to |*outp| and |*outp| is advanced just past the
  * output. It returns the number of bytes in the result, whether written or
  * not, or a negative value on error. */
-int i2d_DHparams(const DH *in, unsigned char **outp);
+OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp);
 
 
 /* ex_data functions.
  *
  * These functions are wrappers. See |ex_data.h| for details. */
 
-int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int DH_set_ex_data(DH *d, int idx, void *arg);
-void *DH_get_ex_data(DH *d, int idx);
+OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp,
+                                       CRYPTO_EX_new *new_func,
+                                       CRYPTO_EX_dup *dup_func,
+                                       CRYPTO_EX_free *free_func);
+OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg);
+OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx);
 
 
 /* dh_method contains function pointers to override the implementation of DH.
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
index 9a91908..76d6677 100644
--- a/include/openssl/digest.h
+++ b/include/openssl/digest.h
@@ -76,20 +76,20 @@
  * The following functions return |EVP_MD| objects that implement the named hash
  * function. */
 
-const EVP_MD *EVP_md5(void);
-const EVP_MD *EVP_sha1(void);
-const EVP_MD *EVP_sha224(void);
-const EVP_MD *EVP_sha256(void);
-const EVP_MD *EVP_sha384(void);
-const EVP_MD *EVP_sha512(void);
+OPENSSL_EXPORT const EVP_MD *EVP_md5(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha1(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha224(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha256(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha384(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
 
 /* EVP_get_digestbynid returns an |EVP_MD| for the given NID, or NULL if no
  * such digest is known. */
-const EVP_MD *EVP_get_digestbynid(int nid);
+OPENSSL_EXPORT const EVP_MD *EVP_get_digestbynid(int nid);
 
 /* EVP_get_digestbyobj returns an |EVP_MD| for the given |ASN1_OBJECT|, or NULL
  * if no such digest is known. */
-const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj);
+OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj);
 
 
 /* Digest contexts.
@@ -98,22 +98,22 @@
  * progress. */
 
 /* EVP_MD_CTX_init initialises an, already allocated, |EVP_MD_CTX|. */
-void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+OPENSSL_EXPORT void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_create allocates and initialises a fresh |EVP_MD_CTX| and returns
  * it, or NULL on allocation failure. */
-EVP_MD_CTX *EVP_MD_CTX_create(void);
+OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_create(void);
 
 /* EVP_MD_CTX_cleanup frees any resources owned by |ctx| and resets it to a
  * freshly initialised state. It does not free |ctx| itself. It returns one. */
-int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+OPENSSL_EXPORT int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_destroy calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. */
-void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+OPENSSL_EXPORT void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_copy_ex sets |out|, which must already be initialised, to be a
  * copy of |in|. It returns one on success and zero on error. */
-int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+OPENSSL_EXPORT int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
 
 
 /* Digest operations. */
@@ -121,15 +121,17 @@
 /* EVP_DigestInit_ex configures |ctx|, which must already have been
  * initialised, for a fresh hashing operation using |type|. It returns one on
  * success and zero otherwise. */
-int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine);
+OPENSSL_EXPORT int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
+                                     ENGINE *engine);
 
 /* EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is
  * initialised before use. */
-int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
 
 /* EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation
  * in |ctx|. It returns one on success and zero otherwise. */
-int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
+                                    size_t len);
 
 /* EVP_MAX_MD_SIZE is the largest digest size supported. Functions that output
  * a digest generally require the buffer have at least this much space. */
@@ -141,20 +143,22 @@
  * on success and zero otherwise. After this call, the hash cannot be updated
  * or finished again until |EVP_DigestFinal_ex| is called to start another
  * hashing operation. */
-int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out,
-                       unsigned int *out_size);
+OPENSSL_EXPORT int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out,
+                                      unsigned int *out_size);
 
 /* EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that
  * |EVP_MD_CTX_cleanup| is called on |ctx| before returning. */
-int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *out_size);
+OPENSSL_EXPORT int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out,
+                                   unsigned int *out_size);
 
 /* EVP_Digest performs a complete hashing operation in one call. It hashes
  * |len| bytes from |data| and writes the digest to |md_out|. At most
  * |EVP_MAX_MD_SIZE| bytes are written. If |out_size| is not NULL then
  * |*out_size| is set to the number of bytes written. It returns one on success
  * and zero otherwise. */
-int EVP_Digest(const void *data, size_t len, uint8_t *md_out,
-               unsigned int *md_out_size, const EVP_MD *type, ENGINE *impl);
+OPENSSL_EXPORT int EVP_Digest(const void *data, size_t len, uint8_t *md_out,
+                              unsigned int *md_out_size, const EVP_MD *type,
+                              ENGINE *impl);
 
 
 /* Digest function accessors.
@@ -163,20 +167,20 @@
  * function. */
 
 /* EVP_MD_type returns a NID identifing |md|. (For example, |NID_md5|.) */
-int EVP_MD_type(const EVP_MD *md);
+OPENSSL_EXPORT int EVP_MD_type(const EVP_MD *md);
 
 /* EVP_MD_name returns the short name for |md| or NULL if no name is known. */
-const char *EVP_MD_name(const EVP_MD *md);
+OPENSSL_EXPORT const char *EVP_MD_name(const EVP_MD *md);
 
 /* EVP_MD_flags returns the flags for |md|, which is a set of |EVP_MD_FLAG_*|
  * values, ORed together. */
-uint32_t EVP_MD_flags(const EVP_MD *md);
+OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md);
 
 /* EVP_MD_size returns the digest size of |md|, in bytes. */
-size_t EVP_MD_size(const EVP_MD *md);
+OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md);
 
 /* EVP_MD_block_size returns the native block-size of |md|. */
-size_t EVP_MD_block_size(const EVP_MD *md);
+OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md);
 
 /* EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a
  * specific public key in order to verify signatures. (For example,
@@ -193,38 +197,39 @@
 
 /* EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of
  * |in|. It returns one on success and zero on error. */
-int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
 
 
 /* Digest operation accessors. */
 
 /* EVP_MD_CTX_md returns the underlying digest function, or NULL if one has not
  * been set. */
-const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_size returns the digest size of |ctx|. It will crash if a digest
  * hasn't been set on |ctx|. */
-unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_block_size returns the block size of the digest function used by
  * |ctx|. It will crash if a digest hasn't been set on |ctx|. */
-unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
  * (For example, |NID_md5|.) It will crash if a digest hasn't been set on
  * |ctx|. */
-int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
+OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
 
 /* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
-void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
+OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
 
 /* EVP_MD_CTX_clear_flags clears any bits from the flags member of |ctx| that
  * are set in |flags|. */
-void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags);
+OPENSSL_EXPORT void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags);
 
 /* EVP_MD_CTX_test_flags returns the AND of |flags| and the flags member of
  * |ctx|. */
-uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, uint32_t flags);
+OPENSSL_EXPORT uint32_t
+    EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, uint32_t flags);
 
 
 struct evp_md_pctx_ops;
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 09fafb0..c8156fa 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -77,17 +77,17 @@
 /* Allocation and destruction. */
 
 /* DSA_new returns a new, empty DSA object or NULL on error. */
-DSA *DSA_new(void);
+OPENSSL_EXPORT DSA *DSA_new(void);
 
 /* DSA_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
-DSA *DSA_new_method(const ENGINE *engine);
+OPENSSL_EXPORT DSA *DSA_new_method(const ENGINE *engine);
 
 /* DSA_free decrements the reference count of |dsa| and frees it if the
  * reference count drops to zero. */
-void DSA_free(DSA *dsa);
+OPENSSL_EXPORT void DSA_free(DSA *dsa);
 
 /* DSA_up_ref increments the reference count of |dsa|. */
-int DSA_up_ref(DSA *dsa);
+OPENSSL_EXPORT int DSA_up_ref(DSA *dsa);
 
 
 /* Parameter generation. */
@@ -109,13 +109,15 @@
  * |event| equal to 2 and 3 at different stages of the process.
  *
  * It returns one on success and zero otherwise. */
-int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed,
-                               size_t seed_len, int *out_counter,
-                               unsigned long *out_h, BN_GENCB *cb);
+OPENSSL_EXPORT int DSA_generate_parameters_ex(DSA *dsa, unsigned bits,
+                                              const uint8_t *seed,
+                                              size_t seed_len, int *out_counter,
+                                              unsigned long *out_h,
+                                              BN_GENCB *cb);
 
 /* DSAparams_dup returns a freshly allocated |DSA| that contains a copy of the
  * parameters from |dsa|. It returns NULL on error. */
-DSA *DSAparams_dup(const DSA *dsa);
+OPENSSL_EXPORT DSA *DSAparams_dup(const DSA *dsa);
 
 
 /* Key generation. */
@@ -123,7 +125,7 @@
 /* DSA_generate_key generates a public/private key pair in |dsa|, which must
  * already have parameters setup. It returns one on success and zero on
  * error. */
-int DSA_generate_key(DSA *dsa);
+OPENSSL_EXPORT int DSA_generate_key(DSA *dsa);
 
 
 /* Signatures. */
@@ -135,14 +137,15 @@
 
 /* DSA_SIG_new returns a freshly allocated, DIG_SIG structure or NULL on error.
  * Both |r| and |s| in the signature will be NULL. */
-DSA_SIG *DSA_SIG_new(void);
+OPENSSL_EXPORT DSA_SIG *DSA_SIG_new(void);
 
 /* DSA_SIG_free frees the contents of |sig| and then frees |sig| itself. */
-void DSA_SIG_free(DSA_SIG *sig);
+OPENSSL_EXPORT void DSA_SIG_free(DSA_SIG *sig);
 
 /* DSA_do_sign returns a signature of the hash in |digest| by the key in |dsa|
  * and returns an allocated, DSA_SIG structure, or NULL on error. */
-DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa);
+OPENSSL_EXPORT DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len,
+                                    DSA *dsa);
 
 /* DSA_do_verify verifies that |sig| is a valid signature, by the public key in
  * |dsa|, of the hash in |digest|. It returns one if so, zero if invalid and -1
@@ -154,8 +157,8 @@
  * Because of this, |DSA_check_signature| is a safer version of this.
  *
  * TODO(fork): deprecate. */
-int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
-                  const DSA *dsa);
+OPENSSL_EXPORT int DSA_do_verify(const uint8_t *digest, size_t digest_len,
+                                 DSA_SIG *sig, const DSA *dsa);
 
 /* DSA_check_signature sets |*out_valid| to zero. Then it verifies that |sig|
  * is a valid signature, by the public key in |dsa| of the hash in |digest|
@@ -163,8 +166,9 @@
  *
  * It returns one if it was able to verify the signature as valid or invalid,
  * and zero on error. */
-int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
-                           size_t digest_len, DSA_SIG *sig, const DSA *dsa);
+OPENSSL_EXPORT int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
+                                          size_t digest_len, DSA_SIG *sig,
+                                          const DSA *dsa);
 
 
 /* ASN.1 signatures.
@@ -179,8 +183,9 @@
  * |out_sig|. It returns one on success and zero otherwise.
  *
  * (The |type| argument is ignored.) */
-int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
-             uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa);
+OPENSSL_EXPORT int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
+                            uint8_t *out_sig, unsigned int *out_siglen,
+                            DSA *dsa);
 
 /* DSA_verify verifies that |sig| is a valid, ASN.1 signature, by the public
  * key in |dsa|, of the hash in |digest|. It returns one if so, zero if invalid
@@ -194,8 +199,9 @@
  * Because of this, |DSA_check_signature| is a safer version of this.
  *
  * TODO(fork): deprecate. */
-int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
-               const uint8_t *sig, size_t sig_len, const DSA *dsa);
+OPENSSL_EXPORT int DSA_verify(int type, const uint8_t *digest,
+                              size_t digest_len, const uint8_t *sig,
+                              size_t sig_len, const DSA *dsa);
 
 /* DSA_check_signature sets |*out_valid| to zero. Then it verifies that |sig|
  * is a valid, ASN.1 signature, by the public key in |dsa|, of the hash in
@@ -203,13 +209,13 @@
  *
  * It returns one if it was able to verify the signature as valid or invalid,
  * and zero on error. */
-int DSA_check_signature(int *out_valid, const uint8_t *digest,
-                        size_t digest_len, const uint8_t *sig, size_t sig_len,
-                        const DSA *dsa);
+OPENSSL_EXPORT int DSA_check_signature(int *out_valid, const uint8_t *digest,
+                                       size_t digest_len, const uint8_t *sig,
+                                       size_t sig_len, const DSA *dsa);
 
 /* DSA_size returns the size, in bytes, of an ASN.1 encoded, DSA signature
  * generated by |dsa|. Parameters must already have been setup in |dsa|. */
-int DSA_size(const DSA *dsa);
+OPENSSL_EXPORT int DSA_size(const DSA *dsa);
 
 
 /* ASN.1 encoding. */
@@ -220,13 +226,14 @@
  * written directly into |*out_sig|, otherwise a fresh |DSA_SIG| is allocated.
  * On successful exit, |*inp| is advanced past the DER structure. It returns
  * the result or NULL on error. */
-DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len);
+OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp,
+                                    long len);
 
 /* i2d_DSA_SIG marshals |in| to an ASN.1, DER structure. If |outp| is not NULL
  * then the result is written to |*outp| and |*outp| is advanced just past the
  * output. It returns the number of bytes in the result, whether written or not,
  * or a negative value on error. */
-int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
+OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
 
 /* d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len|
  * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
@@ -234,13 +241,13 @@
  * written directly into |*out|, otherwise a fresh |DSA| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
 
 /* i2d_DSAPublicKey marshals a public key from |in| to an ASN.1, DER structure.
  * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
  * advanced just past the output. It returns the number of bytes in the result,
  * whether written or not, or a negative value on error. */
-int i2d_DSAPublicKey(const DSA *in, unsigned char **outp);
+OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, unsigned char **outp);
 
 /* d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len|
  * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
@@ -248,13 +255,13 @@
  * written directly into |*out|, otherwise a fresh |DSA| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
 
 /* i2d_DSAPrivateKey marshals a private key from |in| to an ASN.1, DER structure.
  * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
  * advanced just past the output. It returns the number of bytes in the result,
  * whether written or not, or a negative value on error. */
-int i2d_DSAPrivateKey(const DSA *in, unsigned char **outp);
+OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, unsigned char **outp);
 
 /* d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at
  * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
@@ -262,13 +269,13 @@
  * directly into |*out|, otherwise a fresh |DSA| is allocated. On successful
  * exit, |*inp| is advanced past the DER structure. It returns the result or
  * NULL on error. */
-DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
 
 /* i2d_DSAparams marshals DSA parameters from |in| to an ASN.1, DER structure.
  * If |outp| is not NULL then the result is written to |*outp| and |*outp| is
  * advanced just past the output. It returns the number of bytes in the result,
  * whether written or not, or a negative value on error. */
-int i2d_DSAparams(const DSA *in, unsigned char **outp);
+OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, unsigned char **outp);
 
 
 /* Precomputation. */
@@ -280,18 +287,20 @@
  * TODO(fork): decide what to do with this. Since making DSA* opaque there's no
  * way for the user to install them. Also, it forces the DSA* not to be const
  * when passing to the signing function. */
-int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv,
-                   BIGNUM **out_r);
+OPENSSL_EXPORT int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx,
+                                  BIGNUM **out_kinv, BIGNUM **out_r);
 
 
 /* ex_data functions.
  *
  * These functions are wrappers. See |ex_data.h| for details. */
 
-int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int DSA_set_ex_data(DSA *d, int idx, void *arg);
-void *DSA_get_ex_data(const DSA *d, int idx);
+OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp,
+                                        CRYPTO_EX_new *new_func,
+                                        CRYPTO_EX_dup *dup_func,
+                                        CRYPTO_EX_free *free_func);
+OPENSSL_EXPORT int DSA_set_ex_data(DSA *d, int idx, void *arg);
+OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *d, int idx);
 
 
 struct dsa_method {
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 368432e..55f1adf 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -102,105 +102,111 @@
  *   NID_X9_62_prime256v1,
  *   NID_secp384r1,
  *   NID_secp521r1 */
-EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
 
 /* EC_GROUP_free frees |group| and the data that it points to. */
-void EC_GROUP_free(EC_GROUP *group);
+OPENSSL_EXPORT void EC_GROUP_free(EC_GROUP *group);
 
 /* EC_GROUP_copy sets |*dest| equal to |*src|. It returns one on success and
  * zero otherwise. */
-int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src);
+OPENSSL_EXPORT int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src);
 
 /* EC_GROUP_dup returns a fresh |EC_GROUP| which is equal to |a| or NULL on
  * error. */
-EC_GROUP *EC_GROUP_dup(const EC_GROUP *a);
+OPENSSL_EXPORT EC_GROUP *EC_GROUP_dup(const EC_GROUP *a);
 
 /* EC_GROUP_cmp returns one if |a| and |b| are the same group and zero
  * otherwise. */
-int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b);
+OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b);
 
 /* EC_GROUP_get0_generator returns a pointer to the internal |EC_POINT| object
  * in |group| that specifies the generator for the group. */
-const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
 
 /* EC_GROUP_get_order sets |*order| to the order of |group| using |ctx|, if
  * it's not NULL. It returns one on success and zero otherwise. */
-int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order,
+                                      BN_CTX *ctx);
 
 /* EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using
  * |ctx|, if it's not NULL. It returns one on success and zero otherwise. */
-int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group,
+                                         BIGNUM *cofactor, BN_CTX *ctx);
 
 /* EC_GROUP_get_curve_name returns a NID that identifies |group|. */
-int EC_GROUP_get_curve_name(const EC_GROUP *group);
+OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);
 
 /* EC_GROUP_get_degree returns the number of bits needed to represent an
  * element of the field underlying |group|. */
-int EC_GROUP_get_degree(const EC_GROUP *group);
+OPENSSL_EXPORT int EC_GROUP_get_degree(const EC_GROUP *group);
 
 /* EC_GROUP_set_point_conversion_form sets the form that serialised points will
  * take as one of the |POINT_CONVERSION_*| values. */
-void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
-                                        point_conversion_form_t form);
+OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
+    EC_GROUP *group, point_conversion_form_t form);
 
 /* EC_GROUP_precompute_mult precomputes multiplies of the generator in order to
  * speed up operations that involve calculating generator multiples. It returns
  * one on sucess and zero otherwise. If |ctx| is not NULL, it may be used. */
-int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
 
 /* EC_GROUP_have_precompute_mult returns one if |group| contains precomputed
  * generator multiples. */
-int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
+OPENSSL_EXPORT int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
 
 
 /* Points on elliptic curves. */
 
 /* EC_POINT_new returns a fresh |EC_POINT| object in the given group, or NULL
  * on error. */
-EC_POINT *EC_POINT_new(const EC_GROUP *group);
+OPENSSL_EXPORT EC_POINT *EC_POINT_new(const EC_GROUP *group);
 
 /* EC_POINT_free frees |point| and the data that it points to. */
-void EC_POINT_free(EC_POINT *point);
+OPENSSL_EXPORT void EC_POINT_free(EC_POINT *point);
 
 /* EC_POINT_clear_free clears the data that |point| points to, frees it and
  * then frees |point| itself. */
-void EC_POINT_clear_free(EC_POINT *point);
+OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point);
 
 /* EC_POINT_copy sets |*dest| equal to |*src|. It returns one on success and
  * zero otherwise. */
-int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src);
+OPENSSL_EXPORT int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src);
 
 /* EC_POINT_dup returns a fresh |EC_POINT| that contains the same values as
  * |src|, or NULL on error. */
-EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
+OPENSSL_EXPORT EC_POINT *EC_POINT_dup(const EC_POINT *src,
+                                      const EC_GROUP *group);
 
 /* EC_POINT_set_to_infinity sets |point| to be the "point at infinity" for the
  * given group. */
-int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
+OPENSSL_EXPORT int EC_POINT_set_to_infinity(const EC_GROUP *group,
+                                            EC_POINT *point);
 
 /* EC_POINT_is_at_infinity returns one iff |point| is the point at infinity and
  * zero otherwise. */
-int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point);
+OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group,
+                                           const EC_POINT *point);
 
 /* EC_POINT_is_on_curve returns one if |point| is an element of |group| and
  * zero otheriwse. If |ctx| is non-NULL, it may be used. */
-int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
-                         BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group,
+                                        const EC_POINT *point, BN_CTX *ctx);
 
 /* EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero is
  * non-equal and -1 on error. If |ctx| is not NULL, it may be used. */
-int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
-                 BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a,
+                                const EC_POINT *b, BN_CTX *ctx);
 
 /* EC_POINT_make_affine converts |point| to affine form, internally. It returns
  * one on success and zero otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point,
+                                        BN_CTX *ctx);
 
 /* EC_POINTs_make_affine converts |num| points from |points| to affine form,
  * internally. It returns one on success and zero otherwise. If |ctx| is not
  * NULL, it may be used. */
-int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
-                          BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+                                         EC_POINT *points[], BN_CTX *ctx);
 
 
 /* Point conversion. */
@@ -208,64 +214,73 @@
 /* EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of
  * |point| using |ctx|, if it's not NULL. It returns one on success and zero
  * otherwise. */
-int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
-                                        const EC_POINT *point, BIGNUM *x,
-                                        BIGNUM *y, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+                                                       const EC_POINT *point,
+                                                       BIGNUM *x, BIGNUM *y,
+                                                       BN_CTX *ctx);
 
 /* EC_POINT_set_affine_coordinates sets the value of |p| to be (|x|, |y|). The
  * |ctx| argument may be used if not NULL. */
-int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
-                                        const BIGNUM *x, const BIGNUM *y,
-                                        BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
+                                                       EC_POINT *point,
+                                                       const BIGNUM *x,
+                                                       const BIGNUM *y,
+                                                       BN_CTX *ctx);
 
 /* EC_POINT_point2oct serialises |point| into the X9.62 form given by |form|
  * into, at most, |len| bytes at |buf|. It returns the number of bytes written
  * or zero on error if |buf| is non-NULL, else the number of bytes needed. The
  * |ctx| argument may be used if not NULL. */
-size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
-                          point_conversion_form_t form, uint8_t *buf,
-                          size_t len, BN_CTX *ctx);
+OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group,
+                                         const EC_POINT *point,
+                                         point_conversion_form_t form,
+                                         uint8_t *buf, size_t len, BN_CTX *ctx);
 
 /* EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format
  * serialisation in |buf|. It returns one on success and zero otherwise. The
  * |ctx| argument may be used if not NULL. */
-int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
-                       const uint8_t *buf, size_t len, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+                                      const uint8_t *buf, size_t len,
+                                      BN_CTX *ctx);
 
 /* EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with
  * the given |x| coordinate and the y coordinate specified by |y_bit| (see
  * X9.62). It returns one on success and zero otherwise. */
-int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
-                                            EC_POINT *point, const BIGNUM *x,
-                                            int y_bit, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp(
+    const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit,
+    BN_CTX *ctx);
 
 
 /* Group operations. */
 
 /* EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and
  * zero otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-                 const EC_POINT *b, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r,
+                                const EC_POINT *a, const EC_POINT *b,
+                                BN_CTX *ctx);
 
 /* EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and
  * zero otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-                 BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r,
+                                const EC_POINT *a, BN_CTX *ctx);
 
 /* EC_POINT_dbl sets |a| equal to minus |a|. It returns one on success and zero
  * otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a,
+                                   BN_CTX *ctx);
 
 /* EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero
  * otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
-                 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r,
+                                const BIGNUM *n, const EC_POINT *q,
+                                const BIGNUM *m, BN_CTX *ctx);
 
 /* EC_POINTs_mul sets r = generator*n + sum(p[i]*m[i]). It returns one on
  * success and zero otherwise. If |ctx| is not NULL, it may be used. */
-int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
-                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
-                  BN_CTX *ctx);
+OPENSSL_EXPORT int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r,
+                                 const BIGNUM *n, size_t num,
+                                 const EC_POINT *p[], const BIGNUM *m[],
+                                 BN_CTX *ctx);
 
 
 /* Old code expects to get EC_KEY from ec.h. */
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h
index 4a48ffc..d659216 100644
--- a/include/openssl/ec_key.h
+++ b/include/openssl/ec_key.h
@@ -86,88 +86,91 @@
 /* EC key objects. */
 
 /* EC_KEY_new returns a fresh |EC_KEY| object or NULL on error. */
-EC_KEY *EC_KEY_new(void);
+OPENSSL_EXPORT EC_KEY *EC_KEY_new(void);
 
 /* EC_KEY_new_method acts the same as |EC_KEY_new|, but takes an explicit
  * |ENGINE|. */
-EC_KEY *EC_KEY_new_method(const ENGINE *engine);
+OPENSSL_EXPORT EC_KEY *EC_KEY_new_method(const ENGINE *engine);
 
 /* EC_KEY_new_by_curve_name returns a fresh EC_KEY for group specified by |nid|
  * or NULL on error. */
-EC_KEY *EC_KEY_new_by_curve_name(int nid);
+OPENSSL_EXPORT EC_KEY *EC_KEY_new_by_curve_name(int nid);
 
 /* EC_KEY_free frees all the data owned by |key| and |key| itself. */
-void EC_KEY_free(EC_KEY *key);
+OPENSSL_EXPORT void EC_KEY_free(EC_KEY *key);
 
 /* EC_KEY_copy sets |dst| equal to |src| and returns |dst| or NULL on error. */
-EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+OPENSSL_EXPORT EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
 
 /* EC_KEY_dup returns a fresh copy of |src| or NULL on error. */
-EC_KEY *EC_KEY_dup(const EC_KEY *src);
+OPENSSL_EXPORT EC_KEY *EC_KEY_dup(const EC_KEY *src);
 
 /* EC_KEY_up_ref increases the reference count of |key|. It returns one on
  * success and zero otherwise. */
-int EC_KEY_up_ref(EC_KEY *key);
+OPENSSL_EXPORT int EC_KEY_up_ref(EC_KEY *key);
 
 /* EC_KEY_is_opaque returns one if |key| is opaque and doesn't expose its key
  * material. Otherwise it return zero. */
-int EC_KEY_is_opaque(const EC_KEY *key);
+OPENSSL_EXPORT int EC_KEY_is_opaque(const EC_KEY *key);
 
 /* EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. */
-const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+OPENSSL_EXPORT const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
 
 /* EC_KEY_set_group sets the |EC_GROUP| object that |key| will use to |group|.
  * It returns one on success and zero otherwise. */
-int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+OPENSSL_EXPORT int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
 
 /* EC_KEY_get0_private_key returns a pointer to the private key inside |key|. */
-const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+OPENSSL_EXPORT const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
 
 /* EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns
  * one on success and zero otherwise. */
-int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
 
 /* EC_KEY_get0_public_key returns a pointer to the public key point inside
  * |key|. */
-const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+OPENSSL_EXPORT const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
 
 /* EC_KEY_set_public_key sets the public key of |key| to |pub|, by copying it.
  * It returns one on success and zero otherwise. */
-int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+OPENSSL_EXPORT int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
 
 #define EC_PKEY_NO_PARAMETERS 0x001
 #define EC_PKEY_NO_PUBKEY 0x002
 
 /* EC_KEY_get_enc_flags returns the encoding flags for |key|, which is a
  * bitwise-OR of |EC_PKEY_*| values. */
-unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
+OPENSSL_EXPORT unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
 
 /* EC_KEY_set_enc_flags sets the encoding flags for |key|, which is a
  * bitwise-OR of |EC_PKEY_*| values. */
-void EC_KEY_set_enc_flags(EC_KEY *key, unsigned flags);
+OPENSSL_EXPORT void EC_KEY_set_enc_flags(EC_KEY *key, unsigned flags);
 
 /* EC_KEY_get_conv_form returns the conversation form that will be used by
  * |key|. */
-point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
 
 /* EC_KEY_set_conv_form sets the conversion form to be used by |key|. */
-void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform);
+OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key,
+                                         point_conversion_form_t cform);
 
 /* EC_KEY_precompute_mult precomputes multiplies of the generator of the
  * underlying group in order to speed up operations that calculate generator
  * multiples. If |ctx| is not NULL, it may be used. It returns one on success
  * and zero otherwise. */
-int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+OPENSSL_EXPORT int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
 
 /* EC_KEY_check_key performs several checks on |key| (possibly including an
  * expensive check that the public key is in the primary subgroup). It returns
  * one if all checks pass and zero otherwise. If it returns zero then detail
  * about the problem can be found on the error stack. */
-int EC_KEY_check_key(const EC_KEY *key);
+OPENSSL_EXPORT int EC_KEY_check_key(const EC_KEY *key);
 
 /* EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to
  * (|x|, |y|). It returns one on success and zero otherwise. */
-int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
+OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key,
+                                                            BIGNUM *x,
+                                                            BIGNUM *y);
 
 
 /* Key generation. */
@@ -175,7 +178,7 @@
 /* EC_KEY_generate_key generates a random, private key, calculates the
  * corresponding public key and stores both in |key|. It returns one on success
  * or zero otherwise. */
-int EC_KEY_generate_key(EC_KEY *key);
+OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key);
 
 
 /* Serialisation. */
@@ -186,13 +189,14 @@
  * is written directly into |*out_key|, otherwise a fresh |EC_KEY| is
  * allocated. On successful exit, |*inp| is advanced past the DER structure. It
  * returns the result or NULL on error. */
-EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, long len);
+OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
+                                        long len);
 
 /* i2d_ECParameters marshals an EC private key from |key| to an ASN.1, DER
  * structure. If |outp| is not NULL then the result is written to |*outp| and
  * |*outp| is advanced just past the output. It returns the number of bytes in
  * the result, whether written or not, or a negative value on error. */
-int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
+OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
 
 /* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from
  * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to
@@ -200,35 +204,39 @@
  * the result is written directly into |*out_key|, otherwise a fresh |EC_KEY|
  * is allocated. On successful exit, |*inp| is advanced past the DER structure.
  * It returns the result or NULL on error. */
-EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len);
+OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp,
+                                        long len);
 
 /* i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER
  * structure. If |outp| is not NULL then the result is written to |*outp| and
  * |*outp| is advanced just past the output. It returns the number of bytes in
  * the result, whether written or not, or a negative value on error. */
-int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
+OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
 
 /* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into
  * |*out_key|. Note that this differs from the d2i format in that |*out_key|
  * must be non-NULL. On successful exit, |*inp| is advanced past the DER
  * structure. It returns |*out_key| or NULL on error. */
-EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, long len);
+OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
+                                       long len);
 
 /* i2o_ECPublicKey marshals an EC point from |key|. If |outp| is not NULL then
  * the result is written to |*outp| and |*outp| is advanced just past the
  * output. It returns the number of bytes in the result, whether written or
  * not, or a negative value on error. */
-int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
+OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
 
 
 /* ex_data functions.
  *
  * These functions are wrappers. See |ex_data.h| for details. */
 
-int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-                            CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg);
-void *EC_KEY_get_ex_data(const EC_KEY *r, int idx);
+OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp,
+                                           CRYPTO_EX_new *new_func,
+                                           CRYPTO_EX_dup *dup_func,
+                                           CRYPTO_EX_free *free_func);
+OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg);
+OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx);
 
 
 /* ECDSA method. */
diff --git a/include/openssl/ecdh.h b/include/openssl/ecdh.h
index 48aa08d..e97d757 100644
--- a/include/openssl/ecdh.h
+++ b/include/openssl/ecdh.h
@@ -82,16 +82,17 @@
  * return value. Otherwise, as many bytes of the shared key as will fit are
  * copied directly to, at most, |outlen| bytes at |out|. It returns the number
  * of bytes written to |out|, or -1 on error. */
-int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
-                     EC_KEY *priv_key, void *(*KDF)(const void *in, size_t inlen,
-                                                void *out, size_t *outlen));
+OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
+                                    const EC_POINT *pub_key, EC_KEY *priv_key,
+                                    void *(*KDF)(const void *in, size_t inlen,
+                                                 void *out, size_t *outlen));
 
 /* ECDH_KDF_X9_62 writes |outlen| bytes to |out| using the KDF from X9.62
  * applied to |Z| and |sinfo| and using the hash |md|. It returns one on
  * success and zero otherwise. */
-int ECDH_KDF_X9_62(uint8_t *out, size_t outlen, const uint8_t *Z,
-                   size_t Zlen, const uint8_t *sinfo, size_t sinfolen,
-                   const EVP_MD *md);
+OPENSSL_EXPORT int ECDH_KDF_X9_62(uint8_t *out, size_t outlen, const uint8_t *Z,
+                                  size_t Zlen, const uint8_t *sinfo,
+                                  size_t sinfolen, const EVP_MD *md);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/ecdsa.h b/include/openssl/ecdsa.h
index a2436f1..ec4df0f 100644
--- a/include/openssl/ecdsa.h
+++ b/include/openssl/ecdsa.h
@@ -73,19 +73,21 @@
  * space. On successful exit, |*sig_len| is set to the actual number of bytes
  * written. The |type| argument should be zero. It returns one on success and
  * zero otherwise. */
-int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig,
-               unsigned int *sig_len, EC_KEY *key);
+OPENSSL_EXPORT int ECDSA_sign(int type, const uint8_t *digest,
+                              size_t digest_len, uint8_t *sig,
+                              unsigned int *sig_len, EC_KEY *key);
 
 /* ECDSA_verify verifies that |sig_len| bytes from |sig| constitute a valid
  * signature by |key| of |digest|. (The |type| argument should be zero.) It
  * returns one on success or zero if the signature is invalid or an error
  * occured. */
-int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
-                 const uint8_t *sig, size_t sig_len, EC_KEY *key);
+OPENSSL_EXPORT int ECDSA_verify(int type, const uint8_t *digest,
+                                size_t digest_len, const uint8_t *sig,
+                                size_t sig_len, EC_KEY *key);
 
 /* ECDSA_size returns the maximum size of an ECDSA signature using |key|. It
  * returns zero on error. */
-size_t ECDSA_size(const EC_KEY *key);
+OPENSSL_EXPORT size_t ECDSA_size(const EC_KEY *key);
 
 
 /* Low-level signing and verification.
@@ -99,25 +101,25 @@
 };
 
 /* ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. */
-ECDSA_SIG *ECDSA_SIG_new(void);
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_new(void);
 
 /* ECDSA_SIG_free frees |sig| its member |BIGNUM|s. */
-void ECDSA_SIG_free(ECDSA_SIG *sig);
+OPENSSL_EXPORT void ECDSA_SIG_free(ECDSA_SIG *sig);
 
 /* ECDSA_sign signs |digest_len| bytes from |digest| with |key| and returns the
  * resulting signature structure, or NULL on error.
  *
  * TODO(fork): remove this function. */
-ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len,
-                         EC_KEY *key);
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest,
+                                        size_t digest_len, EC_KEY *key);
 
 /* ECDSA_verify verifies that |sig| constitutes a valid signature by |key| of
  * |digest|. It returns one on success or zero if the signature is invalid or
  * on error.
  *
  * TODO(fork): remove this function. */
-int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
-                    const ECDSA_SIG *sig, EC_KEY *key);
+OPENSSL_EXPORT int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
+                                   const ECDSA_SIG *sig, EC_KEY *key);
 
 
 /* Signing with precomputation.
@@ -130,19 +132,22 @@
 /* ECDSA_sign_setup precomputes parts of an ECDSA signing operation. It sets
  * |*kinv| and |*rp| to the precomputed values and uses the |ctx| argument, if
  * not NULL. It returns one on success and zero otherwise. */
-int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);
+OPENSSL_EXPORT int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+                                    BIGNUM **rp);
 
 /* ECDSA_do_sign_ex is the same as |ECDSA_do_sign| but takes precomputed values
  * as generated by |ECDSA_sign_setup|. */
-ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
-                            const BIGNUM *kinv, const BIGNUM *rp,
-                            EC_KEY *eckey);
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest,
+                                           size_t digest_len,
+                                           const BIGNUM *kinv, const BIGNUM *rp,
+                                           EC_KEY *eckey);
 
 /* ECDSA_sign_ex is the same as |ECDSA_sign| but takes precomputed values as
  * generated by |ECDSA_sign_setup|. */
-int ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
-                  uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv,
-                  const BIGNUM *rp, EC_KEY *eckey);
+OPENSSL_EXPORT int ECDSA_sign_ex(int type, const uint8_t *digest,
+                                 size_t digest_len, uint8_t *sig,
+                                 unsigned int *sig_len, const BIGNUM *kinv,
+                                 const BIGNUM *rp, EC_KEY *eckey);
 
 
 /* ASN.1 functions. */
@@ -153,13 +158,14 @@
  * directly into |*out|, otherwise a fresh |ECDSA_SIG| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp,
+                                        long len);
 
 /* i2d_ECDSA_SIG marshals a signature from |sig| to an ASN.1, DER
  * structure. If |outp| is not NULL then the result is written to |*outp| and
  * |*outp| is advanced just past the output. It returns the number of bytes in
  * the result, whether written or not, or a negative value on error. */
-int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp);
+OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/engine.h b/include/openssl/engine.h
index c97196e..f2916b3 100644
--- a/include/openssl/engine.h
+++ b/include/openssl/engine.h
@@ -37,11 +37,11 @@
 
 /* ENGINE_new returns an empty ENGINE that uses the default method for all
  * algorithms. */
-ENGINE *ENGINE_new();
+OPENSSL_EXPORT ENGINE *ENGINE_new();
 
 /* ENGINE_free decrements the reference counts for all methods linked from
  * |engine| and frees |engine| itself. */
-void ENGINE_free(ENGINE *engine);
+OPENSSL_EXPORT void ENGINE_free(ENGINE *engine);
 
 
 /* Method accessors.
@@ -53,21 +53,24 @@
  *
  * Set functions return one on success and zero on allocation failure. */
 
-int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method,
-                         size_t method_size);
-DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine);
+OPENSSL_EXPORT int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method,
+                                        size_t method_size);
+OPENSSL_EXPORT DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine);
 
-int ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method,
-                          size_t method_size);
-DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine);
+OPENSSL_EXPORT int ENGINE_set_DSA_method(ENGINE *engine,
+                                         const DSA_METHOD *method,
+                                         size_t method_size);
+OPENSSL_EXPORT DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine);
 
-int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method,
-                          size_t method_size);
-RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine);
+OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine,
+                                         const RSA_METHOD *method,
+                                         size_t method_size);
+OPENSSL_EXPORT RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine);
 
-int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method,
-                            size_t method_size);
-ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine);
+OPENSSL_EXPORT int ENGINE_set_ECDSA_method(ENGINE *engine,
+                                           const ECDSA_METHOD *method,
+                                           size_t method_size);
+OPENSSL_EXPORT ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine);
 
 
 /* Generic method functions.
@@ -76,11 +79,11 @@
  * structures. */
 
 /* METHOD_ref increments the reference count of |method|. */
-void METHOD_ref(void *method);
+OPENSSL_EXPORT void METHOD_ref(void *method);
 
 /* METHOD_unref decrements the reference count of |method| and frees it if the
  * reference count drops to zero. */
-void METHOD_unref(void *method);
+OPENSSL_EXPORT void METHOD_unref(void *method);
 
 
 /* Private functions. */
diff --git a/include/openssl/err.h b/include/openssl/err.h
index 82f51a6..ddb094c 100644
--- a/include/openssl/err.h
+++ b/include/openssl/err.h
@@ -146,11 +146,11 @@
  * values. If this is not called then the string forms of errors produced by
  * the functions below will contain numeric identifiers rather than
  * human-readable strings. */
-void ERR_load_crypto_strings();
+OPENSSL_EXPORT void ERR_load_crypto_strings();
 
 /* ERR_free_strings frees any internal error values that have been loaded. This
  * should only be called at process shutdown. */
-void ERR_free_strings();
+OPENSSL_EXPORT void ERR_free_strings();
 
 
 /* Reading and formatting errors. */
@@ -158,31 +158,32 @@
 /* ERR_get_error gets the packed error code for the least recent error and
  * removes that error from the queue. If there are no errors in the queue then
  * it returns zero. */
-uint32_t ERR_get_error(void);
+OPENSSL_EXPORT uint32_t ERR_get_error(void);
 
 /* ERR_get_error_line acts like |ERR_get_error|, except that the file and line
  * number of the call that added the error are also returned. */
-uint32_t ERR_get_error_line(const char **file, int *line);
+OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line);
 
 /* ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the
  * error-specific data pointer and flags. The flags are a bitwise-OR of
  * |ERR_FLAG_*| values. */
-uint32_t ERR_get_error_line_data(const char **file, int *line,
-                                 char **data, int *flags);
+OPENSSL_EXPORT uint32_t ERR_get_error_line_data(const char **file, int *line,
+                                                char **data, int *flags);
 
 /* The "peek" functions act like the |ERR_get_error| functions, above, but they
  * do not remove the error from the queue. */
-uint32_t ERR_peek_error(void);
-uint32_t ERR_peek_error_line(const char **file, int *line);
-uint32_t ERR_peek_error_line_data(const char **file, int *line,
-                                  const char **data, int *flags);
+OPENSSL_EXPORT uint32_t ERR_peek_error(void);
+OPENSSL_EXPORT uint32_t ERR_peek_error_line(const char **file, int *line);
+OPENSSL_EXPORT uint32_t ERR_peek_error_line_data(const char **file, int *line,
+                                                 const char **data, int *flags);
 
 /* The "peek last" functions act like the "peek" functions, above, except that
  * they return the most recent error. */
-uint32_t ERR_peek_last_error(void);
-uint32_t ERR_peek_last_error_line(const char **file, int *line);
-uint32_t ERR_peek_last_error_line_data(const char **file, int *line,
-                                       const char **data, int *flags);
+OPENSSL_EXPORT uint32_t ERR_peek_last_error(void);
+OPENSSL_EXPORT uint32_t ERR_peek_last_error_line(const char **file, int *line);
+OPENSSL_EXPORT uint32_t
+    ERR_peek_last_error_line_data(const char **file, int *line,
+                                  const char **data, int *flags);
 
 /* ERR_error_string generates a human-readable string representing
  * |packed_error|, places it at |buf| (which must be at least
@@ -199,26 +200,27 @@
  * and reason string are ASCII text.
  *
  * TODO(fork): remove in favour of |ERR_error_string_n|. */
-char *ERR_error_string(uint32_t packed_error, char *buf);
+OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
 #define ERR_ERROR_STRING_BUF_LEN 256
 
 /* ERR_error_string_n is a variant of |ERR_error_string| that writes at most
  * len characters (including the terminating NUL) and truncates the string if
  * necessary. If |len| is greater than zero then |buf| is always NUL
  * terminated. */
-void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len);
+OPENSSL_EXPORT void ERR_error_string_n(uint32_t packed_error, char *buf,
+                                       size_t len);
 
 /* ERR_lib_error_string returns a string representation of the library that
  * generated |packed_error|. */
-const char *ERR_lib_error_string(uint32_t packed_error);
+OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error);
 
 /* ERR_func_error_string returns a string representation of the function that
  * generated |packed_error|. */
-const char *ERR_func_error_string(uint32_t packed_error);
+OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
 
 /* ERR_reason_error_string returns a string representation of the reason for
  * |packed_error|. */
-const char *ERR_reason_error_string(uint32_t packed_error);
+OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error);
 
 /* ERR_print_errors_callback_t is the type of a function used by
  * |ERR_print_errors_cb|. It takes a pointer to a human readable string (and
@@ -245,13 +247,14 @@
  * The callback can return one to continue the iteration or zero to stop it.
  * The |ctx| argument is an opaque value that is passed through to the
  * callback. */
-void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx);
+OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback,
+                                        void *ctx);
 
 
 /* Clearing errors. */
 
 /* ERR_clear_error clears the error queue for the current thread. */
-void ERR_clear_error(void);
+OPENSSL_EXPORT void ERR_clear_error(void);
 
 
 /* Custom errors. */
@@ -259,13 +262,13 @@
 /* ERR_get_next_error_library returns a value suitable for passing as the
  * |library| argument to |ERR_put_error|. This is intended for code that wishes
  * to push its own, non-standard errors to the error queue. */
-int ERR_get_next_error_library();
+OPENSSL_EXPORT int ERR_get_next_error_library();
 
 
 /* Private functions. */
 
 /* ERR_clear_system_error clears the system's error value (i.e. errno). */
-void ERR_clear_system_error(void);
+OPENSSL_EXPORT void ERR_clear_system_error(void);
 
 /* OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error
  * queue. */
@@ -281,27 +284,27 @@
 
 /* ERR_put_error adds an error to the error queue, dropping the least recent
  * error if neccessary for space reasons. */
-void ERR_put_error(int library, int func, int reason, const char *file,
-                   unsigned line);
+OPENSSL_EXPORT void ERR_put_error(int library, int func, int reason,
+                                  const char *file, unsigned line);
 
 /* ERR_add_error_data takes a variable number (|count|) of const char*
  * pointers, concatenates them and sets the result as the data on the most
  * recent error. */
-void ERR_add_error_data(unsigned count, ...);
+OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...);
 
 /* ERR_add_error_dataf takes a printf-style format and arguments, and sets the
  * result as the data on the most recent error. */
-void ERR_add_error_dataf(const char *format, ...);
+OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...);
 
 /* ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|.
  * It returns one if an error was marked and zero if there are no errors. */
-int ERR_set_mark(void);
+OPENSSL_EXPORT int ERR_set_mark(void);
 
 /* ERR_pop_to_mark removes errors from the most recent to the least recent
  * until (and not including) a "marked" error. It returns zero if no marked
  * error was found (and thus all errors were removed) and one otherwise. Errors
  * are marked using |ERR_set_mark|. */
-int ERR_pop_to_mark(void);
+OPENSSL_EXPORT int ERR_pop_to_mark(void);
 
 struct err_error_st {
   /* file contains the filename where the error occured. */
@@ -465,7 +468,7 @@
 
 /* ERR_load_strings loads an array of ERR_STRING_DATA into the hash table. The
  * array must be terminated by an entry with a NULL string. */
-void ERR_load_strings(const ERR_STRING_DATA *str);
+OPENSSL_EXPORT void ERR_load_strings(const ERR_STRING_DATA *str);
 
 /* ERR_FNS_st is a structure of function pointers that contains the actual
  * implementation of the error queue handling functions. */
@@ -502,7 +505,7 @@
 /* ERR_load_BIO_strings does nothing.
  *
  * TODO(fork): remove. libjingle calls this. */
-void ERR_load_BIO_strings();
+OPENSSL_EXPORT void ERR_load_BIO_strings();
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index d47d51f..de6709c 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -83,57 +83,58 @@
 
 /* EVP_PKEY_new creates a new, empty public-key object and returns it or NULL
  * on allocation failure. */
-EVP_PKEY *EVP_PKEY_new();
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new();
 
 /* EVP_PKEY_free frees all data referenced by |pkey| and then frees |pkey|
  * itself. */
-void EVP_PKEY_free(EVP_PKEY *pkey);
+OPENSSL_EXPORT void EVP_PKEY_free(EVP_PKEY *pkey);
 
 /* EVP_PKEY_is_opaque returns one if |pkey| is opaque. Opaque keys are backed by
  * custom implementations which do not expose key material and parameters. It is
  * an error to attempt to duplicate, export, or compare an opaque key. */
-int EVP_PKEY_is_opaque(const EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_is_opaque(const EVP_PKEY *pkey);
 
 /* EVP_PKEY_cmp compares |a| and |b| and returns one if they are equal, zero if
  * not and a negative number on error.
  *
  * WARNING: this differs from the traditional return value of a "cmp"
  * function. */
-int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+OPENSSL_EXPORT int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
 
 /* EVP_PKEY_dup adds one to the reference count of |pkey| and returns
  * |pkey|. */
-EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey);
 
 /* EVP_PKEY_copy_parameters sets the parameters of |to| to equal the parameters
  * of |from|. It returns one on success and zero on error. */
-int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
 
 /* EVP_PKEY_missing_parameters returns one if |pkey| is missing needed
  * parameters or zero if not, or if the algorithm doesn't take parameters. */
-int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
 
 /* EVP_PKEY_size returns the "size", in bytes, of |pkey|. For example, for an
  * RSA key this returns the number of bytes needed to represent the modulus. */
-int EVP_PKEY_size(const EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey);
 
 /* EVP_PKEY_bits returns the "size", in bits, of |pkey|. For example, for an
  * RSA key, this returns the bit length of the modulus. */
-int EVP_PKEY_bits(EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_bits(EVP_PKEY *pkey);
 
 /* EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*|
  * values. */
-int EVP_PKEY_id(const EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
 
 /* EVP_PKEY_type returns a canonicalised form of |NID|. For example,
  * |EVP_PKEY_RSA2| will be turned into |EVP_PKEY_RSA|. */
-int EVP_PKEY_type(int nid);
+OPENSSL_EXPORT int EVP_PKEY_type(int nid);
 
 /* EVP_PKEY_new_mac_key allocates a fresh |EVP_PKEY| of the given type (e.g.
  * |EVP_PKEY_HMAC|), sets |mac_key| as the MAC key and "generates" a new key,
  * suitable for signing. It returns the fresh |EVP_PKEY|, or NULL on error. */
-EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, const uint8_t *mac_key,
-                               size_t mac_key_len);
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine,
+                                              const uint8_t *mac_key,
+                                              size_t mac_key_len);
 
 
 /* Getting and setting concrete public key types.
@@ -144,21 +145,21 @@
  * functions adopt the caller's reference. The getters return a fresh reference
  * to the underlying object. */
 
-int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key);
-int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key);
-RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key);
+OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key);
+OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
 
-int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
-int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
-struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
+OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
+OPENSSL_EXPORT struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
 
-int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
-int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
-struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
+OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
+OPENSSL_EXPORT struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
 
-int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
-int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key);
-struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
+OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key);
+OPENSSL_EXPORT struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
 
 #define EVP_PKEY_NONE NID_undef
 #define EVP_PKEY_RSA NID_rsaEncryption
@@ -172,18 +173,19 @@
 /* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of
  * the given type. The |type| argument should be one of the |EVP_PKEY_*|
  * values. */
-int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
+OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
 
 /* EVP_PKEY_set_type sets the type of |pkey| to |type|, which should be one of
  * the |EVP_PKEY_*| values. It returns one if sucessful or zero otherwise. If
  * |pkey| is NULL, it simply reports whether the type is known. */
-int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
+OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
 
 /* EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns
  * one if they match, zero if not, or a negative number of on error.
  *
  * WARNING: the return value differs from the usual return value convention. */
-int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a,
+                                           const EVP_PKEY *b);
 
 
 /* ASN.1 functions */
@@ -194,24 +196,25 @@
  * directly into |*out|, otherwise a fresh |EVP_PKEY| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
-                         long len);
+OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
+                                        const uint8_t **inp, long len);
 
 /* d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type
  * of the private key. */
-EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
+                                            long len);
 
 /* i2d_PrivateKey marshals a private key from |key| to an ASN.1, DER
  * structure. If |outp| is not NULL then the result is written to |*outp| and
  * |*outp| is advanced just past the output. It returns the number of bytes in
  * the result, whether written or not, or a negative value on error. */
-int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
+OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
 
 /* i2d_PublicKey marshals a public key from |key| to an ASN.1, DER
  * structure. If |outp| is not NULL then the result is written to |*outp| and
  * |*outp| is advanced just past the output. It returns the number of bytes in
  * the result, whether written or not, or a negative value on error. */
-int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
+OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
 
 
 /* Signing */
@@ -223,13 +226,15 @@
  * signing options.
  *
  * It returns one on success, or zero on error. */
-int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
-                       ENGINE *e, EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                                      const EVP_MD *type, ENGINE *e,
+                                      EVP_PKEY *pkey);
 
 /* EVP_DigestSignUpdate appends |len| bytes from |data| to the data which will
  * be signed in |EVP_DigestSignFinal|. It returns one on success and zero
  * otherwise. */
-int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data,
+                                        size_t len);
 
 /* EVP_DigestSignFinal signs the data that has been included by one or more
  * calls to |EVP_DigestSignUpdate|. If |out_sig| is NULL then |*out_sig_len| is
@@ -239,7 +244,8 @@
  * set to its length.
  *
  * It returns one on success, or zero on error. */
-int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len);
+OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
+                                       size_t *out_sig_len);
 
 
 /* Verifying */
@@ -251,13 +257,15 @@
  * signing options.
  *
  * It returns one on success, or zero on error. */
-int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
-                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                                        const EVP_MD *type, ENGINE *e,
+                                        EVP_PKEY *pkey);
 
 /* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
  * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
  * zero otherwise. */
-int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
+                                          size_t len);
 
 /* EVP_DigestVerifyFinal verifies that |sig_len| bytes of |sig| are a valid
  * signature for the data that has been included by one or more calls to
@@ -265,8 +273,8 @@
  *
  * It returns one on success and <= 0 on error. WARNING: this differs from the
  * usual return value convention. */
-int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
-                          size_t sig_len);
+OPENSSL_EXPORT int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
+                                         size_t sig_len);
 
 
 /* Signing (old functions) */
@@ -277,16 +285,18 @@
  *
  * (In order to initialise |ctx|, either obtain it initialised with
  * |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) */
-int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+OPENSSL_EXPORT int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
+                                   ENGINE *impl);
 
 /* EVP_SignInit is a deprecated version of |EVP_SignInit_ex|.
  *
  * TODO(fork): remove. */
-int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+OPENSSL_EXPORT int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);
 
 /* EVP_SignUpdate appends |len| bytes from |data| to the data which will be
  * signed in |EVP_SignFinal|. */
-int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+OPENSSL_EXPORT int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data,
+                                  size_t len);
 
 /* EVP_SignFinal signs the data that has been included by one or more calls to
  * |EVP_SignUpdate|, using the key |pkey|, and writes it to |sig|. On entry,
@@ -297,8 +307,8 @@
  *
  * It does not modify |ctx|, thus it's possible to continue to use |ctx| in
  * order to sign a longer message. */
-int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig,
-                  unsigned int *out_sig_len, EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig,
+                                 unsigned int *out_sig_len, EVP_PKEY *pkey);
 
 
 /* Verifying (old functions) */
@@ -309,16 +319,18 @@
  *
  * (In order to initialise |ctx|, either obtain it initialised with
  * |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) */
-int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+OPENSSL_EXPORT int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
+                                     ENGINE *impl);
 
 /* EVP_VerifyInit is a deprecated version of |EVP_VerifyInit_ex|.
  *
  * TODO(fork): remove. */
-int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+OPENSSL_EXPORT int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
 
 /* EVP_VerifyUpdate appends |len| bytes from |data| to the data which will be
  * signed in |EVP_VerifyFinal|. */
-int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+OPENSSL_EXPORT int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data,
+                                    size_t len);
 
 /* EVP_VerifyFinal verifies that |sig_len| bytes of |sig| are a valid
  * signature, by |pkey|, for the data that has been included by one or more
@@ -328,26 +340,26 @@
  *
  * It does not modify |ctx|, thus it's possible to continue to use |ctx| in
  * order to sign a longer message. */
-int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len,
-                    EVP_PKEY *pkey);
+OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
+                                   size_t sig_len, EVP_PKEY *pkey);
 
 
 /* Printing */
 
 /* EVP_PKEY_print_public prints a textual representation of the public key in
  * |pkey| to |out|. Returns one on success or zero otherwise. */
-int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *pctx);
+OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+                                         int indent, ASN1_PCTX *pctx);
 
 /* EVP_PKEY_print_public prints a textual representation of the private key in
  * |pkey| to |out|. Returns one on success or zero otherwise. */
-int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
-                           ASN1_PCTX *pctx);
+OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+                                          int indent, ASN1_PCTX *pctx);
 
 /* EVP_PKEY_print_public prints a textual representation of the parameters in
  * |pkey| to |out|. Returns one on success or zero otherwise. */
-int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
-                          ASN1_PCTX *pctx);
+OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+                                         int indent, ASN1_PCTX *pctx);
 
 
 /* Password stretching.
@@ -359,16 +371,17 @@
 /* PKCS5_PBKDF2_HMAC computes |iterations| iterations of PBKDF2 of |password|
  * and |salt|, using |digest|, and outputs |key_len| bytes to |out_key|. It
  * returns one on success and zero on error. */
-int PKCS5_PBKDF2_HMAC(const char *password, int password_len,
-                      const uint8_t *salt, size_t salt_len, unsigned iterations,
-                      const EVP_MD *digest, size_t key_len, uint8_t *out_key);
+OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC(const char *password, int password_len,
+                                     const uint8_t *salt, size_t salt_len,
+                                     unsigned iterations, const EVP_MD *digest,
+                                     size_t key_len, uint8_t *out_key);
 
 /* PKCS5_PBKDF2_HMAC_SHA1 is the same as PKCS5_PBKDF2_HMAC, but with |digest|
  * fixed to |EVP_sha1|. */
-int PKCS5_PBKDF2_HMAC_SHA1(const char *password, int password_len,
-                           const uint8_t *salt, size_t salt_len,
-                           unsigned iterations, size_t key_len,
-                           uint8_t *out_key);
+OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password,
+                                          int password_len, const uint8_t *salt,
+                                          size_t salt_len, unsigned iterations,
+                                          size_t key_len, uint8_t *out_key);
 
 
 /* Public key contexts.
@@ -378,31 +391,31 @@
 
 /* EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It
  * returns the context or NULL on error. */
-EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
 
 /* EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for a key of type |id|
  * (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where
  * |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass
  * it. It returns the context or NULL on error. */
-EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
 
 /* EVP_KEY_CTX_free frees |ctx| and the data it owns. */
-void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the
  * state of |ctx|. It returns the fresh |EVP_PKEY_CTX| or NULL on error. */
-EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. */
-EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_CTX_set_app_data sets an opaque pointer on |ctx|. */
-void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+OPENSSL_EXPORT void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
 
 /* EVP_PKEY_CTX_get_app_data returns the opaque pointer from |ctx| that was
  * previously set with |EVP_PKEY_CTX_set_app_data|, or NULL if none has been
  * set. */
-void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype|
  * arguments can be -1 to specify that any type and operation are acceptable,
@@ -413,14 +426,14 @@
  *
  * It returns -2 if |cmd| is not recognised, -1 on error or a |cmd| specific
  * value otherwise. */
-int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
-                      int p1, void *p2);
+OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+                                     int cmd, int p1, void *p2);
 
 /* EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It
  * should be called before |EVP_PKEY_sign|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_sign signs |data_len| bytes from |data| using |ctx|. If |sig| is
  * NULL, the maximum size of the signature is written to
@@ -433,27 +446,29 @@
  *
  * It returns one on success or zero on error. (Note: this differs from
  * OpenSSL, which can also return negative values to indicate an error. ) */
-int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
-                  const uint8_t *data, size_t data_len);
+OPENSSL_EXPORT int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig,
+                                 size_t *sig_len, const uint8_t *data,
+                                 size_t data_len);
 
 /* EVP_PKEY_verify_init initialises an |EVP_PKEY_CTX| for a signature
  * verification operation. It should be called before |EVP_PKEY_verify|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_verify verifies that |sig_len| bytes from |sig| are a valid signature
  * for |data|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
-                    const uint8_t *data, size_t data_len);
+OPENSSL_EXPORT int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
+                                   size_t sig_len, const uint8_t *data,
+                                   size_t data_len);
 
 /* EVP_PKEY_encrypt_init initialises an |EVP_PKEY_CTX| for an encryption
  * operation. It should be called before |EVP_PKEY_encrypt|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_encrypt encrypts |in_len| bytes from |in|. If |out| is NULL, the
  * maximum size of the ciphertext is written to |out_len|. Otherwise, |*out_len|
@@ -465,14 +480,15 @@
  * ciphertext. The actual ciphertext may be smaller.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
-                     const uint8_t *in, size_t in_len);
+OPENSSL_EXPORT int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
+                                    size_t *out_len, const uint8_t *in,
+                                    size_t in_len);
 
 /* EVP_PKEY_decrypt_init initialises an |EVP_PKEY_CTX| for a decryption
  * operation. It should be called before |EVP_PKEY_decrypt|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_decrypt decrypts |in_len| bytes from |in|. If |out| is NULL, the
  * maximum size of the plaintext is written to |out_len|. Otherwise, |*out_len|
@@ -484,21 +500,22 @@
  * plaintext. The actual plaintext may be smaller.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
-                     const uint8_t *in, size_t in_len);
+OPENSSL_EXPORT int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
+                                    size_t *out_len, const uint8_t *in,
+                                    size_t in_len);
 
 /* EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation
  * operation. It should be called before |EVP_PKEY_derive_set_peer| and
  * |EVP_PKEY_derive|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_derive_set_peer sets the peer's key to be used for key derivation
  * by |ctx| to |peer|. It should be called after |EVP_PKEY_derive_init|. (For
  * example, this is used to set the peer's key in (EC)DH.) It returns one on
  * success and zero on error. */
-int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+OPENSSL_EXPORT int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
 
 /* EVP_PKEY_derive derives a shared key between the two keys configured in
  * |ctx|. If |key| is non-NULL then, on entry, |out_key_len| must contain the
@@ -510,18 +527,19 @@
  * actual key may be smaller.
  *
  * It returns one on success and zero on error. */
-int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len);
+OPENSSL_EXPORT int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
+                                   size_t *out_key_len);
 
 /* EVP_PKEY_keygen_init initialises an |EVP_PKEY_CTX| for a key generation
  * operation. It should be called before |EVP_PKEY_keygen|.
  *
  * It returns one on success or zero on error. */
-int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+OPENSSL_EXPORT int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
 
 /* EVP_PKEY_keygen performs a key generation operation using the values from
  * |ctx| and sets |*ppkey| to a fresh |EVP_PKEY| containing the resulting key.
  * It returns one on success or zero on error. */
-int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+OPENSSL_EXPORT int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
 
 
 /* EVP_PKEY_CTX_ctrl operations.
@@ -534,12 +552,14 @@
 /* EVP_PKEY_CTX_set_signature_md sets |md| as the digest to be used in a
  * signature operation. It returns one on success or otherwise on error. See
  * the return values of |EVP_PKEY_CTX_ctrl| for details. */
-int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx,
+                                                 const EVP_MD *md);
 
 /* EVP_PKEY_CTX_get_signature_md sets |*out_md| to the digest to be used in a
  * signature operation. It returns one on success or otherwise on error. See
  * the return values of |EVP_PKEY_CTX_ctrl| for details. */
-int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx,
+                                                 const EVP_MD **out_md);
 
 /* EVP_PKEY_CTRL_DIGESTINIT is an internal value. It's called by
  * EVP_DigestInit_ex to signal the |EVP_PKEY| that a digest operation is
@@ -574,13 +594,14 @@
  * of the |RSA_*_PADDING| values. Returns one on success or another value on
  * error. See |EVP_PKEY_CTX_ctrl| for the other return values, which are
  * non-standard. */
-int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding);
 
 /* EVP_PKEY_CTX_get_rsa_padding sets |*out_padding| to the current padding
  * value, which is one of the |RSA_*_PADDING| values. Returns one on success or
  * another value on error. See |EVP_PKEY_CTX_ctrl| for the other return values,
  * which are non-standard. */
-int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx,
+                                                int *out_padding);
 
 /* EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded
  * signature. A value of -1 cause the salt to be the same length as the digest
@@ -589,7 +610,8 @@
  *
  * Returns one on success or another value on error. See |EVP_PKEY_CTX_ctrl|
  * for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx,
+                                                    int salt_len);
 
 /* EVP_PKEY_CTX_get_rsa_pss_saltlen sets |*out_salt_len| to the salt length of
  * a PSS-padded signature. See the documentation for
@@ -598,38 +620,45 @@
  *
  * Returns one on success or another value on error. See |EVP_PKEY_CTX_ctrl|
  * for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx,
+                                                    int *out_salt_len);
 
 /* EVP_PKEY_CTX_set_rsa_keygen_bits sets the size of the desired RSA modulus,
  * in bits, for key generation. Returns one on success or another value on
  * error. See |EVP_PKEY_CTX_ctrl| for the other return values, which are
  * non-standard. */
-int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx,
+                                                    int bits);
 
 /* EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key
  * generation. Returns one on success or another value on error. See
  * |EVP_PKEY_CTX_ctrl| for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx,
+                                                      BIGNUM *e);
 
 /* EVP_PKEY_CTX_set_rsa_oaep_md sets |md| as the digest used in OAEP padding.
  * Returns one on success or another value on error. See |EVP_PKEY_CTX_ctrl|
  * for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx,
+                                                const EVP_MD *md);
 
 /* EVP_PKEY_CTX_get_rsa_oaep_md sets |*out_md| to the digest function used in
  * OAEP padding. Returns one on success or another value on error. See
  * |EVP_PKEY_CTX_ctrl| for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx,
+                                                const EVP_MD **out_md);
 
 /* EVP_PKEY_CTX_set_rsa_mgf1_md sets |md| as the digest used in MGF1. Returns
  * one on success or another value on error. See |EVP_PKEY_CTX_ctrl| for the
  * other return values, which are non-standard. */
-int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx,
+                                                const EVP_MD *md);
 
 /* EVP_PKEY_CTX_get_rsa_mgf1_md sets |*out_md| to the digest function used in
  * MGF1. Returns one on success or another value on error. See
  * |EVP_PKEY_CTX_ctrl| for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx,
+                                                const EVP_MD **out_md);
 
 /* EVP_PKEY_CTX_set0_rsa_oaep_label sets |label_len| bytes from |label| as the
  * label used in OAEP. DANGER: this call takes ownership of |label| and will
@@ -637,14 +666,15 @@
  *
  * Returns one on success or another value on error. See |EVP_PKEY_CTX_ctrl|
  * for the other return values, which are non-standard. */
-int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
-                                     size_t label_len);
+OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
+                                                    const uint8_t *label,
+                                                    size_t label_len);
 
 /* EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal
  * buffer containing the OAEP label (which may be NULL) and returns the length
  * of the label or a negative value on error. */
-int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
-                                     const uint8_t **out_label);
+OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
+                                                    const uint8_t **out_label);
 
 
 /* EC specific */
@@ -678,20 +708,20 @@
 /* Private functions */
 
 /* OpenSSL_add_all_algorithms does nothing. */
-void OpenSSL_add_all_algorithms();
+OPENSSL_EXPORT void OpenSSL_add_all_algorithms();
 
 /* EVP_cleanup does nothing. */
-void EVP_cleanup();
+OPENSSL_EXPORT void EVP_cleanup();
 
 /* EVP_PKEY_asn1_find returns the ASN.1 method table for the given |nid|, which
  * should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
  * unknown. */
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid);
+OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine,
+                                                              int nid);
 
 /* TODO(fork): move to PEM? */
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
-                                                   const char *name,
-                                                   size_t len);
+OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(
+    ENGINE **pengine, const char *name, size_t len);
 
 struct evp_pkey_st {
   int references;
diff --git a/include/openssl/ex_data.h b/include/openssl/ex_data.h
index 9dfe5cf..f61501a 100644
--- a/include/openssl/ex_data.h
+++ b/include/openssl/ex_data.h
@@ -187,9 +187,10 @@
  * module have a private global EX_CLASS_ITEM somewhere and any direct callers
  * of CRYPTO_{get,set}_ex_data{,_index} would have to always call the
  * wrappers. */
-int CRYPTO_get_ex_new_index(int class_value, long argl, void *argp,
-                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
-                            CRYPTO_EX_free *free_func);
+OPENSSL_EXPORT int CRYPTO_get_ex_new_index(int class_value, long argl,
+                                           void *argp, CRYPTO_EX_new *new_func,
+                                           CRYPTO_EX_dup *dup_func,
+                                           CRYPTO_EX_free *free_func);
 
 /* CRYPTO_set_ex_data sets an extra data pointer on a given object. This should
  * not be called directly, rather each class of object should provide a wrapper
@@ -197,7 +198,7 @@
  *
  * The |index| argument should have been returned from a previous call to
  * |CRYPTO_get_ex_new_index|. */
-int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
+OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
 
 /* CRYPTO_set_ex_data return an extra data pointer for a given object, or NULL
  * if no such index exists. This should not be called directly, rather each
@@ -205,7 +206,7 @@
  *
  * The |index| argument should have been returned from a previous call to
  * |CRYPTO_get_ex_new_index|. */
-void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
+OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
 
 /* CRYPTO_EX_INDEX_* are the built-in classes of objects.
  *
@@ -240,7 +241,7 @@
  * that wishes to use ex_data.
  *
  * TODO(fork): hopefully remove this. */
-int CRYPTO_ex_data_new_class(void);
+OPENSSL_EXPORT int CRYPTO_ex_data_new_class(void);
 
 
 /* Embedding, allocating and freeing |CRYPTO_EX_DATA| structures for objects
@@ -249,17 +250,19 @@
 /* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA| which is
  * embedded inside of |obj| which is of class |class_value|. Returns one on
  * success and zero otherwise. */
-int CRYPTO_new_ex_data(int class_value, void *obj, CRYPTO_EX_DATA *ad);
+OPENSSL_EXPORT int CRYPTO_new_ex_data(int class_value, void *obj,
+                                      CRYPTO_EX_DATA *ad);
 
 /* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated
  * |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given
  * class. It returns one on success and zero otherwise. */
-int CRYPTO_dup_ex_data(int class_value, CRYPTO_EX_DATA *to,
-                       const CRYPTO_EX_DATA *from);
+OPENSSL_EXPORT int CRYPTO_dup_ex_data(int class_value, CRYPTO_EX_DATA *to,
+                                      const CRYPTO_EX_DATA *from);
 
 /* CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an
  * object of the given class. */
-void CRYPTO_free_ex_data(int class_value, void *obj, CRYPTO_EX_DATA *ad);
+OPENSSL_EXPORT void CRYPTO_free_ex_data(int class_value, void *obj,
+                                        CRYPTO_EX_DATA *ad);
 
 
 /* Handling different ex_data implementations. */
@@ -269,19 +272,21 @@
 
 /* CRYPTO_get_ex_data_implementation returns the current implementation of
  * ex_data. */
-const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+OPENSSL_EXPORT const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(
+    void);
 
 /* CRYPTO_set_ex_data_implementation sets the implementation of ex_data to use,
  * unless ex_data has already been used and the default implementation
  * installed. It returns one on success and zero otherwise. */
-int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *impl);
+OPENSSL_EXPORT int CRYPTO_set_ex_data_implementation(
+    const CRYPTO_EX_DATA_IMPL *impl);
 
 
 /* Private functions. */
 
 /* CRYPTO_cleanup_all_ex_data cleans up all ex_data state. It assumes that no
  * other threads are executing code that might call ex_data functions. */
-void CRYPTO_cleanup_all_ex_data(void);
+OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void);
 
 struct crypto_ex_data_st {
   STACK_OF(void) *sk;
diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h
index 33c9061..34c4497 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/hmac.h
@@ -76,9 +76,10 @@
  * and hash function, and writes the result to |out|. On entry, |out| must
  * contain |EVP_MAX_MD_SIZE| bytes of space. The actual length of the result is
  * written to |*out_len|. It returns |out| or NULL on error. */
-uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
-              const uint8_t *data, size_t data_len, uint8_t *out,
-              unsigned int *out_len);
+OPENSSL_EXPORT uint8_t *HMAC(const EVP_MD *evp_md, const void *key,
+                             size_t key_len, const uint8_t *data,
+                             size_t data_len, uint8_t *out,
+                             unsigned int *out_len);
 
 
 /* Incremental operation. */
@@ -87,51 +88,54 @@
  * that HMAC_CTX objects will be allocated on the stack thus no allocation
  * function is provided. If needed, allocate |sizeof(HMAC_CTX)| and call
  * |HMAC_CTX_init| on it. */
-void HMAC_CTX_init(HMAC_CTX *ctx);
+OPENSSL_EXPORT void HMAC_CTX_init(HMAC_CTX *ctx);
 
 /* HMAC_CTX_cleanup frees data owned by |ctx|. */
-void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+OPENSSL_EXPORT void HMAC_CTX_cleanup(HMAC_CTX *ctx);
 
 /* HMAC_Init_ex sets up an initialised |HMAC_CTX| to use |md| as the hash
  * function and |key| as the key. Any of |md| or |key| can be NULL, in which
  * case the previous value will be used. It returns one on success or zero
  * otherwise. */
-int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
-                 const EVP_MD *md, ENGINE *impl);
+OPENSSL_EXPORT int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
+                                const EVP_MD *md, ENGINE *impl);
 
 /* HMAC_Update hashes |data_len| bytes from |data| into the current HMAC
  * operation in |ctx|. It returns one on success and zero on error. */
-int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len);
+OPENSSL_EXPORT int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data,
+                               size_t data_len);
 
 /* HMAC_Final completes the HMAC operation in |ctx| and writes the result to
  * |out| and the sets |*out_len| to the length of the result. On entry, |out|
  * must contain at least |EVP_MAX_MD_SIZE| bytes of space. It returns one on
  * success or zero on error. */
-int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len);
+OPENSSL_EXPORT int HMAC_Final(HMAC_CTX *ctx, uint8_t *out,
+                              unsigned int *out_len);
 
 
 /* Utility functions. */
 
 /* HMAC_size returns the size, in bytes, of the HMAC that will be produced by
  * |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. */
-size_t HMAC_size(const HMAC_CTX *ctx);
+OPENSSL_EXPORT size_t HMAC_size(const HMAC_CTX *ctx);
 
 /* HMAC_CTX_copy sets |dest| equal to |src|. On entry, |dest| must have been
  * initialised by calling |HMAC_CTX_init|. It returns one on success and zero
  * on error. */
-int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src);
+OPENSSL_EXPORT int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src);
 
 /* HMAC_CTX_set_flags ORs |flags| into the flags of the underlying digests of
  * |ctx|, which must have been setup by a call to |HMAC_Init_ex|. See
  * |EVP_MD_CTX_set_flags|.
  *
  * TODO(fork): remove? */
-void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
+OPENSSL_EXPORT void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
 
 
 /* Deprecated functions. */
 
-int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md);
+OPENSSL_EXPORT int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len,
+                             const EVP_MD *md);
 
 
 /* Private functions */
diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h
index 82842d7..fa64ad2 100644
--- a/include/openssl/lhash.h
+++ b/include/openssl/lhash.h
@@ -148,42 +148,43 @@
 /* lh_new returns a new, empty hash table or NULL on error. If |comp| is NULL,
  * |strcmp| will be used. If |hash| is NULL, a generic hash function will be
  * used. */
-_LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp);
+OPENSSL_EXPORT _LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp);
 
 /* lh_free frees the hash table itself but none of the elements. See
  * |lh_doall|. */
-void lh_free(_LHASH *lh);
+OPENSSL_EXPORT void lh_free(_LHASH *lh);
 
 /* lh_num_items returns the number of items in |lh|. */
-size_t lh_num_items(const _LHASH *lh);
+OPENSSL_EXPORT size_t lh_num_items(const _LHASH *lh);
 
 /* lh_retrieve finds an element equal to |data| in the hash table and returns
  * it. If no such element exists, it returns NULL. */
-void *lh_retrieve(const _LHASH *lh, const void *data);
+OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data);
 
 /* lh_insert inserts |data| into the hash table. If an existing element is
  * equal to |data| (with respect to the comparison function) then |*old_data|
  * will be set to that value and it will be replaced. Otherwise, or in the
  * event of an error, |*old_data| will be set to NULL. It returns one on
  * success or zero in the case of an allocation error. */
-int lh_insert(_LHASH *lh, void **old_data, void *data);
+OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data);
 
 /* lh_delete removes an element equal to |data| from the hash table and returns
  * it. If no such element is found, it returns NULL. */
-void *lh_delete(_LHASH *lh, const void *data);
+OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data);
 
 /* lh_doall calls |func| on each element of the hash table.
  * TODO(fork): rename this */
-void lh_doall(_LHASH *lh, void (*func)(void *));
+OPENSSL_EXPORT void lh_doall(_LHASH *lh, void (*func)(void *));
 
 /* lh_doall_arg calls |func| on each element of the hash table and also passes
  * |arg| as the second argument.
  * TODO(fork): rename this */
-void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg);
+OPENSSL_EXPORT void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *),
+                                 void *arg);
 
 /* lh_strhash is the default hash function which processes NUL-terminated
  * strings. */
-uint32_t lh_strhash(const char *c);
+OPENSSL_EXPORT uint32_t lh_strhash(const char *c);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/md5.h b/include/openssl/md5.h
index 7a1a00f..dc800c0 100644
--- a/include/openssl/md5.h
+++ b/include/openssl/md5.h
@@ -73,23 +73,23 @@
 #define MD5_DIGEST_LENGTH 16
 
 /* MD51_Init initialises |md5| and returns 1. */
-int MD5_Init(MD5_CTX *md5);
+OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5);
 
 /* MD5_Update adds |len| bytes from |data| to |md5| and returns one. */
-int MD5_Update(MD5_CTX *md5, const void *data, size_t len);
+OPENSSL_EXPORT int MD5_Update(MD5_CTX *md5, const void *data, size_t len);
 
 /* MD5_Final adds the final padding to |md5| and writes the resulting digest to
  * |md|, which must have at least |MD5_DIGEST_LENGTH| bytes of space. It
  * returns one. */
-int MD5_Final(uint8_t *md, MD5_CTX *md5);
+OPENSSL_EXPORT int MD5_Final(uint8_t *md, MD5_CTX *md5);
 
 /* MD5 writes the digest of |len| bytes from |data| to |out| and returns |out|.
  * There must be at least |MD5_DIGEST_LENGTH| bytes of space in |out|. */
-uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out);
+OPENSSL_EXPORT uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out);
 
 /* MD5_Transform is a low-level function that performs a single, MD5 block
  * transformation using the state from |md5| and 64 bytes from |block|. */
-void MD5_Transform(MD5_CTX *md5, const uint8_t *block);
+OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block);
 
 struct md5_state_st {
   uint32_t A, B, C, D;
diff --git a/include/openssl/mem.h b/include/openssl/mem.h
index 0d04c95..293e04b 100644
--- a/include/openssl/mem.h
+++ b/include/openssl/mem.h
@@ -82,29 +82,29 @@
 
 /* OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to
  * |memset_s| from C11. */
-void OPENSSL_cleanse(void *ptr, size_t len);
+OPENSSL_EXPORT void OPENSSL_cleanse(void *ptr, size_t len);
 
 /* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
  * takes an amount of time dependent on |len|, but independent of the contents
  * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
  * defined order as the return value when a != b is undefined, other than to be
  * non-zero. */
-int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+OPENSSL_EXPORT int CRYPTO_memcmp(const void *a, const void *b, size_t len);
 
 /* OPENSSL_hash32 implements the 32 bit, FNV-1a hash. */
-uint32_t OPENSSL_hash32(const void *ptr, size_t len);
+OPENSSL_EXPORT uint32_t OPENSSL_hash32(const void *ptr, size_t len);
 
 /* OPENSSL_strdup has the same behaviour as strdup(3). */
-char *OPENSSL_strdup(const char *s);
+OPENSSL_EXPORT char *OPENSSL_strdup(const char *s);
 
 /* OPENSSL_strnlen has the same behaviour as strnlen(3). */
-size_t OPENSSL_strnlen(const char *s, size_t len);
+OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len);
 
 /* OPENSSL_strcasecmp has the same behaviour as strcasecmp(3). */
-int OPENSSL_strcasecmp(const char *a, const char *b);
+OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b);
 
 /* OPENSSL_strncasecmp has the same behaviour as strncasecmp(3). */
-int OPENSSL_strncasecmp(const char *a, const char *b, size_t n);
+OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n);
 
 /* DECIMAL_SIZE returns an upper bound for the length of the decimal
  * representation of the given type. */
@@ -120,10 +120,11 @@
 #else
 #define __bio_h__attr__(x)
 #endif
-int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...)
     __bio_h__attr__((__format__(__printf__, 3, 4)));
 
-int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format,
+                                 va_list args)
     __bio_h__attr__((__format__(__printf__, 3, 0)));
 #undef __bio_h__attr__
 
diff --git a/include/openssl/modes.h b/include/openssl/modes.h
index c3a11ba..220adec 100644
--- a/include/openssl/modes.h
+++ b/include/openssl/modes.h
@@ -76,20 +76,19 @@
  * stored in |ecount_buf| and |*num|, which must be zeroed before the initial
  * call. The counter is a 128-bit, big-endian value in |ivec| and is
  * incremented by this function. */
-void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out,
-                           size_t len, const void *key, uint8_t ivec[16],
-                           uint8_t ecount_buf[16], unsigned int *num,
-                           block128_f block);
+OPENSSL_EXPORT void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out,
+                                          size_t len, const void *key,
+                                          uint8_t ivec[16],
+                                          uint8_t ecount_buf[16],
+                                          unsigned int *num, block128_f block);
 
 /* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
  * |ctr|, a function that performs CTR mode but only deals with the lower 32
  * bits of the counter. This is useful when |ctr| can be an optimised
  * function. */
-void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out,
-                                 size_t len, const void *key,
-                                 uint8_t ivec[16],
-                                 uint8_t ecount_buf[16],
-                                 unsigned int *num, ctr128_f ctr);
+OPENSSL_EXPORT void CRYPTO_ctr128_encrypt_ctr32(
+    const uint8_t *in, uint8_t *out, size_t len, const void *key,
+    uint8_t ivec[16], uint8_t ecount_buf[16], unsigned int *num, ctr128_f ctr);
 
 
 /* GCM. */
@@ -98,54 +97,61 @@
 
 /* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
  * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
-GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
+OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
 
 /* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with the
  * given key. */
-void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block);
+OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key,
+                                       block128_f block);
 
 /* CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. */
-void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv, size_t len);
+OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv,
+                                        size_t len);
 
 /* CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. This
  * must be called before and data is encrypted. It returns one on success and
  * zero otherwise. */
-int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len);
+OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad,
+                                     size_t len);
 
 /* CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. It returns
  * one on success and zero otherwise. */
-int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const uint8_t *in, uint8_t *out,
-                          size_t len);
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
+                                         uint8_t *out, size_t len);
 
 /* CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. It returns
  * one on success and zero otherwise. */
-int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const uint8_t *in, uint8_t *out,
-                          size_t len);
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
+                                         uint8_t *out, size_t len);
 
 /* CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using a
  * CTR function that only handles the bottom 32 bits of the nonce, like
  * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
  * otherwise. */
-int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
-                                uint8_t *out, size_t len, ctr128_f stream);
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+                                               const uint8_t *in, uint8_t *out,
+                                               size_t len, ctr128_f stream);
 
 /* CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using a
  * CTR function that only handles the bottom 32 bits of the nonce, like
  * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
  * otherwise. */
-int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
-                                uint8_t *out, size_t len, ctr128_f stream);
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+                                               const uint8_t *in, uint8_t *out,
+                                               size_t len, ctr128_f stream);
 
 /* CRYPTO_gcm128_finish calculates the authenticator and compares it against
  * |len| bytes of |tag|. It returns one on success and zero otherwise. */
-int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len);
+OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag,
+                                        size_t len);
 
 /* CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. The
  * minimum of |len| and 16 bytes are copied into |tag|. */
-void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, size_t len);
+OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
+                                      size_t len);
 
 /* CRYPTO_gcm128_release clears and frees |ctx|. */
-void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
 
 
 /* CBC. */
diff --git a/include/openssl/obj.h b/include/openssl/obj.h
index 7c9772a..f868fd3 100644
--- a/include/openssl/obj.h
+++ b/include/openssl/obj.h
@@ -84,48 +84,48 @@
 /* Basic operations. */
 
 /* OBJ_dup returns a duplicate copy of |obj| or NULL on allocation failure. */
-ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj);
+OPENSSL_EXPORT ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj);
 
 /* OBJ_cmp returns a value less than, equal to or greater than zero if |a| is
  * less than, equal to or greater than |b|, respectively. */
-int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
+OPENSSL_EXPORT int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
 
 
 /* Looking up nids. */
 
 /* OBJ_obj2nid returns the nid corresponding to |obj|, or |NID_undef| if no
  * such object is known. */
-int OBJ_obj2nid(const ASN1_OBJECT *obj);
+OPENSSL_EXPORT int OBJ_obj2nid(const ASN1_OBJECT *obj);
 
 /* OBJ_cbs2nid returns the nid corresponding to the DER data in |cbs|, or
  * |NID_undef| if no such object is known. */
-int OBJ_cbs2nid(const CBS *cbs);
+OPENSSL_EXPORT int OBJ_cbs2nid(const CBS *cbs);
 
 /* OBJ_sn2nid returns the nid corresponding to |short_name|, or |NID_undef| if
  * no such short name is known. */
-int OBJ_sn2nid(const char *short_name);
+OPENSSL_EXPORT int OBJ_sn2nid(const char *short_name);
 
 /* OBJ_ln2nid returns the nid corresponding to |long_name|, or |NID_undef| if
  * no such long name is known. */
-int OBJ_ln2nid(const char *long_name);
+OPENSSL_EXPORT int OBJ_ln2nid(const char *long_name);
 
 /* OBJ_txt2nid returns the nid corresponding to |s|, which may be a short name,
  * long name, or an ASCII string containing a dotted sequence of numbers. It
  * returns the nid or NID_undef if unknown. */
-int OBJ_txt2nid(const char *s);
+OPENSSL_EXPORT int OBJ_txt2nid(const char *s);
 
 
 /* Getting information about nids. */
 
 /* OBJ_nid2obj returns the ASN1_OBJECT corresponding to |nid|, or NULL if |nid|
  * is unknown. */
-const ASN1_OBJECT *OBJ_nid2obj(int nid);
+OPENSSL_EXPORT const ASN1_OBJECT *OBJ_nid2obj(int nid);
 
 /* OBJ_nid2sn returns the short name for |nid|, or NULL if |nid| is unknown. */
-const char *OBJ_nid2sn(int nid);
+OPENSSL_EXPORT const char *OBJ_nid2sn(int nid);
 
 /* OBJ_nid2sn returns the long name for |nid|, or NULL if |nid| is unknown. */
-const char *OBJ_nid2ln(int nid);
+OPENSSL_EXPORT const char *OBJ_nid2ln(int nid);
 
 
 /* Dealing with textual representations of object identifiers. */
@@ -135,7 +135,7 @@
  * and short names of a known objects to find a match. Otherwise |s| must
  * contain an ASCII string with a dotted sequence of numbers. The resulting
  * object need not be previously known. It returns NULL on error. */
-ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names);
+OPENSSL_EXPORT ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names);
 
 /* OBJ_obj2txt converts |obj| to a textual representation. If
  * |dont_return_name| is zero then |obj| will be matched against known objects
@@ -145,15 +145,16 @@
  * there. If |out_len| is at least one, then string written to |out| will
  * always be NUL terminated. It returns the number of characters that could
  * have been written, not including the final NUL, or -1 on error. */
-int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj,
-                int dont_return_name);
+OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj,
+                               int dont_return_name);
 
 
 /* Adding objects at runtime. */
 
 /* OBJ_create adds a known object and returns the nid of the new object, or
  * NID_undef on error. */
-int OBJ_create(const char *oid, const char *short_name, const char *long_name);
+OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name,
+                              const char *long_name);
 
 
 /* Handling signature algorithm identifiers.
@@ -170,14 +171,16 @@
  * and |*out_pkey_nid| and returns one. Otherwise it returns zero. Any of
  * |out_digest_nid| or |out_pkey_nid| can be NULL if the caller doesn't need
  * that output value. */
-int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid);
+OPENSSL_EXPORT int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid,
+                                       int *out_pkey_nid);
 
 /* OBJ_find_sigid_by_algs finds the signature NID that corresponds to the
  * combination of |digest_nid| and |pkey_nid|. If success, it sets
  * |*out_sign_nid| and returns one. Otherwise it returns zero. The
  * |out_sign_nid| argument can be NULL if the caller only wishes to learn
  * whether the combination is valid. */
-int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid);
+OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
+                                          int pkey_nid);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index 464aae4..4bd9bd0 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -217,25 +217,25 @@
 #else
 
 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
-type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
 return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
 } 
 
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
-int PEM_write_##name(FILE *fp, type *x) \
+OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x) \
 { \
 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
-int PEM_write_##name(FILE *fp, const type *x) \
+OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x) \
 { \
 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
-int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
@@ -243,7 +243,7 @@
 	}
 
 #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
-int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
@@ -253,32 +253,32 @@
 #endif
 
 #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
-type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
 { \
 return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
 }
 
 #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
-int PEM_write_bio_##name(BIO *bp, type *x) \
+OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x) \
 { \
 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
-int PEM_write_bio_##name(BIO *bp, const type *x) \
+OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x) \
 { \
 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
-int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
 	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
-int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
 	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
@@ -327,32 +327,32 @@
 #else
 
 #define DECLARE_PEM_read_fp(name, type) \
-	type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+	OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
 
 #define DECLARE_PEM_write_fp(name, type) \
-	int PEM_write_##name(FILE *fp, type *x);
+	OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x);
 
 #define DECLARE_PEM_write_fp_const(name, type) \
-	int PEM_write_##name(FILE *fp, const type *x);
+	OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x);
 
 #define DECLARE_PEM_write_cb_fp(name, type) \
-	int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
 
 #endif
 
 #ifndef OPENSSL_NO_BIO
 #define DECLARE_PEM_read_bio(name, type) \
-	type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+	OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
 
 #define DECLARE_PEM_write_bio(name, type) \
-	int PEM_write_bio_##name(BIO *bp, type *x);
+	OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x);
 
 #define DECLARE_PEM_write_bio_const(name, type) \
-	int PEM_write_bio_##name(BIO *bp, const type *x);
+	OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x);
 
 #define DECLARE_PEM_write_cb_bio(name, type) \
-	int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
 
 #else
@@ -400,56 +400,37 @@
 typedef int pem_password_cb(char *buf, int size, int rwflag);
 #endif
 
-int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
-int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
-	pem_password_cb *callback,void *u);
+OPENSSL_EXPORT int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+OPENSSL_EXPORT int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, pem_password_cb *callback,void *u);
 
 #ifndef OPENSSL_NO_BIO
-int	PEM_read_bio(BIO *bp, char **name, char **header,
-		unsigned char **data,long *len);
-int	PEM_write_bio(BIO *bp,const char *name, const char *hdr,
-		      const unsigned char *data, long len);
-int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
-	     pem_password_cb *cb, void *u);
-void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
-			  void **x, pem_password_cb *cb, void *u);
-int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
-			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
-			   pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int	PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,long *len);
+OPENSSL_EXPORT int	PEM_write_bio(BIO *bp,const char *name, const char *hdr, const unsigned char *data, long len);
+OPENSSL_EXPORT int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x, const EVP_CIPHER *enc,unsigned char *kstr,int klen, pem_password_cb *cb, void *u);
 
-STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
-int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
-		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
+OPENSSL_EXPORT STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
 #endif
 
-int	PEM_read(FILE *fp, char **name, char **header,
-		unsigned char **data,long *len);
-int	PEM_write(FILE *fp, const char *name, const char *hdr,
-		  const unsigned char *data, long len);
-void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
-		      pem_password_cb *cb, void *u);
-int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
-		       void *x,const EVP_CIPHER *enc,unsigned char *kstr,
-		       int klen,pem_password_cb *callback, void *u);
-STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
-	pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int	PEM_read(FILE *fp, char **name, char **header, unsigned char **data,long *len);
+OPENSSL_EXPORT int	PEM_write(FILE *fp, const char *name, const char *hdr, const unsigned char *data, long len);
+OPENSSL_EXPORT void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp, void *x,const EVP_CIPHER *enc,unsigned char *kstr, int klen,pem_password_cb *callback, void *u);
+OPENSSL_EXPORT STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
 
-int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
-		EVP_MD *md_type, unsigned char **ek, int *ekl,
-		unsigned char *iv, EVP_PKEY **pubk, int npubk);
-void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
-		unsigned char *in, int inl);
-int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl,
-		unsigned char *out, int *outl, EVP_PKEY *priv);
+OPENSSL_EXPORT int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk);
+OPENSSL_EXPORT void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, unsigned char *in, int inl);
+OPENSSL_EXPORT int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl, unsigned char *out, int *outl, EVP_PKEY *priv);
 
-void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
-void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
-int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
-		unsigned int *siglen, EVP_PKEY *pkey);
+OPENSSL_EXPORT void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+OPENSSL_EXPORT void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
+OPENSSL_EXPORT int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey);
 
-int	PEM_def_callback(char *buf, int num, int w, void *key);
-void	PEM_proc_type(char *buf, int type);
-void	PEM_dek_info(char *buf, const char *type, int len, char *str);
+OPENSSL_EXPORT int	PEM_def_callback(char *buf, int num, int w, void *key);
+OPENSSL_EXPORT void	PEM_proc_type(char *buf, int type);
+OPENSSL_EXPORT void	PEM_dek_info(char *buf, const char *type, int len, char *str);
 
 
 DECLARE_PEM_rw(X509, X509)
@@ -503,48 +484,33 @@
 
 DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
 
-int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
-int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
-                                  char *, int, pem_password_cb *, void *);
-int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
-int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
-EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
 
-int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
-int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
-int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
-				  char *kstr, int klen,
-				  pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u);
 
-EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
 
-int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
-			      char *kstr,int klen, pem_password_cb *cd, void *u);
+OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u);
 
-EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
-int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+OPENSSL_EXPORT EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+OPENSSL_EXPORT int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
 
 
-EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
-EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
-EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
-EVP_PKEY *b2i_PublicKey_bio(BIO *in);
-int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
-int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+OPENSSL_EXPORT EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+OPENSSL_EXPORT EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+OPENSSL_EXPORT int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+OPENSSL_EXPORT int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
 #ifndef OPENSSL_NO_RC4
-EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
-int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
-		pem_password_cb *cb, void *u);
+OPENSSL_EXPORT EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+OPENSSL_EXPORT int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u);
 #endif
 
 
diff --git a/include/openssl/pkcs8.h b/include/openssl/pkcs8.h
index 9c4f60c..917c7db 100644
--- a/include/openssl/pkcs8.h
+++ b/include/openssl/pkcs8.h
@@ -65,12 +65,15 @@
 extern "C" {
 #endif
 
-X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
-                        int pass_len, uint8_t *salt, size_t salt_len, int iterations,
-                        PKCS8_PRIV_KEY_INFO *p8inf);
+OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+                                       const char *pass, int pass_len,
+                                       uint8_t *salt, size_t salt_len,
+                                       int iterations,
+                                       PKCS8_PRIV_KEY_INFO *p8inf);
 
-PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass,
-                                   int pass_len);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8,
+                                                  const char *pass,
+                                                  int pass_len);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/rand.h b/include/openssl/rand.h
index 62e1037..d17c3ea 100644
--- a/include/openssl/rand.h
+++ b/include/openssl/rand.h
@@ -24,26 +24,26 @@
 
 /* RAND_bytes writes |len| bytes of random data to |buf|. It returns one on
  * success and zero on otherwise. */
-int RAND_bytes(uint8_t *buf, size_t len);
+OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len);
 
 /* RAND_cleanup frees any resources used by the RNG. This is not safe if other
  * threads might still be calling |RAND_bytes|. */
-void RAND_cleanup();
+OPENSSL_EXPORT void RAND_cleanup();
 
 
 /* Deprecated functions */
 
 /* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */
-int RAND_pseudo_bytes(uint8_t *buf, size_t len);
+OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len);
 
 /* RAND_seed does nothing. */
-void RAND_seed(const void *buf, int num);
+OPENSSL_EXPORT void RAND_seed(const void *buf, int num);
 
 /* RAND_add does nothing. */
-void RAND_add(const void *buf, int num, double entropy);
+OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
 
 /* RAND_poll returns one. */
-int RAND_poll(void);
+OPENSSL_EXPORT int RAND_poll(void);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/rc4.h b/include/openssl/rc4.h
index 4b87e8b..4c13117 100644
--- a/include/openssl/rc4.h
+++ b/include/openssl/rc4.h
@@ -74,11 +74,13 @@
 
 /* RC4_set_key performs an RC4 key schedule and initialises |rc4key| with |len|
  * bytes of key material from |key|. */
-void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key);
+OPENSSL_EXPORT void RC4_set_key(RC4_KEY *rc4key, unsigned len,
+                                const uint8_t *key);
 
 /* RC4 encrypts (or decrypts, it's the same with RC4) |len| bytes from |in| to
  * |out|. */
-void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out);
+OPENSSL_EXPORT void RC4(RC4_KEY *key, size_t len, const uint8_t *in,
+                        uint8_t *out);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index 9cc465d..5338827 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -73,17 +73,17 @@
 /* Allocation and destruction. */
 
 /* RSA_new returns a new, empty RSA object or NULL on error. */
-RSA *RSA_new(void);
+OPENSSL_EXPORT RSA *RSA_new(void);
 
 /* RSA_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
-RSA *RSA_new_method(const ENGINE *engine);
+OPENSSL_EXPORT RSA *RSA_new_method(const ENGINE *engine);
 
 /* RSA_free decrements the reference count of |rsa| and frees it if the
  * reference count drops to zero. */
-void RSA_free(RSA *rsa);
+OPENSSL_EXPORT void RSA_free(RSA *rsa);
 
 /* RSA_up_ref increments the reference count of |rsa|. */
-int RSA_up_ref(RSA *rsa);
+OPENSSL_EXPORT int RSA_up_ref(RSA *rsa);
 
 
 /* Key generation. */
@@ -96,7 +96,8 @@
  * with event=3 when a suitable value for |p| is found.
  *
  * It returns one on success or zero on error. */
-int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
+                                       BN_GENCB *cb);
 
 
 /* Encryption / Decryption */
@@ -117,8 +118,9 @@
  * The |padding| argument must be one of the |RSA_*_PADDING| values. If in
  * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING|
  * is the most secure. */
-int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                const uint8_t *in, size_t in_len, int padding);
+OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out,
+                               size_t max_out, const uint8_t *in, size_t in_len,
+                               int padding);
 
 /* RSA_decrypt decrypts |in_len| bytes from |in| with the private key from
  * |rsa| and writes, at most, |max_out| bytes of plaintext to |out|. The
@@ -129,8 +131,9 @@
  * The |padding| argument must be one of the |RSA_*_PADDING| values. If in
  * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING|
  * is the most secure. */
-int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                const uint8_t *in, size_t in_len, int padding);
+OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out,
+                               size_t max_out, const uint8_t *in, size_t in_len,
+                               int padding);
 
 /* RSA_public_encrypt encrypts |flen| bytes from |from| to the public key in
  * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
@@ -141,8 +144,8 @@
  *
  * WARNING: this function is dangerous because it breaks the usual return value
  * convention. Use |RSA_encrypt| instead. */
-int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
-                       int padding);
+OPENSSL_EXPORT int RSA_public_encrypt(int flen, const uint8_t *from,
+                                      uint8_t *to, RSA *rsa, int padding);
 
 /* RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in
  * |rsa| and writes the plaintext to |to|. The |to| buffer must have at
@@ -153,8 +156,8 @@
  *
  * WARNING: this function is dangerous because it breaks the usual return value
  * convention. Use |RSA_decrypt| instead. */
-int RSA_private_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
-                        int padding);
+OPENSSL_EXPORT int RSA_private_decrypt(int flen, const uint8_t *from,
+                                       uint8_t *to, RSA *rsa, int padding);
 
 /* RSA_message_index_PKCS1_type_2 performs the first step of a PKCS #1 padding
  * check for decryption. If the |from_len| bytes pointed to at |from| are a
@@ -167,8 +170,9 @@
  *
  * WARNING: This function behaves differently from the usual OpenSSL convention
  * in that it does NOT put an error on the queue in the error case. */
-int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
-                                   size_t *out_index);
+OPENSSL_EXPORT int RSA_message_index_PKCS1_type_2(const uint8_t *from,
+                                                  size_t from_len,
+                                                  size_t *out_index);
 
 
 /* Signing / Verification */
@@ -182,8 +186,9 @@
  * |NID_sha256|.
  *
  * It returns 1 on success and zero on error. */
-int RSA_sign(int hash_nid, const uint8_t *in, unsigned int in_len, uint8_t *out,
-             unsigned int *out_len, RSA *rsa);
+OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *in,
+                            unsigned int in_len, uint8_t *out,
+                            unsigned int *out_len, RSA *rsa);
 
 /* RSA_sign_raw signs |in_len| bytes from |in| with the public key from |rsa|
  * and writes, at most, |max_out| bytes of encrypted data to |out|. The
@@ -193,8 +198,9 @@
  *
  * The |padding| argument must be one of the |RSA_*_PADDING| values. If in
  * doubt, |RSA_PKCS1_PADDING| is the most common. */
-int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                 const uint8_t *in, size_t in_len, int padding);
+OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                                size_t max_out, const uint8_t *in,
+                                size_t in_len, int padding);
 
 /* RSA_verify verifies that |sig_len| bytes from |sig| are a valid, PKCS#1
  * signature of |msg_len| bytes at |msg| by |rsa|.
@@ -207,8 +213,8 @@
  *
  * WARNING: this differs from the original, OpenSSL function which additionally
  * returned -1 on error. */
-int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
-               const uint8_t *sig, size_t sig_len, RSA *rsa);
+OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
+                              const uint8_t *sig, size_t sig_len, RSA *rsa);
 
 /* RSA_verify_raw verifies |in_len| bytes of signature from |in| using the
  * public key from |rsa| and writes, at most, |max_out| bytes of plaintext to
@@ -219,8 +225,9 @@
  *
  * The |padding| argument must be one of the |RSA_*_PADDING| values. If in
  * doubt, |RSA_PKCS1_PADDING| is the most common. */
-int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                   const uint8_t *in, size_t in_len, int padding);
+OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                                  size_t max_out, const uint8_t *in,
+                                  size_t in_len, int padding);
 
 /* 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
@@ -230,8 +237,8 @@
  *
  * WARNING: this function is dangerous because it breaks the usual return value
  * convention. Use |RSA_sign_raw| instead. */
-int RSA_private_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
-                        int padding);
+OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+                                       uint8_t *to, RSA *rsa, int padding);
 
 /* RSA_private_encrypt verifies |flen| bytes of signature from |from| using the
  * public key in |rsa| and writes the plaintext to |to|. The |to| buffer must
@@ -241,39 +248,39 @@
  *
  * WARNING: this function is dangerous because it breaks the usual return value
  * convention. Use |RSA_verify_raw| instead. */
-int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
-                       int padding);
+OPENSSL_EXPORT int RSA_public_decrypt(int flen, const uint8_t *from,
+                                      uint8_t *to, RSA *rsa, int padding);
 
 
 /* Utility functions. */
 
 /* RSA_size returns the number of bytes in the modulus, which is also the size
  * of a signature of encrypted value using |rsa|. */
-unsigned RSA_size(const RSA *rsa);
+OPENSSL_EXPORT unsigned RSA_size(const RSA *rsa);
 
 /* RSA_is_opaque returns one if |rsa| is opaque and doesn't expose its key
  * material. Otherwise it return zero. */
-int RSA_is_opaque(const RSA *rsa);
+OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa);
 
 /* RSAPublicKey_dup allocates a fresh |RSA| and copies the private key from
  * |rsa| into it. It returns the fresh |RSA| object, or NULL on error. */
-RSA *RSAPublicKey_dup(const RSA *rsa);
+OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa);
 
 /* RSAPrivateKey_dup allocates a fresh |RSA| and copies the private key from
  * |rsa| into it. It returns the fresh |RSA| object, or NULL on error. */
-RSA *RSAPrivateKey_dup(const RSA *rsa);
+OPENSSL_EXPORT RSA *RSAPrivateKey_dup(const RSA *rsa);
 
 /* RSA_check_key performs basic validatity tests on |rsa|. It returns one if
  * they pass and zero otherwise. Opaque keys and public keys always pass. If it
  * returns zero then a more detailed error is available on the error queue. */
-int RSA_check_key(const RSA *rsa);
+OPENSSL_EXPORT int RSA_check_key(const RSA *rsa);
 
 /* RSA_recover_crt_params uses |rsa->n|, |rsa->d| and |rsa->e| in order to
  * calculate the two primes used and thus the precomputed, CRT values. These
  * values are set in the |p|, |q|, |dmp1|, |dmq1| and |iqmp| members of |rsa|,
  * which must be |NULL| on entry. It returns one on success and zero
  * otherwise. */
-int RSA_recover_crt_params(RSA *rsa);
+OPENSSL_EXPORT int RSA_recover_crt_params(RSA *rsa);
 
 
 /* ASN.1 functions. */
@@ -284,13 +291,13 @@
  * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
 
 /* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
  * NULL then the result is written to |*outp| and |*outp| is advanced just past
  * the output. It returns the number of bytes in the result, whether written or
  * not, or a negative value on error. */
-int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
+OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
 
 /* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
  * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
@@ -298,23 +305,25 @@
  * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
  * successful exit, |*inp| is advanced past the DER structure. It returns the
  * result or NULL on error. */
-RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
 
 /* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
  * NULL then the result is written to |*outp| and |*outp| is advanced just past
  * the output. It returns the number of bytes in the result, whether written or
  * not, or a negative value on error. */
-int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
+OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
 
 
 /* ex_data functions.
  *
  * These functions are wrappers. See |ex_data.h| for details. */
 
-int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int RSA_set_ex_data(RSA *r, int idx, void *arg);
-void *RSA_get_ex_data(const RSA *r, int idx);
+OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp,
+                                        CRYPTO_EX_new *new_func,
+                                        CRYPTO_EX_dup *dup_func,
+                                        CRYPTO_EX_free *free_func);
+OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg);
+OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
 
 /* RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key
  * material. This may be set if, for instance, it is wrapping some other crypto
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index 2eda284..bc10d38 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -78,24 +78,24 @@
 #define SHA_LONG uint32_t
 
 /* SHA1_Init initialises |sha| and returns one. */
-int SHA1_Init(SHA_CTX *sha);
+OPENSSL_EXPORT int SHA1_Init(SHA_CTX *sha);
 
 /* SHA1_Update adds |len| bytes from |data| to |sha| and returns one. */
-int SHA1_Update(SHA_CTX *sha, const void *data, size_t len);
+OPENSSL_EXPORT int SHA1_Update(SHA_CTX *sha, const void *data, size_t len);
 
 /* SHA1_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. It
  * returns one. */
-int SHA1_Final(uint8_t *md, SHA_CTX *sha);
+OPENSSL_EXPORT int SHA1_Final(uint8_t *md, SHA_CTX *sha);
 
 /* SHA1 writes the digest of |len| bytes from |data| to |out| and returns
  * |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in
  * |out|. */
-uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out);
+OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out);
 
 /* SHA1_Transform is a low-level function that performs a single, SHA-1 block
  * transformation using the state from |sha| and 64 bytes from |block|. */
-void SHA1_Transform(SHA_CTX *sha, const uint8_t *block);
+OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, const uint8_t *block);
 
 struct sha_state_st {
   uint32_t h0, h1, h2, h3, h4;
@@ -114,19 +114,19 @@
 #define SHA224_DIGEST_LENGTH 28
 
 /* SHA224_Init initialises |sha| and returns 1. */
-int SHA224_Init(SHA256_CTX *sha);
+OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha);
 
 /* SHA224_Update adds |len| bytes from |data| to |sha|. */
-int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len);
+OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len);
 
 /* SHA224_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. */
-int SHA224_Final(uint8_t *md, SHA256_CTX *sha);
+OPENSSL_EXPORT int SHA224_Final(uint8_t *md, SHA256_CTX *sha);
 
 /* SHA224 writes the digest of |len| bytes from |data| to |out| and returns
  * |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in
  * |out|. */
-uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out);
+OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out);
 
 
 /* SHA-256. */
@@ -138,23 +138,23 @@
 #define SHA256_DIGEST_LENGTH 32
 
 /* SHA256_Init initialises |sha| and returns 1. */
-int SHA256_Init(SHA256_CTX *sha);
+OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha);
 
 /* SHA256_Update adds |len| bytes from |data| to |sha|. */
-int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len);
+OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len);
 
 /* SHA256_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. */
-int SHA256_Final(uint8_t *md, SHA256_CTX *sha);
+OPENSSL_EXPORT int SHA256_Final(uint8_t *md, SHA256_CTX *sha);
 
 /* SHA256 writes the digest of |len| bytes from |data| to |out| and returns
  * |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in
  * |out|. */
-uint8_t *SHA256(const uint8_t *data, size_t len ,uint8_t *out);
+OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out);
 
 /* SHA256_Transform is a low-level function that performs a single, SHA-1 block
  * transformation using the state from |sha| and 64 bytes from |block|. */
-void SHA256_Transform(SHA256_CTX *sha, const uint8_t *data);
+OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, const uint8_t *data);
 
 struct sha256_state_st {
   uint32_t h[8];
@@ -173,23 +173,23 @@
 #define SHA384_DIGEST_LENGTH 48
 
 /* SHA384_Init initialises |sha| and returns 1. */
-int SHA384_Init(SHA512_CTX *sha);
+OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha);
 
 /* SHA384_Update adds |len| bytes from |data| to |sha|. */
-int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len);
+OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA384_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. */
-int SHA384_Final(uint8_t *md, SHA512_CTX *sha);
+OPENSSL_EXPORT int SHA384_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA384 writes the digest of |len| bytes from |data| to |out| and returns
  * |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in
  * |out|. */
-uint8_t *SHA384(const uint8_t *data, size_t len ,uint8_t *out);
+OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out);
 
 /* SHA384_Transform is a low-level function that performs a single, SHA-1 block
  * transformation using the state from |sha| and 64 bytes from |block|. */
-void SHA384_Transform(SHA512_CTX *sha, const uint8_t *data);
+OPENSSL_EXPORT void SHA384_Transform(SHA512_CTX *sha, const uint8_t *data);
 
 
 /* SHA-512. */
@@ -201,23 +201,23 @@
 #define SHA512_DIGEST_LENGTH 64
 
 /* SHA512_Init initialises |sha| and returns 1. */
-int SHA512_Init(SHA512_CTX *sha);
+OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha);
 
 /* SHA512_Update adds |len| bytes from |data| to |sha|. */
-int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len);
+OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA512_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. */
-int SHA512_Final(uint8_t *md, SHA512_CTX *sha);
+OPENSSL_EXPORT int SHA512_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA512 writes the digest of |len| bytes from |data| to |out| and returns
  * |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in
  * |out|. */
-uint8_t *SHA512(const uint8_t *data, size_t len ,uint8_t *out);
+OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out);
 
 /* SHA512_Transform is a low-level function that performs a single, SHA-1 block
  * transformation using the state from |sha| and 64 bytes from |block|. */
-void SHA512_Transform(SHA512_CTX *sha, const uint8_t *data);
+OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, const uint8_t *data);
 
 struct sha512_state_st {
   uint64_t h[8];
diff --git a/include/openssl/srtp.h b/include/openssl/srtp.h
index c0cf33e..3e29e5d 100644
--- a/include/openssl/srtp.h
+++ b/include/openssl/srtp.h
@@ -130,12 +130,14 @@
 #define SRTP_NULL_SHA1_80      0x0005
 #define SRTP_NULL_SHA1_32      0x0006
 
-int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
-int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
-SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,
+                                               const char *profiles);
+OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+OPENSSL_EXPORT SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
 
-STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
-SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *
+    SSL_get_srtp_profiles(SSL *ssl);
+OPENSSL_EXPORT SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 550361c..fab2e56 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -717,8 +717,8 @@
 #define SSL_clear_cert_flags(s,op) \
 	SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
 
-void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
-void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+OPENSSL_EXPORT void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+OPENSSL_EXPORT void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
 #define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 #define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 
@@ -768,7 +768,7 @@
  * it sets |out_data| to point to the extension contents (not including the type
  * and length bytes), sets |out_len| to the length of the extension contents
  * and returns one. */
-char
+OPENSSL_EXPORT char
 SSL_early_callback_ctx_extension_get(const struct ssl_early_callback_ctx *ctx,
 				     uint16_t extension_type,
 				     const unsigned char **out_data,
@@ -1100,7 +1100,7 @@
 #define SSL_SESS_CACHE_NO_INTERNAL \
 	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
 
-LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
 #define SSL_CTX_sess_number(ctx) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
 #define SSL_CTX_sess_connect(ctx) \
@@ -1130,45 +1130,45 @@
 #define SSL_CTX_enable_tls_channel_id(ctx) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
 
-void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
-int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
-void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess));
-void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
-void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy));
-SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy);
+OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
+OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
+OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess));
+OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy));
+OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy);
 /* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
  * that the session isn't currently unavailable. SSL_get_error will then return
  * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
  * lookup has completed. */
-SSL_SESSION *SSL_magic_pending_session_ptr(void);
-void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val));
-void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
-void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
-int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
-void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
-void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
+OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
+OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val));
+OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
+OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
 #ifndef OPENSSL_NO_ENGINE
-int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+OPENSSL_EXPORT int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
 #endif
-void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
-void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
+OPENSSL_EXPORT void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
+OPENSSL_EXPORT void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
 #ifndef OPENSSL_NO_NEXTPROTONEG
-void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
+OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
 					   int (*cb) (SSL *ssl,
 						      const unsigned char **out,
 						      unsigned int *outlen,
 						      void *arg), void *arg);
-void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
 				      int (*cb) (SSL *ssl, unsigned char **out,
 						 unsigned char *outlen,
 						 const unsigned char *in,
 						 unsigned int inlen, void *arg),
 				      void *arg);
-void SSL_get0_next_proto_negotiated(const SSL *s,
+OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *s,
 				    const uint8_t **data, unsigned *len);
 #endif
 
-int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+OPENSSL_EXPORT int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
 			  const unsigned char *in, unsigned int inlen,
 			  const unsigned char *client, unsigned int client_len);
 
@@ -1176,11 +1176,11 @@
 #define OPENSSL_NPN_NEGOTIATED	1
 #define OPENSSL_NPN_NO_OVERLAP	2
 
-int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
+OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
 			    unsigned protos_len);
-int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
+OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
 			unsigned protos_len);
-void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
+OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
 				int (*cb) (SSL *ssl,
 					   const unsigned char **out,
 					   unsigned char *outlen,
@@ -1188,31 +1188,32 @@
 					   unsigned int inlen,
 					   void *arg),
 				void *arg);
-void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
-			    unsigned *len);
-
+OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+			    unsigned *len); 
 /* the maximum length of the buffer given to callbacks containing the
  * resulting identity/psk */
 #define PSK_MAX_IDENTITY_LEN 128
 #define PSK_MAX_PSK_LEN 256
-void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
+OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
 	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
 		char *identity, unsigned int max_identity_len, unsigned char *psk,
 		unsigned int max_psk_len));
-void SSL_set_psk_client_callback(SSL *ssl, 
+OPENSSL_EXPORT void SSL_set_psk_client_callback(SSL *ssl, 
 	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
 		char *identity, unsigned int max_identity_len, unsigned char *psk,
 		unsigned int max_psk_len));
-void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
+OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
 	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
 		unsigned char *psk, unsigned int max_psk_len));
-void SSL_set_psk_server_callback(SSL *ssl,
+OPENSSL_EXPORT void SSL_set_psk_server_callback(SSL *ssl,
 	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
 		unsigned char *psk, unsigned int max_psk_len));
-int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
-int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
-const char *SSL_get_psk_identity_hint(const SSL *s);
-const char *SSL_get_psk_identity(const SSL *s);
+OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *s);
+OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *s);
+OPENSSL_EXPORT void ssl_update_cache(SSL *s, int mode);
+OPENSSL_EXPORT int ssl_get_new_session(SSL *s, int session);
 
 #define SSL_NOTHING	1
 #define SSL_WRITING	2
@@ -1547,8 +1548,8 @@
  *   -- that we sent (SSL_get_finished)
  *   -- that we expected from peer (SSL_get_peer_finished).
  * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
-size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
-size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+OPENSSL_EXPORT size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
 
 /* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options
  * are 'ored' with SSL_VERIFY_PEER if they are desired */
@@ -1932,301 +1933,292 @@
 	SSL_ctrl(s, SSL_CTRL_FALLBACK_SCSV, 0, NULL)
 
 #ifndef OPENSSL_NO_BIO
-BIO_METHOD *BIO_f_ssl(void);
-BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
-BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
-BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
-void BIO_ssl_shutdown(BIO *ssl_bio);
+OPENSSL_EXPORT BIO_METHOD *BIO_f_ssl(void);
+OPENSSL_EXPORT BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
+OPENSSL_EXPORT BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+OPENSSL_EXPORT BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+OPENSSL_EXPORT void BIO_ssl_shutdown(BIO *ssl_bio);
 
 #endif
 
-int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
-int	SSL_CTX_set_cipher_list_tls11(SSL_CTX *,const char *str);
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
-void	SSL_CTX_free(SSL_CTX *);
-long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
-long SSL_CTX_get_timeout(const SSL_CTX *ctx);
-X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
-void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
-int SSL_want(const SSL *s);
-int	SSL_clear(SSL *s);
+OPENSSL_EXPORT int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
+OPENSSL_EXPORT int	SSL_CTX_set_cipher_list_tls11(SSL_CTX *,const char *str);
+OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
+OPENSSL_EXPORT void	SSL_CTX_free(SSL_CTX *);
+OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
+OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
+OPENSSL_EXPORT int SSL_want(const SSL *s);
+OPENSSL_EXPORT int	SSL_clear(SSL *s);
 
-void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
+OPENSSL_EXPORT void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
 
-const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
-int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
-const char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
-const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
-unsigned long 	SSL_CIPHER_get_id(const SSL_CIPHER *c);
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+OPENSSL_EXPORT int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
+OPENSSL_EXPORT const char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
+OPENSSL_EXPORT const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
+OPENSSL_EXPORT unsigned long 	SSL_CIPHER_get_id(const SSL_CIPHER *c);
 
-int	SSL_get_fd(const SSL *s);
-int	SSL_get_rfd(const SSL *s);
-int	SSL_get_wfd(const SSL *s);
-const char  * SSL_get_cipher_list(const SSL *s,int n);
-char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
-int	SSL_get_read_ahead(const SSL * s);
-int	SSL_pending(const SSL *s);
+OPENSSL_EXPORT int	SSL_get_fd(const SSL *s);
+OPENSSL_EXPORT int	SSL_get_rfd(const SSL *s);
+OPENSSL_EXPORT int	SSL_get_wfd(const SSL *s);
+OPENSSL_EXPORT const char  * SSL_get_cipher_list(const SSL *s,int n);
+OPENSSL_EXPORT char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+OPENSSL_EXPORT int	SSL_get_read_ahead(const SSL * s);
+OPENSSL_EXPORT int	SSL_pending(const SSL *s);
 #ifndef OPENSSL_NO_SOCK
-int	SSL_set_fd(SSL *s, int fd);
-int	SSL_set_rfd(SSL *s, int fd);
-int	SSL_set_wfd(SSL *s, int fd);
+OPENSSL_EXPORT int	SSL_set_fd(SSL *s, int fd);
+OPENSSL_EXPORT int	SSL_set_rfd(SSL *s, int fd);
+OPENSSL_EXPORT int	SSL_set_wfd(SSL *s, int fd);
 #endif
 #ifndef OPENSSL_NO_BIO
-void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
-BIO *	SSL_get_rbio(const SSL *s);
-BIO *	SSL_get_wbio(const SSL *s);
+OPENSSL_EXPORT void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
+OPENSSL_EXPORT BIO *	SSL_get_rbio(const SSL *s);
+OPENSSL_EXPORT BIO *	SSL_get_wbio(const SSL *s);
 #endif
-int	SSL_set_cipher_list(SSL *s, const char *str);
-void	SSL_set_read_ahead(SSL *s, int yes);
-int	SSL_get_verify_mode(const SSL *s);
-int	SSL_get_verify_depth(const SSL *s);
-int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
-void	SSL_set_verify(SSL *s, int mode,
-		       int (*callback)(int ok,X509_STORE_CTX *ctx));
-void	SSL_set_verify_depth(SSL *s, int depth);
-void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg);
-int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
-int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
-int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
-int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
-int	SSL_use_certificate(SSL *ssl, X509 *x);
-int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+OPENSSL_EXPORT int	SSL_set_cipher_list(SSL *s, const char *str);
+OPENSSL_EXPORT void	SSL_set_read_ahead(SSL *s, int yes);
+OPENSSL_EXPORT int	SSL_get_verify_mode(const SSL *s);
+OPENSSL_EXPORT int	SSL_get_verify_depth(const SSL *s);
+OPENSSL_EXPORT int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
+OPENSSL_EXPORT void	SSL_set_verify(SSL *s, int mode, int (*callback)(int ok,X509_STORE_CTX *ctx));
+OPENSSL_EXPORT void	SSL_set_verify_depth(SSL *s, int depth);
+OPENSSL_EXPORT void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg);
+OPENSSL_EXPORT int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+OPENSSL_EXPORT int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+OPENSSL_EXPORT int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+OPENSSL_EXPORT int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+OPENSSL_EXPORT int	SSL_use_certificate(SSL *ssl, X509 *x);
+OPENSSL_EXPORT int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
 
 #ifndef OPENSSL_NO_STDIO
-int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
-int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
-int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
-int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
-int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
-int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
-int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
-STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
-int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
-					    const char *file);
+OPENSSL_EXPORT int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+OPENSSL_EXPORT int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+OPENSSL_EXPORT int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+OPENSSL_EXPORT int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+OPENSSL_EXPORT int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+OPENSSL_EXPORT int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+OPENSSL_EXPORT int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+OPENSSL_EXPORT int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, const char *file);
 #ifndef OPENSSL_SYS_VMS
 #ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
-int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
-					   const char *dir);
+OPENSSL_EXPORT int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, const char *dir);
 #endif
 #endif
 
 #endif
 
-void	SSL_load_error_strings(void );
-const char *SSL_state_string(const SSL *s);
-const char *SSL_rstate_string(const SSL *s);
-const char *SSL_state_string_long(const SSL *s);
-const char *SSL_rstate_string_long(const SSL *s);
-long	SSL_SESSION_get_time(const SSL_SESSION *s);
-long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
-long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
-long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
-X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
-int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
-			       unsigned int sid_ctx_len);
+OPENSSL_EXPORT void	SSL_load_error_strings(void );
+OPENSSL_EXPORT const char *SSL_state_string(const SSL *s);
+OPENSSL_EXPORT const char *SSL_rstate_string(const SSL *s);
+OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
+OPENSSL_EXPORT const char *SSL_rstate_string_long(const SSL *s);
+OPENSSL_EXPORT long	SSL_SESSION_get_time(const SSL_SESSION *s);
+OPENSSL_EXPORT long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
+OPENSSL_EXPORT long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
+OPENSSL_EXPORT long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
+OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx, unsigned int sid_ctx_len);
 
-SSL_SESSION *SSL_SESSION_new(void);
-const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
-					unsigned int *len);
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(void);
+OPENSSL_EXPORT const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
-int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
+OPENSSL_EXPORT int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
 #endif
 #ifndef OPENSSL_NO_BIO
-int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
+OPENSSL_EXPORT int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
 #endif
-void	SSL_SESSION_free(SSL_SESSION *ses);
-int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
-int	SSL_set_session(SSL *to, SSL_SESSION *session);
-int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
-int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
-int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
-int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
-					unsigned int id_len);
-SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp,
-			     long length);
+OPENSSL_EXPORT void	SSL_SESSION_free(SSL_SESSION *ses);
+OPENSSL_EXPORT int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+OPENSSL_EXPORT int	SSL_set_session(SSL *to, SSL_SESSION *session);
+OPENSSL_EXPORT int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+OPENSSL_EXPORT int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+OPENSSL_EXPORT int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+OPENSSL_EXPORT int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+OPENSSL_EXPORT int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, unsigned int id_len);
+OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp, long length);
 
 #ifdef HEADER_X509_H
-X509 *	SSL_get_peer_certificate(const SSL *s);
+OPENSSL_EXPORT X509 *	SSL_get_peer_certificate(const SSL *s);
 #endif
 
-STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
 
-int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
-int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
-int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
-void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
+OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
+OPENSSL_EXPORT void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
 			int (*callback)(int, X509_STORE_CTX *));
-void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
-void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
-void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg);
-int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
-int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
-int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
-int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
+OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
+OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
+OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg);
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
 	const unsigned char *d, long len);
-int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
-int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
+OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
 
-void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
-void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
 
-int SSL_CTX_check_private_key(const SSL_CTX *ctx);
-int SSL_check_private_key(const SSL *ctx);
+OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+OPENSSL_EXPORT int SSL_check_private_key(const SSL *ctx);
 
-int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
-				       unsigned int sid_ctx_len);
+OPENSSL_EXPORT int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx, unsigned int sid_ctx_len);
 
-SSL *	SSL_new(SSL_CTX *ctx);
-int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
-				   unsigned int sid_ctx_len);
+OPENSSL_EXPORT SSL *	SSL_new(SSL_CTX *ctx);
+OPENSSL_EXPORT int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx, unsigned int sid_ctx_len);
 
-int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
-int SSL_set_purpose(SSL *s, int purpose);
-int SSL_CTX_set_trust(SSL_CTX *s, int trust);
-int SSL_set_trust(SSL *s, int trust);
+OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+OPENSSL_EXPORT int SSL_set_purpose(SSL *s, int purpose);
+OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+OPENSSL_EXPORT int SSL_set_trust(SSL *s, int trust);
 
-int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
-int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
 
-X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
-X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
 
-void	SSL_certs_clear(SSL *s);
-void	SSL_free(SSL *ssl);
-int 	SSL_accept(SSL *ssl);
-int 	SSL_connect(SSL *ssl);
-int 	SSL_read(SSL *ssl,void *buf,int num);
-int 	SSL_peek(SSL *ssl,void *buf,int num);
-int 	SSL_write(SSL *ssl,const void *buf,int num);
-long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
-long	SSL_callback_ctrl(SSL *, int, void (*)(void));
-long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
-long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+OPENSSL_EXPORT void	SSL_certs_clear(SSL *s);
+OPENSSL_EXPORT void	SSL_free(SSL *ssl);
+OPENSSL_EXPORT int 	SSL_accept(SSL *ssl);
+OPENSSL_EXPORT int 	SSL_connect(SSL *ssl);
+OPENSSL_EXPORT int 	SSL_read(SSL *ssl,void *buf,int num);
+OPENSSL_EXPORT int 	SSL_peek(SSL *ssl,void *buf,int num);
+OPENSSL_EXPORT int 	SSL_write(SSL *ssl,const void *buf,int num);
+OPENSSL_EXPORT long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
+OPENSSL_EXPORT long	SSL_callback_ctrl(SSL *, int, void (*)(void));
+OPENSSL_EXPORT long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
+OPENSSL_EXPORT long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
 
-int	SSL_get_error(const SSL *s,int ret_code);
-const char *SSL_get_version(const SSL *s);
+OPENSSL_EXPORT int	SSL_get_error(const SSL *s,int ret_code);
+OPENSSL_EXPORT const char *SSL_get_version(const SSL *s);
 
-int SSL_CIPHER_is_AES(const SSL_CIPHER *c);
-int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c);
-int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c);
-int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c);
+OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *c);
+OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c);
+OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c);
+OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c);
 
 /* This sets the 'default' SSL version that SSL_new() will create */
-int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+OPENSSL_EXPORT int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
-const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
-const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
-const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
 
-const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
 
-const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
-const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
-const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
 
-const SSL_METHOD *TLSv1_1_method(void);		/* TLSv1.1 */
-const SSL_METHOD *TLSv1_1_server_method(void);	/* TLSv1.1 */
-const SSL_METHOD *TLSv1_1_client_method(void);	/* TLSv1.1 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);		/* TLSv1.1 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);	/* TLSv1.1 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);	/* TLSv1.1 */
 
-const SSL_METHOD *TLSv1_2_method(void);		/* TLSv1.2 */
-const SSL_METHOD *TLSv1_2_server_method(void);	/* TLSv1.2 */
-const SSL_METHOD *TLSv1_2_client_method(void);	/* TLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);		/* TLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);	/* TLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);	/* TLSv1.2 */
 
 
-const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
-const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
-const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
 
-const SSL_METHOD *DTLSv1_2_method(void);	/* DTLSv1.2 */
-const SSL_METHOD *DTLSv1_2_server_method(void);	/* DTLSv1.2 */
-const SSL_METHOD *DTLSv1_2_client_method(void);	/* DTLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);	/* DTLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);	/* DTLSv1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);	/* DTLSv1.2 */
 
-const SSL_METHOD *DTLS_method(void);		/* DTLS 1.0 and 1.2 */
-const SSL_METHOD *DTLS_server_method(void);	/* DTLS 1.0 and 1.2 */
-const SSL_METHOD *DTLS_client_method(void);	/* DTLS 1.0 and 1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);		/* DTLS 1.0 and 1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);	/* DTLS 1.0 and 1.2 */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);	/* DTLS 1.0 and 1.2 */
 
-STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
-int SSL_do_handshake(SSL *s);
-int SSL_renegotiate(SSL *s);
-int SSL_renegotiate_abbreviated(SSL *s);
-int SSL_renegotiate_pending(SSL *s);
-int SSL_shutdown(SSL *s);
+OPENSSL_EXPORT int SSL_do_handshake(SSL *s);
+OPENSSL_EXPORT int SSL_renegotiate(SSL *s);
+OPENSSL_EXPORT int SSL_renegotiate_abbreviated(SSL *s);
+OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *s);
+OPENSSL_EXPORT int SSL_shutdown(SSL *s);
 
-const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
-const SSL_METHOD *SSL_get_ssl_method(SSL *s);
-int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
-const char *SSL_alert_type_string_long(int value);
-const char *SSL_alert_type_string(int value);
-const char *SSL_alert_desc_string_long(int value);
-const char *SSL_alert_desc_string(int value);
+OPENSSL_EXPORT const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
+OPENSSL_EXPORT const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
+OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
+OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
+OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
+OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
 
-void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
-void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
-STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
-STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
-int SSL_add_client_CA(SSL *ssl,X509 *x);
-int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl,X509 *x);
+OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
 
-void SSL_set_connect_state(SSL *s);
-void SSL_set_accept_state(SSL *s);
+OPENSSL_EXPORT void SSL_set_connect_state(SSL *s);
+OPENSSL_EXPORT void SSL_set_accept_state(SSL *s);
 
-long SSL_get_default_timeout(const SSL *s);
+OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
 
-int SSL_library_init(void );
+OPENSSL_EXPORT int SSL_library_init(void );
 
-const char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);
-STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
 
-X509 *SSL_get_certificate(const SSL *ssl);
-/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl);
+OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
+OPENSSL_EXPORT /* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl);
 
-X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
-EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
 
-void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
-int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
-void SSL_set_quiet_shutdown(SSL *ssl,int mode);
-int SSL_get_quiet_shutdown(const SSL *ssl);
-void SSL_set_shutdown(SSL *ssl,int mode);
-int SSL_get_shutdown(const SSL *ssl);
-int SSL_version(const SSL *ssl);
-int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
-int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
+OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl,int mode);
+OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
+OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl,int mode);
+OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
+OPENSSL_EXPORT int SSL_version(const SSL *ssl);
+OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
 	const char *CApath);
 #define SSL_get0_session SSL_get_session /* just peek at pointer */
-SSL_SESSION *SSL_get_session(const SSL *ssl);
-SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
-SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
-SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx);
-void SSL_set_info_callback(SSL *ssl,
+OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
+OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx);
+OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
 			   void (*cb)(const SSL *ssl,int type,int val));
-void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
-int SSL_state(const SSL *ssl);
-void SSL_set_state(SSL *ssl, int state);
+OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
+OPENSSL_EXPORT int SSL_state(const SSL *ssl);
+OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
 
-void SSL_set_verify_result(SSL *ssl,long v);
-long SSL_get_verify_result(const SSL *ssl);
+OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl,long v);
+OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
 
-int SSL_set_ex_data(SSL *ssl,int idx,void *data);
-void *SSL_get_ex_data(const SSL *ssl,int idx);
-int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl,int idx,void *data);
+OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl,int idx);
+OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
 
-int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
-void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
-int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
+OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
+OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
 
-int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
-void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
-int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
+OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
+OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
 
-int SSL_get_ex_data_X509_STORE_CTX_idx(void );
+OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void );
 
 #define SSL_CTX_sess_set_cache_size(ctx,t) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
@@ -2258,76 +2250,74 @@
 	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
 
      /* NB: the keylength is only applicable when is_export is true */
-void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
 				  RSA *(*cb)(SSL *ssl,int is_export,
 					     int keylength));
 
-void SSL_set_tmp_rsa_callback(SSL *ssl,
+OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl,
 				  RSA *(*cb)(SSL *ssl,int is_export,
 					     int keylength));
 #ifndef OPENSSL_NO_DH
-void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
 				 DH *(*dh)(SSL *ssl,int is_export,
 					   int keylength));
-void SSL_set_tmp_dh_callback(SSL *ssl,
+OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
 				 DH *(*dh)(SSL *ssl,int is_export,
 					   int keylength));
 #endif
 #ifndef OPENSSL_NO_ECDH
-void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
+OPENSSL_EXPORT void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
 				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
 					   int keylength));
-void SSL_set_tmp_ecdh_callback(SSL *ssl,
+OPENSSL_EXPORT void SSL_set_tmp_ecdh_callback(SSL *ssl,
 				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
 					   int keylength));
 #endif
 
-const void *SSL_get_current_compression(SSL *s);
-const void *SSL_get_current_expansion(SSL *s);
-const char *SSL_COMP_get_name(const void *comp);
-void *SSL_COMP_get_compression_methods(void);
-int SSL_COMP_add_compression_method(int id,void *cm);
+OPENSSL_EXPORT const void *SSL_get_current_compression(SSL *s);
+OPENSSL_EXPORT const void *SSL_get_current_expansion(SSL *s);
+OPENSSL_EXPORT const char *SSL_COMP_get_name(const void *comp);
+OPENSSL_EXPORT void *SSL_COMP_get_compression_methods(void);
+OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id,void *cm);
 
 /* TLS extensions functions */
-int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+OPENSSL_EXPORT int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
 
-int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
-				  void *arg);
+OPENSSL_EXPORT int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, void *arg);
 
 /* Pre-shared secret session resumption functions */
-int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
+OPENSSL_EXPORT int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
 
-void SSL_set_debug(SSL *s, int debug);
-int SSL_cache_hit(SSL *s);
-int SSL_is_server(SSL *s);
+OPENSSL_EXPORT void SSL_set_debug(SSL *s, int debug);
+OPENSSL_EXPORT int SSL_cache_hit(SSL *s);
+OPENSSL_EXPORT int SSL_is_server(SSL *s);
 
 /* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
  * SSL_SESSION structures so that a test can ensure that outside code agrees on
  * these values. */
-void SSL_get_structure_sizes(size_t* ssl_size, size_t* ssl_ctx_size,
-                             size_t* ssl_session_size);
+OPENSSL_EXPORT void SSL_get_structure_sizes(size_t* ssl_size, size_t* ssl_ctx_size, size_t* ssl_session_size);
 
-SSL_CONF_CTX *SSL_CONF_CTX_new(void);
-int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx);
-void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
-unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
-unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
-int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre);
+OPENSSL_EXPORT SSL_CONF_CTX *SSL_CONF_CTX_new(void);
+OPENSSL_EXPORT int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx);
+OPENSSL_EXPORT void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
+OPENSSL_EXPORT unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+OPENSSL_EXPORT unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+OPENSSL_EXPORT int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre);
 
-void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
-void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);
+OPENSSL_EXPORT void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
+OPENSSL_EXPORT void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);
 
-int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value);
-int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
-int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd);
+OPENSSL_EXPORT int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value);
+OPENSSL_EXPORT int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
+OPENSSL_EXPORT int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd);
 
 #ifndef OPENSSL_NO_SSL_TRACE
-void SSL_trace(int write_p, int version, int content_type,
+OPENSSL_EXPORT void SSL_trace(int write_p, int version, int content_type,
 		const void *buf, size_t len, SSL *ssl, void *arg);
-const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
+OPENSSL_EXPORT const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
 #endif
 
-void ERR_load_SSL_strings(void);
+OPENSSL_EXPORT void ERR_load_SSL_strings(void);
 
 
 #ifdef  __cplusplus
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index 53bf167..55e9508 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -202,49 +202,49 @@
 
 /* sk_new creates a new, empty stack with the given comparision function, which
  * may be zero. It returns the new stack or NULL on allocation failure. */
-_STACK *sk_new(stack_cmp_func comp);
+OPENSSL_EXPORT _STACK *sk_new(stack_cmp_func comp);
 
 /* sk_new_null creates a new, empty stack. It returns the new stack or NULL on
  * allocation failure. */
-_STACK *sk_new_null(void);
+OPENSSL_EXPORT _STACK *sk_new_null(void);
 
 /* sk_num returns the number of elements in |s|. */
-size_t sk_num(const _STACK *sk);
+OPENSSL_EXPORT size_t sk_num(const _STACK *sk);
 
 /* sk_zero resets |sk| to the empty state but does nothing to free the
  * individual elements themselves. */
-void sk_zero(_STACK *sk);
+OPENSSL_EXPORT void sk_zero(_STACK *sk);
 
 /* sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of
  * range. */
-void *sk_value(const _STACK *sk, size_t i);
+OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i);
 
 /* sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out
  * of range, it returns NULL. */
-void *sk_set(_STACK *sk, size_t i, void *p);
+OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p);
 
 /* sk_free frees the given stack and array of pointers, but does nothing to
  * free the individual elements. Also see |sk_pop_free|. */
-void sk_free(_STACK *sk);
+OPENSSL_EXPORT void sk_free(_STACK *sk);
 
 /* sk_pop_free calls |free_func| on each element in the stack and then frees
  * the stack itself. */
-void sk_pop_free(_STACK *sk, void (*free_func)(void *));
+OPENSSL_EXPORT void sk_pop_free(_STACK *sk, void (*free_func)(void *));
 
 /* sk_insert inserts |p| into the stack at index |where|, moving existing
  * elements if needed. It returns the length of the new stack, or zero on
  * error. */
-size_t sk_insert(_STACK *sk, void *p, size_t where);
+OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where);
 
 /* sk_delete removes the pointer at index |where|, moving other elements down
  * if needed. It returns the removed pointer, or NULL if |where| is out of
  * range. */
-void *sk_delete(_STACK *sk, size_t where);
+OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where);
 
 /* sk_delete_ptr removes, at most, one instance of |p| from the stack based on
  * pointer equality. If an instance of |p| is found then |p| is returned,
  * otherwise it returns NULL. */
-void *sk_delete_ptr(_STACK *sk, void *p);
+OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, void *p);
 
 /* sk_find returns the first value in the stack equal to |p|. If a comparision
  * function has been set on the stack, then equality is defined by it and the
@@ -252,36 +252,36 @@
  * Otherwise pointer equality is used. If a matching element is found, its
  * index is written to |*out_index| (if |out_index| is not NULL) and one is
  * returned. Otherwise zero is returned. */
-int sk_find(_STACK *sk, size_t *out_index, void *p);
+OPENSSL_EXPORT int sk_find(_STACK *sk, size_t *out_index, void *p);
 
 /* sk_shift removes and returns the first element in the stack, or returns NULL
  * if the stack is empty. */
-void *sk_shift(_STACK *sk);
+OPENSSL_EXPORT void *sk_shift(_STACK *sk);
 
 /* sk_push appends |p| to the stack and returns the length of the new stack, or
  * 0 on allocation failure. */
-size_t sk_push(_STACK *sk, void *p);
+OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p);
 
 /* sk_pop returns and removes the last element on the stack, or NULL if the
  * stack is empty. */
-void *sk_pop(_STACK *sk);
+OPENSSL_EXPORT void *sk_pop(_STACK *sk);
 
 /* sk_dup performs a shallow copy of a stack and returns the new stack, or NULL
  * on error. */
-_STACK *sk_dup(const _STACK *sk);
+OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk);
 
 /* sk_sort sorts the elements of |sk| into ascending order based on the
  * comparison function. The stack maintains a |sorted| flag and sorting an
  * already sorted stack is a no-op. */
-void sk_sort(_STACK *sk);
+OPENSSL_EXPORT void sk_sort(_STACK *sk);
 
 /* sk_is_sorted returns one if |sk| is known to be sorted and zero
  * otherwise. */
-int sk_is_sorted(const _STACK *sk);
+OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk);
 
 /* sk_set_cmp_func sets the comparison function to be used by |sk| and returns
  * the previous one. */
-stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp);
+OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp);
 
 
 #if defined(__cplusplus)
diff --git a/include/openssl/thread.h b/include/openssl/thread.h
index ef06f1e..5676280 100644
--- a/include/openssl/thread.h
+++ b/include/openssl/thread.h
@@ -83,7 +83,7 @@
 
 /* CRYPTO_num_locks returns the number of static locks that the callback
  * function passed to |CRYPTO_set_locking_callback| must be able to handle. */
-int CRYPTO_num_locks(void);
+OPENSSL_EXPORT int CRYPTO_num_locks(void);
 
 /* CRYPTO_set_locking_callback sets a callback function that implements locking
  * on behalf of OpenSSL. The callback is called whenever OpenSSL needs to lock
@@ -94,8 +94,8 @@
  * CRYPTO_UNLOCK, to denote the action, and CRYPTO_READ or CRYPTO_WRITE, to
  * indicate the type of lock. The |file| and |line| arguments give the location
  * in the OpenSSL source where the locking action originated. */
-void CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num,
-                                              const char *file, int line));
+OPENSSL_EXPORT void CRYPTO_set_locking_callback(
+    void (*func)(int mode, int lock_num, const char *file, int line));
 
 /* CRYPTO_set_add_lock_callback sets an optional callback which is used when
  * OpenSSL needs to add a fixed amount to an integer. For example, this is used
@@ -108,13 +108,12 @@
  * amount to add to the integer (|amount|, which may be negative), the number
  * of the lock which would have been taken to protect the operation and the
  * position in the OpenSSL code where the operation originated. */
-void CRYPTO_set_add_lock_callback(int (*func)(int *num, int amount,
-                                              int lock_num, const char *file,
-                                              int line));
+OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)(
+    int *num, int amount, int lock_num, const char *file, int line));
 
 /* CRYPTO_get_lock_name returns the name of the lock given by |lock_num|. This
  * can be used in a locking callback for debugging purposes. */
-const char *CRYPTO_get_lock_name(int lock_num);
+OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num);
 
 
 /* CRYPTO_THREADID identifies a thread in a multithreaded program. This
@@ -131,11 +130,12 @@
  * |CRYPTO_THREADID_set_numeric| or |CRYPTO_THREADID_set_pointer| should be
  * used depending on whether thread IDs are numbers or pointers on the host
  * system. */
-int CRYPTO_THREADID_set_callback(
+OPENSSL_EXPORT int CRYPTO_THREADID_set_callback(
     void (*threadid_func)(CRYPTO_THREADID *threadid));
 
-void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
-void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id,
+                                                unsigned long val);
+OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
 
 
 /* Private functions: */
@@ -153,19 +153,20 @@
 /* CRYPTO_lock locks or unlocks the lock specified by |lock_num| (one of
  * |CRYPTO_LOCK_*|). Don't call this directly, rather use one of the
  * CRYPTO_[rw]_(un)lock macros. */
-void CRYPTO_lock(int mode, int lock_num, const char *file, int line);
+OPENSSL_EXPORT void CRYPTO_lock(int mode, int lock_num, const char *file,
+                                int line);
 
 /* CRYPTO_add_lock adds |amount| to |*pointer|, protected by the lock specified
  * by |lock_num|. It returns the new value of |*pointer|. Don't call this
  * function directly, rather use the |CRYPTO_add_lock| macro.
  *
  * TODO(fork): rename to CRYPTO_add_locked. */
-int CRYPTO_add_lock(int *pointer, int amount, int lock_num, const char *file,
-                    int line);
+OPENSSL_EXPORT int CRYPTO_add_lock(int *pointer, int amount, int lock_num,
+                                   const char *file, int line);
 
 
 /* CRYPTO_THREADID_current stores the current thread identifier in |id|. */
-void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
 
 /* CRYPTO_THREADID_cmp returns < 0, 0 or > 0 if |a| is less than, equal to or
  * greater than |b|, respectively. */
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 3b1b51c..b075a20 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -300,8 +300,8 @@
 
 #define TLSEXT_MAXLEN_host_name 255
 
-const char *SSL_get_servername(const SSL *s, const int type);
-int SSL_get_servername_type(const SSL *s);
+OPENSSL_EXPORT const char *SSL_get_servername(const SSL *s, const int type);
+OPENSSL_EXPORT int SSL_get_servername_type(const SSL *s);
 /* SSL_export_keying_material exports a value derived from the master secret,
  * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
  * optional context. (Since a zero length context is allowed, the |use_context|
@@ -309,19 +309,19 @@
  *
  * It returns 1 on success and zero otherwise.
  */
-int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+OPENSSL_EXPORT int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
 	const char *label, size_t llen, const unsigned char *p, size_t plen,
 	int use_context);
 
-int SSL_get_sigalgs(SSL *s, int idx,
+OPENSSL_EXPORT int SSL_get_sigalgs(SSL *s, int idx,
 			int *psign, int *phash, int *psignandhash,
 			unsigned char *rsig, unsigned char *rhash);
 
-int SSL_get_shared_sigalgs(SSL *s, int idx,
+OPENSSL_EXPORT int SSL_get_shared_sigalgs(SSL *s, int idx,
 			int *psign, int *phash, int *psignandhash,
 			unsigned char *rsig, unsigned char *rhash);
 
-int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);
+OPENSSL_EXPORT int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);
 
 #define SSL_set_tlsext_host_name(s,name) \
 SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index d7ab2ce..d07b2f5 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -594,193 +594,192 @@
 #define		X509_CINF_get_extensions(c) ((c)->extensions)
 #define		X509_CINF_get_signature(c) ((c)->signature)
 
-void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
-X509_CRL_METHOD *X509_CRL_METHOD_new(
+OPENSSL_EXPORT void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+OPENSSL_EXPORT X509_CRL_METHOD *X509_CRL_METHOD_new(
 	int (*crl_init)(X509_CRL *crl),
 	int (*crl_free)(X509_CRL *crl),
 	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
 				ASN1_INTEGER *ser, X509_NAME *issuer),
 	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk));
-void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+OPENSSL_EXPORT void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
 
-void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
-void *X509_CRL_get_meth_data(X509_CRL *crl);
+OPENSSL_EXPORT void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+OPENSSL_EXPORT void *X509_CRL_get_meth_data(X509_CRL *crl);
 
 /* This one is only used so that a binary form can output, as in
  * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
 #define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
 
 
-const char *X509_verify_cert_error_string(long n);
+OPENSSL_EXPORT const char *X509_verify_cert_error_string(long n);
 
 #ifndef OPENSSL_NO_EVP
-int X509_verify(X509 *a, EVP_PKEY *r);
+OPENSSL_EXPORT int X509_verify(X509 *a, EVP_PKEY *r);
 
-int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
-int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
-int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+OPENSSL_EXPORT int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
 
-NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
-char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
-EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
-int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+OPENSSL_EXPORT NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
+OPENSSL_EXPORT char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
 
-int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+OPENSSL_EXPORT int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
 
-int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent);
-int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
+OPENSSL_EXPORT int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent);
+OPENSSL_EXPORT int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
 
-int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
+OPENSSL_EXPORT int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+OPENSSL_EXPORT int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
 /* int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); */
-int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
-int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
+OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
+OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
 /* int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); */
-int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
 
-int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
+OPENSSL_EXPORT int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
 		unsigned char *md, unsigned int *len);
-int X509_digest(const X509 *data,const EVP_MD *type,
+OPENSSL_EXPORT int X509_digest(const X509 *data,const EVP_MD *type,
 		unsigned char *md, unsigned int *len);
-int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
+OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
 		unsigned char *md, unsigned int *len);
-int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
+OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
 		unsigned char *md, unsigned int *len);
-int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
+OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
 		unsigned char *md, unsigned int *len);
 #endif
 
 #ifndef OPENSSL_NO_FP_API
-X509 *d2i_X509_fp(FILE *fp, X509 **x509);
-int i2d_X509_fp(FILE *fp,X509 *x509);
-X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
-int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
-X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
-int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
-RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
-int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
-RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
-int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
-RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
-int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
+OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+OPENSSL_EXPORT int i2d_X509_fp(FILE *fp,X509 *x509);
+OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
+OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
+OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
+OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
+OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
+OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
+OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
 #ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
-int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
-DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
-int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
 #endif
 #ifndef OPENSSL_NO_EC
-EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
-int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
-EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
-int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+OPENSSL_EXPORT int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+OPENSSL_EXPORT int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
 #endif
-X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
-int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
-PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
+OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
 						PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
-int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
-int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 #endif
 
 #ifndef OPENSSL_NO_BIO
-X509 *d2i_X509_bio(BIO *bp,X509 **x509);
-int i2d_X509_bio(BIO *bp,X509 *x509);
-X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
-int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
-X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
-int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
-RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
-int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
-RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
-int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
-RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
-int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
+OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp,X509 **x509);
+OPENSSL_EXPORT int i2d_X509_bio(BIO *bp,X509 *x509);
+OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
+OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
+OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
+OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
+OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
+OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
+OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
+OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
 #ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
-int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
-DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
-int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
 #endif
 #ifndef OPENSSL_NO_EC
-EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
-int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
-EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
-int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+OPENSSL_EXPORT int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+OPENSSL_EXPORT int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
 #endif
-X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
-int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
-PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
+OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
 						PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
-int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
-int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
+OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
 #endif
 
-X509 *X509_dup(X509 *x509);
-X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
-X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
-X509_CRL *X509_CRL_dup(X509_CRL *crl);
-X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
-X509_REQ *X509_REQ_dup(X509_REQ *req);
-X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
-int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval);
-void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+OPENSSL_EXPORT X509 *X509_dup(X509 *x509);
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl);
+OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
+OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req);
+OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+OPENSSL_EXPORT int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval);
+OPENSSL_EXPORT void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
 						X509_ALGOR *algor);
-void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+OPENSSL_EXPORT void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
 
-X509_NAME *X509_NAME_dup(X509_NAME *xn);
-X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *xn);
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
 
-int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
-int		X509_cmp_current_time(const ASN1_TIME *s);
-ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
-ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s,
-				int offset_day, long offset_sec, time_t *t);
-ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
+OPENSSL_EXPORT int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
+OPENSSL_EXPORT int		X509_cmp_current_time(const ASN1_TIME *s);
+OPENSSL_EXPORT ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+OPENSSL_EXPORT ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *t);
+OPENSSL_EXPORT ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
 
-const char *	X509_get_default_cert_area(void );
-const char *	X509_get_default_cert_dir(void );
-const char *	X509_get_default_cert_file(void );
-const char *	X509_get_default_cert_dir_env(void );
-const char *	X509_get_default_cert_file_env(void );
-const char *	X509_get_default_private_dir(void );
+OPENSSL_EXPORT const char *	X509_get_default_cert_area(void );
+OPENSSL_EXPORT const char *	X509_get_default_cert_dir(void );
+OPENSSL_EXPORT const char *	X509_get_default_cert_file(void );
+OPENSSL_EXPORT const char *	X509_get_default_cert_dir_env(void );
+OPENSSL_EXPORT const char *	X509_get_default_cert_file_env(void );
+OPENSSL_EXPORT const char *	X509_get_default_private_dir(void );
 
-X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
-X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
+OPENSSL_EXPORT X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+OPENSSL_EXPORT X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
 
 DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
 DECLARE_ASN1_FUNCTIONS(X509_VAL)
 
 DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
 
-int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
-EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
-int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
+OPENSSL_EXPORT int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
+OPENSSL_EXPORT int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
 					   STACK_OF(X509) *chain);
-int		i2d_PUBKEY(const EVP_PKEY *a,unsigned char **pp);
-EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
+OPENSSL_EXPORT int		i2d_PUBKEY(const EVP_PKEY *a,unsigned char **pp);
+OPENSSL_EXPORT EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
 			long length);
-int		i2d_RSA_PUBKEY(const RSA *a,unsigned char **pp);
-RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
+OPENSSL_EXPORT int		i2d_RSA_PUBKEY(const RSA *a,unsigned char **pp);
+OPENSSL_EXPORT RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
 			long length);
 #ifndef OPENSSL_NO_DSA
-int		i2d_DSA_PUBKEY(const DSA *a,unsigned char **pp);
-DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
+OPENSSL_EXPORT int		i2d_DSA_PUBKEY(const DSA *a,unsigned char **pp);
+OPENSSL_EXPORT DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
 			long length);
 #endif
 #ifndef OPENSSL_NO_EC
-int		i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp);
-EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
+OPENSSL_EXPORT int		i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp);
+OPENSSL_EXPORT EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
 			long length);
 #endif
 
@@ -789,7 +788,7 @@
 DECLARE_ASN1_FUNCTIONS(X509_REQ)
 
 DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
-X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
 
 DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
 DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
@@ -798,7 +797,7 @@
 
 DECLARE_ASN1_FUNCTIONS(X509_NAME)
 
-int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+OPENSSL_EXPORT int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(X509_CINF)
 
@@ -807,390 +806,390 @@
 
 DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
 
-int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int X509_set_ex_data(X509 *r, int idx, void *arg);
-void *X509_get_ex_data(X509 *r, int idx);
-int		i2d_X509_AUX(X509 *a,unsigned char **pp);
-X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
+OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg);
+OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx);
+OPENSSL_EXPORT int		i2d_X509_AUX(X509 *a,unsigned char **pp);
+OPENSSL_EXPORT X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
 
-void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+OPENSSL_EXPORT void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
 								const X509 *x);
-int X509_get_signature_nid(const X509 *x);
+OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x);
 
-int X509_alias_set1(X509 *x, unsigned char *name, int len);
-int X509_keyid_set1(X509 *x, unsigned char *id, int len);
-unsigned char * X509_alias_get0(X509 *x, int *len);
-unsigned char * X509_keyid_get0(X509 *x, int *len);
-int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
-int X509_TRUST_set(int *t, int trust);
-int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
-int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
-void X509_trust_clear(X509 *x);
-void X509_reject_clear(X509 *x);
+OPENSSL_EXPORT int X509_alias_set1(X509 *x, unsigned char *name, int len);
+OPENSSL_EXPORT int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+OPENSSL_EXPORT unsigned char * X509_alias_get0(X509 *x, int *len);
+OPENSSL_EXPORT unsigned char * X509_keyid_get0(X509 *x, int *len);
+OPENSSL_EXPORT int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
+OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust);
+OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+OPENSSL_EXPORT void X509_trust_clear(X509 *x);
+OPENSSL_EXPORT void X509_reject_clear(X509 *x);
 
 DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
 DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
 DECLARE_ASN1_FUNCTIONS(X509_CRL)
 
-int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
-int X509_CRL_get0_by_serial(X509_CRL *crl,
+OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl,
 		X509_REVOKED **ret, ASN1_INTEGER *serial);
-int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
 
-X509_PKEY *	X509_PKEY_new(void );
-void		X509_PKEY_free(X509_PKEY *a);
-int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
-X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
+OPENSSL_EXPORT X509_PKEY *	X509_PKEY_new(void );
+OPENSSL_EXPORT void		X509_PKEY_free(X509_PKEY *a);
+OPENSSL_EXPORT int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
+OPENSSL_EXPORT X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
 
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
 
 #ifndef OPENSSL_NO_EVP
-X509_INFO *	X509_INFO_new(void);
-void		X509_INFO_free(X509_INFO *a);
-char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+OPENSSL_EXPORT X509_INFO *	X509_INFO_new(void);
+OPENSSL_EXPORT void		X509_INFO_free(X509_INFO *a);
+OPENSSL_EXPORT char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
 
-int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+OPENSSL_EXPORT int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
 		ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
 
-int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
+OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
 		unsigned char *md,unsigned int *len);
 
-int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+OPENSSL_EXPORT int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
 	      X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
 	      char *data,EVP_PKEY *pkey, const EVP_MD *type);
 
-int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
+OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
 	unsigned char *md,unsigned int *len);
 
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
 	ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
 
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
 	ASN1_BIT_STRING *signature,
 	void *data, EVP_PKEY *pkey, const EVP_MD *type);
-int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it,
 		X509_ALGOR *algor1, X509_ALGOR *algor2,
 	     	ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx);
 #endif
 
-int 		X509_set_version(X509 *x,long version);
-int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
-ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
-int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
-X509_NAME *	X509_get_issuer_name(X509 *a);
-int 		X509_set_subject_name(X509 *x, X509_NAME *name);
-X509_NAME *	X509_get_subject_name(X509 *a);
-int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
-int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
-int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
-EVP_PKEY *	X509_get_pubkey(X509 *x);
-ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
-int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
+OPENSSL_EXPORT int 		X509_set_version(X509 *x,long version);
+OPENSSL_EXPORT int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+OPENSSL_EXPORT ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
+OPENSSL_EXPORT int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
+OPENSSL_EXPORT X509_NAME *	X509_get_issuer_name(X509 *a);
+OPENSSL_EXPORT int 		X509_set_subject_name(X509 *x, X509_NAME *name);
+OPENSSL_EXPORT X509_NAME *	X509_get_subject_name(X509 *a);
+OPENSSL_EXPORT int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+OPENSSL_EXPORT int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
+OPENSSL_EXPORT int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *	X509_get_pubkey(X509 *x);
+OPENSSL_EXPORT ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
+OPENSSL_EXPORT int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
 
-int		X509_REQ_set_version(X509_REQ *x,long version);
-int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
-int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
-EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
-int		X509_REQ_extension_nid(int nid);
-int *		X509_REQ_get_extension_nids(void);
-void		X509_REQ_set_extension_nids(int *nids);
-STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
-int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+OPENSSL_EXPORT int		X509_REQ_set_version(X509_REQ *x,long version);
+OPENSSL_EXPORT int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
+OPENSSL_EXPORT int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+OPENSSL_EXPORT EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
+OPENSSL_EXPORT int		X509_REQ_extension_nid(int nid);
+OPENSSL_EXPORT int *		X509_REQ_get_extension_nids(void);
+OPENSSL_EXPORT void		X509_REQ_set_extension_nids(int *nids);
+OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+OPENSSL_EXPORT int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
 				int nid);
-int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
-int X509_REQ_get_attr_count(const X509_REQ *req);
-int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+OPENSSL_EXPORT int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req);
+OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
 			  int lastpos);
-int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
 			  int lastpos);
-X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
-X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
-int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
-int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
 			const ASN1_OBJECT *obj, int type,
 			const unsigned char *bytes, int len);
-int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req,
 			int nid, int type,
 			const unsigned char *bytes, int len);
-int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req,
 			const char *attrname, int type,
 			const unsigned char *bytes, int len);
 
-int X509_CRL_set_version(X509_CRL *x, long version);
-int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
-int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
-int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
-int X509_CRL_sort(X509_CRL *crl);
+OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *x, long version);
+OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+OPENSSL_EXPORT int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+OPENSSL_EXPORT int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl);
 
-int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
-int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
 
-X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
 			EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);
 
-int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
+OPENSSL_EXPORT int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
 
-int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
-int 		X509_chain_check_suiteb(int *perror_depth,
+OPENSSL_EXPORT int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
+OPENSSL_EXPORT int 		X509_chain_check_suiteb(int *perror_depth,
 						X509 *x, STACK_OF(X509) *chain,
 						unsigned long flags);
-int 		X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk,
+OPENSSL_EXPORT int 		X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk,
 						unsigned long flags);
-STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
+OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
 
-int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
-unsigned long	X509_issuer_and_serial_hash(X509 *a);
+OPENSSL_EXPORT int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+OPENSSL_EXPORT unsigned long	X509_issuer_and_serial_hash(X509 *a);
 
-int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
-unsigned long	X509_issuer_name_hash(X509 *a);
+OPENSSL_EXPORT int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
+OPENSSL_EXPORT unsigned long	X509_issuer_name_hash(X509 *a);
 
-int		X509_subject_name_cmp(const X509 *a, const X509 *b);
-unsigned long	X509_subject_name_hash(X509 *x);
+OPENSSL_EXPORT int		X509_subject_name_cmp(const X509 *a, const X509 *b);
+OPENSSL_EXPORT unsigned long	X509_subject_name_hash(X509 *x);
 
 #ifndef OPENSSL_NO_MD5
-unsigned long	X509_issuer_name_hash_old(X509 *a);
-unsigned long	X509_subject_name_hash_old(X509 *x);
+OPENSSL_EXPORT unsigned long	X509_issuer_name_hash_old(X509 *a);
+OPENSSL_EXPORT unsigned long	X509_subject_name_hash_old(X509 *x);
 #endif
 
-int		X509_cmp(const X509 *a, const X509 *b);
-int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
-unsigned long	X509_NAME_hash(X509_NAME *x);
-unsigned long	X509_NAME_hash_old(X509_NAME *x);
+OPENSSL_EXPORT int		X509_cmp(const X509 *a, const X509 *b);
+OPENSSL_EXPORT int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+OPENSSL_EXPORT unsigned long	X509_NAME_hash(X509_NAME *x);
+OPENSSL_EXPORT unsigned long	X509_NAME_hash_old(X509_NAME *x);
 
-int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
-int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+OPENSSL_EXPORT int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+OPENSSL_EXPORT int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
 #ifndef OPENSSL_NO_FP_API
-int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
-int		X509_print_fp(FILE *bp,X509 *x);
-int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
-int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
-int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
+OPENSSL_EXPORT int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+OPENSSL_EXPORT int		X509_print_fp(FILE *bp,X509 *x);
+OPENSSL_EXPORT int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
+OPENSSL_EXPORT int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
+OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
 #endif
 
 #ifndef OPENSSL_NO_BIO
-int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
-int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
-int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
-int		X509_print(BIO *bp,X509 *x);
-int		X509_ocspid_print(BIO *bp,X509 *x);
-int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
-int		X509_CRL_print(BIO *bp,X509_CRL *x);
-int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
-int		X509_REQ_print(BIO *bp,X509_REQ *req);
+OPENSSL_EXPORT int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
+OPENSSL_EXPORT int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+OPENSSL_EXPORT int		X509_print(BIO *bp,X509 *x);
+OPENSSL_EXPORT int		X509_ocspid_print(BIO *bp,X509 *x);
+OPENSSL_EXPORT int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
+OPENSSL_EXPORT int		X509_CRL_print(BIO *bp,X509_CRL *x);
+OPENSSL_EXPORT int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
+OPENSSL_EXPORT int		X509_REQ_print(BIO *bp,X509_REQ *req);
 #endif
 
-int 		X509_NAME_entry_count(X509_NAME *name);
-int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
+OPENSSL_EXPORT int 		X509_NAME_entry_count(X509_NAME *name);
+OPENSSL_EXPORT int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
 			char *buf,int len);
-int		X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+OPENSSL_EXPORT int		X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
 			char *buf,int len);
 
 /* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
  * lastpos, search after that position on. */
-int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
-int 		X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+OPENSSL_EXPORT int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+OPENSSL_EXPORT int 		X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
 			int lastpos);
-X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
-X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
-int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+OPENSSL_EXPORT int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
 			int loc, int set);
-int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
 			unsigned char *bytes, int len, int loc, int set);
-int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
 			unsigned char *bytes, int len, int loc, int set);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
 		const char *field, int type, const unsigned char *bytes, int len);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
 			int type,unsigned char *bytes, int len);
-int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+OPENSSL_EXPORT int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
 			const unsigned char *bytes, int len, int loc, int set);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
 			const ASN1_OBJECT *obj, int type,const unsigned char *bytes,
 			int len);
-int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
+OPENSSL_EXPORT int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
 			const ASN1_OBJECT *obj);
-int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+OPENSSL_EXPORT int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
 			const unsigned char *bytes, int len);
-ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
-ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+OPENSSL_EXPORT ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+OPENSSL_EXPORT ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
 
-int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
-int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+OPENSSL_EXPORT int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+OPENSSL_EXPORT int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
 				      int nid, int lastpos);
-int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+OPENSSL_EXPORT int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
 				      const ASN1_OBJECT *obj,int lastpos);
-int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+OPENSSL_EXPORT int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
 					   int crit, int lastpos);
-X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
-X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
-STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
 					 X509_EXTENSION *ex, int loc);
 
-int		X509_get_ext_count(X509 *x);
-int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
-int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
-int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
-X509_EXTENSION *X509_get_ext(X509 *x, int loc);
-X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
-int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
-int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+OPENSSL_EXPORT int		X509_get_ext_count(X509 *x);
+OPENSSL_EXPORT int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+OPENSSL_EXPORT int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
+OPENSSL_EXPORT int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+OPENSSL_EXPORT int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+OPENSSL_EXPORT void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
 							unsigned long flags);
 
-int		X509_CRL_get_ext_count(X509_CRL *x);
-int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
-int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
-int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
-X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
-X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
-int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
-void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
-int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+OPENSSL_EXPORT int		X509_CRL_get_ext_count(X509_CRL *x);
+OPENSSL_EXPORT int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+OPENSSL_EXPORT int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
+OPENSSL_EXPORT int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+OPENSSL_EXPORT int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+OPENSSL_EXPORT void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
 							unsigned long flags);
 
-int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
-int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
-int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
-int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
-X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
-X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
-int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
-void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
-int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+OPENSSL_EXPORT int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
+OPENSSL_EXPORT int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+OPENSSL_EXPORT int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
+OPENSSL_EXPORT int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+OPENSSL_EXPORT int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+OPENSSL_EXPORT void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
 							unsigned long flags);
 
-X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
 			int nid, int crit, ASN1_OCTET_STRING *data);
-X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
 			const ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
-int		X509_EXTENSION_set_object(X509_EXTENSION *ex,const ASN1_OBJECT *obj);
-int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
-int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
+OPENSSL_EXPORT int		X509_EXTENSION_set_object(X509_EXTENSION *ex,const ASN1_OBJECT *obj);
+OPENSSL_EXPORT int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+OPENSSL_EXPORT int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
 			ASN1_OCTET_STRING *data);
-ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
-ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
-int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+OPENSSL_EXPORT ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
+OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+OPENSSL_EXPORT int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
 
-int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
-int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+OPENSSL_EXPORT int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+OPENSSL_EXPORT int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
 			  int lastpos);
-int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj,
+OPENSSL_EXPORT int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj,
 			  int lastpos);
-X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
-X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+OPENSSL_EXPORT X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+OPENSSL_EXPORT X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
 					 X509_ATTRIBUTE *attr);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
 			const ASN1_OBJECT *obj, int type,
 			const unsigned char *bytes, int len);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
 			int nid, int type,
 			const unsigned char *bytes, int len);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
 			const char *attrname, int type,
 			const unsigned char *bytes, int len);
-void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+OPENSSL_EXPORT void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
 				ASN1_OBJECT *obj, int lastpos, int type);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
 	     int atrtype, const void *data, int len);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
 	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
 		const char *atrname, int type, const unsigned char *bytes, int len);
-int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
-int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
-void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+OPENSSL_EXPORT int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+OPENSSL_EXPORT int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
+OPENSSL_EXPORT void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
 					int atrtype, void *data);
-int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
-ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
-ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+OPENSSL_EXPORT int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+OPENSSL_EXPORT ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
 
-int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
-int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+OPENSSL_EXPORT int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+OPENSSL_EXPORT int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
 			  int lastpos);
-int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+OPENSSL_EXPORT int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
 			  int lastpos);
-X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
-X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
-int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
-int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+OPENSSL_EXPORT X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+OPENSSL_EXPORT X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+OPENSSL_EXPORT int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+OPENSSL_EXPORT int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
 			const ASN1_OBJECT *obj, int type,
 			const unsigned char *bytes, int len);
-int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+OPENSSL_EXPORT int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
 			int nid, int type,
 			const unsigned char *bytes, int len);
-int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+OPENSSL_EXPORT int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
 			const char *attrname, int type,
 			const unsigned char *bytes, int len);
 
-int		X509_verify_cert(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT int		X509_verify_cert(X509_STORE_CTX *ctx);
 
 /* lookup a cert from a X509 STACK */
-X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
+OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
 				     ASN1_INTEGER *serial);
-X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
+OPENSSL_EXPORT X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(PBEPARAM)
 DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
 DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
 
-int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+OPENSSL_EXPORT int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
 				const unsigned char *salt, int saltlen);
 
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+OPENSSL_EXPORT X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
 				const unsigned char *salt, int saltlen);
-X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+OPENSSL_EXPORT X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
 					 unsigned char *salt, int saltlen);
-X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+OPENSSL_EXPORT X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
 				 unsigned char *salt, int saltlen,
 				 unsigned char *aiv, int prf_nid);
 
-X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+OPENSSL_EXPORT X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
 				int prf_nid, int keylen);
 
 /* PKCS#8 utilities */
 
 DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
 
-EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
-PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 
-int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+OPENSSL_EXPORT int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
 			int version, int ptype, void *pval,
 				unsigned char *penc, int penclen);
-int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+OPENSSL_EXPORT int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
 		const unsigned char **pk, int *ppklen,
 		X509_ALGOR **pa,
 		PKCS8_PRIV_KEY_INFO *p8);
 
-int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj,
+OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj,
 					int ptype, void *pval,
 					unsigned char *penc, int penclen);
-int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
 		const unsigned char **pk, int *ppklen,
 		X509_ALGOR **pa,
 		X509_PUBKEY *pub);
 
-int X509_check_trust(X509 *x, int id, int flags);
-int X509_TRUST_get_count(void);
-X509_TRUST * X509_TRUST_get0(int idx);
-int X509_TRUST_get_by_id(int id);
-int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags);
+OPENSSL_EXPORT int X509_TRUST_get_count(void);
+OPENSSL_EXPORT X509_TRUST * X509_TRUST_get0(int idx);
+OPENSSL_EXPORT int X509_TRUST_get_by_id(int id);
+OPENSSL_EXPORT int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
 					char *name, int arg1, void *arg2);
-void X509_TRUST_cleanup(void);
-int X509_TRUST_get_flags(X509_TRUST *xp);
-char *X509_TRUST_get0_name(X509_TRUST *xp);
-int X509_TRUST_get_trust(X509_TRUST *xp);
+OPENSSL_EXPORT void X509_TRUST_cleanup(void);
+OPENSSL_EXPORT int X509_TRUST_get_flags(X509_TRUST *xp);
+OPENSSL_EXPORT char *X509_TRUST_get0_name(X509_TRUST *xp);
+OPENSSL_EXPORT int X509_TRUST_get_trust(X509_TRUST *xp);
 
 /* PKCS7_get_certificates parses a PKCS#7, SignedData structure from |cbs| and
  * appends the included certificates to |out_certs|. It returns one on success
  * and zero on error. */
-int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs);
+OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs);
 
 
 /* EVP_PK values indicate the algorithm of the public key in a certificate. */
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 7675ed6..c65bfde 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -206,7 +206,7 @@
 	int references;
 	} /* X509_STORE */;
 
-int X509_STORE_set_depth(X509_STORE *store, int depth);
+OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth);
 
 #define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
 #define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
@@ -275,7 +275,7 @@
 	CRYPTO_EX_DATA ex_data;
 	} /* X509_STORE_CTX */;
 
-void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 
 #define X509_STORE_CTX_set_app_data(ctx,data) \
 	X509_STORE_CTX_set_ex_data(ctx,0,data)
@@ -424,180 +424,180 @@
 				| X509_V_FLAG_INHIBIT_ANY \
 				| X509_V_FLAG_INHIBIT_MAP)
 
-int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
 	     X509_NAME *name);
-X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
-X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
-void X509_OBJECT_up_ref_count(X509_OBJECT *a);
-void X509_OBJECT_free_contents(X509_OBJECT *a);
-X509_STORE *X509_STORE_new(void );
-void X509_STORE_free(X509_STORE *v);
+OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
+OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
+OPENSSL_EXPORT void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a);
+OPENSSL_EXPORT X509_STORE *X509_STORE_new(void );
+OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v);
 
-STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
-STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
-int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
-int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
-int X509_STORE_set_trust(X509_STORE *ctx, int trust);
-int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+OPENSSL_EXPORT STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+OPENSSL_EXPORT STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
 
-void X509_STORE_set_verify_cb(X509_STORE *ctx,
+OPENSSL_EXPORT void X509_STORE_set_verify_cb(X509_STORE *ctx,
 				  int (*verify_cb)(int, X509_STORE_CTX *));
 
-void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
+OPENSSL_EXPORT void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
 		STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm));
 
-X509_STORE_CTX *X509_STORE_CTX_new(void);
+OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void);
 
-int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
 
-void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
-int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
 			 X509 *x509, STACK_OF(X509) *chain);
-void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
-void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
 
-X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
 
-X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
 
-X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
-X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
 
-int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
-int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
 
-int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
+OPENSSL_EXPORT int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
 	X509_OBJECT *ret);
 
-int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
 	long argl, char **ret);
 
 #ifndef OPENSSL_NO_STDIO
-int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
-int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
-int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+OPENSSL_EXPORT int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
 #endif
 
 
-X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
-void X509_LOOKUP_free(X509_LOOKUP *ctx);
-int X509_LOOKUP_init(X509_LOOKUP *ctx);
-int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+OPENSSL_EXPORT X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx);
+OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx);
+OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
 	X509_OBJECT *ret);
-int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+OPENSSL_EXPORT int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
 	ASN1_INTEGER *serial, X509_OBJECT *ret);
-int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+OPENSSL_EXPORT int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
 	unsigned char *bytes, int len, X509_OBJECT *ret);
-int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
+OPENSSL_EXPORT int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
 	int len, X509_OBJECT *ret);
-int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
 
 #ifndef OPENSSL_NO_STDIO
-int	X509_STORE_load_locations (X509_STORE *ctx,
+OPENSSL_EXPORT int	X509_STORE_load_locations (X509_STORE *ctx,
 		const char *file, const char *dir);
-int	X509_STORE_set_default_paths(X509_STORE *ctx);
+OPENSSL_EXPORT int	X509_STORE_set_default_paths(X509_STORE *ctx);
 #endif
 
-int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
-void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
-int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
-void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
-int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
-X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
-X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
-X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
-X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
-STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
-STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
-void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
-void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
-void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
-int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
-int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
-int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+OPENSSL_EXPORT int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
+OPENSSL_EXPORT void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
+OPENSSL_EXPORT int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+OPENSSL_EXPORT int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
+OPENSSL_EXPORT void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+OPENSSL_EXPORT void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
+OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
 				int purpose, int trust);
-void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
-void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
 								time_t t);
-void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
 				  int (*verify_cb)(int, X509_STORE_CTX *));
   
-X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
-int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
 
-X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
-void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
-int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
 
 /* X509_VERIFY_PARAM functions */
 
-X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
-void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
 						const X509_VERIFY_PARAM *from);
-int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
 						const X509_VERIFY_PARAM *from);
-int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
-int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
-int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
 							unsigned long flags);
-unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
-int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
-void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
-void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
-int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
 						ASN1_OBJECT *policy);
-int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
 					STACK_OF(ASN1_OBJECT) *policies);
 
-int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
 				const unsigned char *name, size_t namelen);
-void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
 					unsigned int flags);
-int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
 				const unsigned char *email, size_t emaillen);
-int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
 					const unsigned char *ip, size_t iplen);
-int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);
 
-int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
-const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
 
-int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_get_count(void);
-const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
-const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
-void X509_VERIFY_PARAM_table_cleanup(void);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void);
+OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
+OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void);
 
-int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+OPENSSL_EXPORT int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
 			STACK_OF(X509) *certs,
 			STACK_OF(ASN1_OBJECT) *policy_oids,
 			unsigned int flags);
 
-void X509_policy_tree_free(X509_POLICY_TREE *tree);
+OPENSSL_EXPORT void X509_policy_tree_free(X509_POLICY_TREE *tree);
 
-int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
-X509_POLICY_LEVEL *
+OPENSSL_EXPORT int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+OPENSSL_EXPORT X509_POLICY_LEVEL *
 	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i);
 
-STACK_OF(X509_POLICY_NODE) *
+OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *
 	X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree);
 
-STACK_OF(X509_POLICY_NODE) *
+OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *
 	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree);
 
-int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+OPENSSL_EXPORT int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
 
-X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
+OPENSSL_EXPORT X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
 
-const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+OPENSSL_EXPORT const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
 
-STACK_OF(POLICYQUALINFO) *
+OPENSSL_EXPORT STACK_OF(POLICYQUALINFO) *
 	X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node);
-const X509_POLICY_NODE *
+OPENSSL_EXPORT const X509_POLICY_NODE *
 	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
 
 #ifdef  __cplusplus
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
index d74a444..99f7cf8 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -521,42 +521,42 @@
 DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
 
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
-GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
-int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+OPENSSL_EXPORT int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
 
 
 
-ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+OPENSSL_EXPORT ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
 				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
 				ASN1_BIT_STRING *bits,
 				STACK_OF(CONF_VALUE) *extlist);
 
-STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
-int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
+OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
 
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
 
-STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
 		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
-GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
 				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 
 DECLARE_ASN1_FUNCTIONS(OTHERNAME)
 DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
-int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
-void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
-void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
-int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+OPENSSL_EXPORT void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
 				ASN1_OBJECT *oid, ASN1_TYPE *value);
-int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
 				ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
 
-char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
-ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
+OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
 
-DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
-int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
+OPENSSL_EXPORT DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
 
 DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
 DECLARE_ASN1_FUNCTIONS(POLICYINFO)
@@ -569,9 +569,9 @@
 DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
 DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
 
-int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
 
-int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
+OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
 
 DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
 DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
@@ -589,111 +589,111 @@
 DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
 
-GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
 			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
 			       int gen_type, char *value, int is_nc);
 
-GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
 			       CONF_VALUE *cnf);
-GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
 				  const X509V3_EXT_METHOD *method,
 				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
-void X509V3_conf_free(CONF_VALUE *val);
+OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val);
 
-X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
-X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
-int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
-int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
-int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
-int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
+OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
+OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
 
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
 				    int ext_nid, char *value);
-X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
 				char *name, char *value);
-int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+OPENSSL_EXPORT int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
 			char *section, X509 *cert);
-int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+OPENSSL_EXPORT int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
 			    char *section, X509_REQ *req);
-int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+OPENSSL_EXPORT int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
 			    char *section, X509_CRL *crl);
 
-int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+OPENSSL_EXPORT int X509V3_add_value_bool_nf(char *name, int asn1_bool,
 			     STACK_OF(CONF_VALUE) **extlist);
-int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
-int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
-void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
-void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
+OPENSSL_EXPORT int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+OPENSSL_EXPORT int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+OPENSSL_EXPORT void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
 
-char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
-STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
-void X509V3_string_free(X509V3_CTX *ctx, char *str);
-void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
-void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+OPENSSL_EXPORT char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
+OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str);
+OPENSSL_EXPORT void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
 				 X509_REQ *req, X509_CRL *crl, int flags);
 
-int X509V3_add_value(const char *name, const char *value,
+OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value,
 						STACK_OF(CONF_VALUE) **extlist);
-int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, const unsigned char *value,
 						STACK_OF(CONF_VALUE) **extlist);
-int X509V3_add_value_bool(const char *name, int asn1_bool,
+OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool,
 						STACK_OF(CONF_VALUE) **extlist);
-int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+OPENSSL_EXPORT int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
 						STACK_OF(CONF_VALUE) **extlist);
-char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
-ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
-char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
-char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
-int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
-int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
-int X509V3_EXT_add_alias(int nid_to, int nid_from);
-void X509V3_EXT_cleanup(void);
+OPENSSL_EXPORT char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+OPENSSL_EXPORT ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+OPENSSL_EXPORT int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+OPENSSL_EXPORT int X509V3_EXT_add_alias(int nid_to, int nid_from);
+OPENSSL_EXPORT void X509V3_EXT_cleanup(void);
 
-const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
-const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
-int X509V3_add_standard_extensions(void);
-STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
-void *X509V3_EXT_d2i(X509_EXTENSION *ext);
-void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+OPENSSL_EXPORT int X509V3_add_standard_extensions(void);
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+OPENSSL_EXPORT void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+OPENSSL_EXPORT void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
 
 
-X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
-int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
 
 char *hex_to_string(const unsigned char *buffer, long len);
 unsigned char *string_to_hex(const char *str, long *len);
 int name_cmp(const char *name, const char *cmp);
 
-void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
 								 int ml);
-int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
-int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
+OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
 
-int X509V3_extensions_print(BIO *out, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
+OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
 
-int X509_check_ca(X509 *x);
-int X509_check_purpose(X509 *x, int id, int ca);
-int X509_supported_extension(X509_EXTENSION *ex);
-int X509_PURPOSE_set(int *p, int purpose);
-int X509_check_issued(X509 *issuer, X509 *subject);
-int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
-int X509_PURPOSE_get_count(void);
-X509_PURPOSE * X509_PURPOSE_get0(int idx);
-int X509_PURPOSE_get_by_sname(char *sname);
-int X509_PURPOSE_get_by_id(int id);
-int X509_PURPOSE_add(int id, int trust, int flags,
+OPENSSL_EXPORT int X509_check_ca(X509 *x);
+OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca);
+OPENSSL_EXPORT int X509_supported_extension(X509_EXTENSION *ex);
+OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose);
+OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject);
+OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
+OPENSSL_EXPORT int X509_PURPOSE_get_count(void);
+OPENSSL_EXPORT X509_PURPOSE * X509_PURPOSE_get0(int idx);
+OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(char *sname);
+OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id);
+OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags,
 			int (*ck)(const X509_PURPOSE *, const X509 *, int),
 				char *name, char *sname, void *arg);
-char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
-char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
-int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
-void X509_PURPOSE_cleanup(void);
-int X509_PURPOSE_get_id(X509_PURPOSE *);
+OPENSSL_EXPORT char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+OPENSSL_EXPORT int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+OPENSSL_EXPORT void X509_PURPOSE_cleanup(void);
+OPENSSL_EXPORT int X509_PURPOSE_get_id(X509_PURPOSE *);
 
-STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
-STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
-void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
-STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
 /* Flags for X509_check_* functions */
 
 /* Always check subject name for host match even if subject alt names present */
@@ -713,21 +713,21 @@
  */
 #define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
 
-int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen,
+OPENSSL_EXPORT int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen,
 					unsigned int flags);
-int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen,
+OPENSSL_EXPORT int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen,
 					unsigned int flags);
-int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
 					unsigned int flags);
-int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
+OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
 
-ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
-ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
-int a2i_ipadd(unsigned char *ipout, const char *ipasc);
-int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
+OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+OPENSSL_EXPORT int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
 						unsigned long chtype);
 
-void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
 DECLARE_STACK_OF(X509_POLICY_NODE)
 
 /* BEGIN ERROR CODES */
diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt
index 71102ff..3db8607 100644
--- a/ssl/CMakeLists.txt
+++ b/ssl/CMakeLists.txt
@@ -4,6 +4,7 @@
 
 add_library(
 	ssl
+	STATIC
 
 	d1_both.c
 	d1_clnt.c
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 7f63ce6..e2d0850 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -872,7 +872,6 @@
 SESS_CERT *ssl_sess_cert_new(void);
 void ssl_sess_cert_free(SESS_CERT *sc);
 int ssl_set_peer_cert_type(SESS_CERT *c, int type);
-int ssl_get_new_session(SSL *s, int session);
 int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx);
 int ssl_cipher_id_cmp(const void *in_a, const void *in_b);
 int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp);
@@ -883,7 +882,6 @@
 					     struct ssl_cipher_preference_list_st **pref,
 					     STACK_OF(SSL_CIPHER) **sorted,
 					     const char *rule_str, CERT *c);
-void ssl_update_cache(SSL *s, int mode);
 struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_dup(
 	struct ssl_cipher_preference_list_st *cipher_list);
 void ssl_cipher_preference_list_free(