Repository: randombit/botan
Pull request #3482 (2023-04-06 08:15:11)

Update of BSI policy for BSI guidelines 2023
I've checked Botan's BSI policy against the newest ['BSI – Technical Guideline' document](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf?__blob=publicationFile&v=6) to see if the current policy is still up to date. This PR contains some adaptions. Since I'm still quite new to Botan and are not familiar with all algorithms, I hope that you can verify and double check my changes. In the following I give the reasoning for all changes I've done:

1. Removed the XTS mode, since it does not appear in [Table 2.2 of the Guideline](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf?__blob=publicationFile&v=6#page=25).
2. Added the PQC signature scheme Dilithium (Kyber/XMSS were already added). The BSI states [the following](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf?__blob=publicationFile&v=6#page=39):
> The international standardisation of PQC mechanisms, in particular by the American National Institute of Standards and Technology (NIST), has meanwhile started and first mechanisms have been selected for standardisation. Corresponding standards are expected in the coming years. Introducing current, non-standardised mechanisms in new cryptographic systems is therefore always associated with the risk of creating systems that are incompatible with standards that are foreseeable for the near future. However, in applications that are intended to guarantee the confidentiality of information with a high value and a long-term need for protection, these problems weigh less heavily in the BSI’s view than the possibility of future attacks. In general, it is recommended to put great stress on cryptoagility in the design of new systems;

For me it sounds like PQC algorithms should be used with caution, but are basically allowed.
3. Added `argon2_avx2` for password based KDFs. I see no reason why not (argon2_ssse3 is already enabled).
4. The BSI states [the following](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf?__blob=publicationFile&v=6#page=72):
> If the use of a a cryptographic hardware token for password-based key derivation is not possible, the hash function Argon2id should be used. The security parameters of Argon2id and the requirements for the passwords depend on the application scenario and should be discussed with an expert.

For me it sounds like only Argon2 is recommended for PBKDFs. Therefore, i would forbid all other PBKDFs, i.e, ``pbkdf2``, `bcrypt_pbkdf`, `pgp_s2k`, and `scrypt`. Also the password hashes `passhash9` and `bcrypt`(already prohibited).
5. Added `getentropy` as entropy collection. I don't know much about there different entropy collection systems, but it seems that BSD's getentropy has high security claims. Also the BSI does not specify specific algorithms as far as I know.
6. Reenabled `hkdf`. I was told it is required for TLS 1.3.
7. Disabled the public key padding modules `eme_raw`. Should be sensible.
8. Disabled the hash module ``raw_hash``. At first glance I could not find other modules using `raw_hash`. Otherwise, it should definitely be disabled.


codecov-commenter: ## [Codecov](https://codecov.io/gh/randombit/botan/pull/3482?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) Report
Patch coverage has no change and project coverage change: **`-0.02`** :warning:
> Comparison is base [(`0a4ab5d`)](https://codecov.io/gh/randombit/botan/commit/0a4ab5d796e823cf7e7807757ec842b932869694?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) 88.24% compared to head [(`452bbaf`)](https://codecov.io/gh/randombit/botan/pull/3482?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) 88.22%.

:mega: This organization is not using Codecov’s [GitHub App Integration](https://github.com/apps/codecov). We recommend you install it so Codecov can continue to function properly for your repositories. [Learn more](https://about.codecov.io/blog/codecov-is-updating-its-github-integration/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd)

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3482      +/-   ##
==========================================
- Coverage   88.24%   88.22%   -0.02%     
==========================================
  Files         618      618              
  Lines       70379    70378       -1     
  Branches     6876     6874       -2     
==========================================
- Hits        62103    62094       -9     
- Misses       5422     5426       +4     
- Partials     2854     2858       +4     
```


[see 8 files with indirect coverage changes](https://codecov.io/gh/randombit/botan/pull/3482/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd)

</details>

[:umbrella: View full report in Codecov by Sentry](https://codecov.io/gh/randombit/botan/pull/3482?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd).

FAlbertDev: I've disabled the PQC algorithms kyber and dilithium for now, since they are not yet wanted in the current policy. Maybe these will be activated in the next iteration. (4fe8b03)
FAlbertDev: I would suggest that we leave the current changes for now. In the following weeks we are planning to agree with the BSI about the goals of the policy (including prohibition strategy, etc.). Afterward, we may need further adaptions. 
Until then, these changes should (at least) enable the TLS 1.3 modules in this policy.
randombit: Please rebase and squash before merge
coveralls: 
[![Coverage Status](https://coveralls.io/builds/59611077/badge)](https://coveralls.io/builds/59611077)

Coverage: 91.73% (+0.004%) from 91.726% when pulling **2686d91000b8a5602ed563fd68288230ad6b28a1 on FAlbertDev:bsi-policy-update** into **b37705fe12306c0973f03137f40d24b173c5a67a on randombit:master**.


Patch:
diff --git a/configure.py b/configure.py
index 2e7fece56..9143c329a 100755
--- a/configure.py
+++ b/configure.py
@@ -241,15 +241,6 @@ class BuildPaths: # pylint: disable=too-many-instance-attributes
         self.cli_headers = normalize_source_paths(find_headers_in(source_paths.src_dir, 'cli'))
         self.test_sources = normalize_source_paths(find_sources_in(source_paths.src_dir, 'tests'))
 
-        if 'examples' in options.build_targets:
-            self.example_sources = normalize_source_paths(find_sources_in(source_paths.src_dir, 'examples'))
-            self.example_output_dir = os.path.join(self.build_dir, 'examples')
-            self.example_obj_dir = os.path.join(self.build_dir, 'obj', 'examples')
-        else:
-            self.example_sources = None
-            self.example_output_dir = None
-            self.example_obj_dir = None
-
         if options.build_fuzzers:
             self.fuzzer_sources = list(find_sources_in(source_paths.src_dir, 'fuzzer'))
             self.fuzzer_output_dir = os.path.join(self.build_dir, 'fuzzer')
@@ -272,9 +263,8 @@ class BuildPaths: # pylint: disable=too-many-instance-attributes
         if self.doc_output_dir_doxygen:
             out += [self.doc_output_dir_doxygen, self.doc_module_info]
         if self.fuzzer_output_dir:
-            out += [self.fuzzobj_dir, self.fuzzer_output_dir]
-        if self.example_output_dir:
-            out += [self.example_obj_dir, self.example_output_dir]
+            out += [self.fuzzobj_dir]
+            out += [self.fuzzer_output_dir]
         return out
 
     def format_include_paths(self, cc, external_includes):
@@ -296,11 +286,9 @@ class BuildPaths: # pylint: disable=too-many-instance-attributes
             return (self.test_sources, self.testobj_dir)
         if typ == 'fuzzer':
             return (self.fuzzer_sources, self.fuzzobj_dir)
-        if typ == 'examples':
-            return (self.example_sources, self.example_obj_dir)
         raise InternalError("Unknown src info type '%s'" % (typ))
 
-ACCEPTABLE_BUILD_TARGETS = ["static", "shared", "cli", "tests", "bogo_shim", "examples"]
+ACCEPTABLE_BUILD_TARGETS = ["static", "shared", "cli", "tests", "bogo_shim"]
 
 def process_command_line(args): # pylint: disable=too-many-locals,too-many-statements
     """
@@ -1206,7 +1194,6 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
                 'binary_name': None,
                 'linker_name': None,
                 'macro_name': None,
-                'minimum_supported_version': None,
                 'output_to_object': '-o ',
                 'output_to_exe': '-o ',
                 'add_include_dir_option': '-I',
@@ -1235,7 +1222,6 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
                 'ar_options': '',
                 'ar_output_to': '',
                 'werror_flags': '',
-                'supports_gcc_inline_asm': 'no',
             })
 
         self.add_framework_option = lex.add_framework_option
@@ -1274,12 +1260,10 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
         self.size_optimization_flags = lex.size_optimization_flags
         self.so_link_commands = lex.so_link_commands
         self.stack_protector_flags = lex.stack_protector_flags
-        self.supports_gcc_inline_asm = lex.supports_gcc_inline_asm == 'yes'
         self.visibility_attribute = lex.visibility_attribute
         self.visibility_build_flags = lex.visibility_build_flags
         self.warning_flags = lex.warning_flags
         self.werror_flags = lex.werror_flags
-        self.minimum_supported_version = lex.minimum_supported_version
 
     def cross_check(self, os_info, arch_info, all_isas):
 
@@ -1896,13 +1880,9 @@ def generate_build_info(build_paths, modules, cc, arch, osinfo, options):
                 'isa_flags': _isa_specific_flags(src)
                 }
 
-            if target_type in ['fuzzer', 'examples']:
-                exe_basename = os.path.basename(obj_file).replace('.' + osinfo.obj_suffix, '')
-
-                if target_type == 'fuzzer':
-                    info['exe'] = os.path.join(build_paths.fuzzer_output_dir, exe_basename)
-                else:
-                    info['exe'] = os.path.join(build_paths.example_output_dir, exe_basename)
+            if target_type == 'fuzzer':
+                fuzz_basename = os.path.basename(obj_file).replace('.' + osinfo.obj_suffix, '')
+                info['exe'] = os.path.join(build_paths.fuzzer_output_dir, fuzz_basename)
 
             output.append(info)
 
@@ -1910,13 +1890,11 @@ def generate_build_info(build_paths, modules, cc, arch, osinfo, options):
 
     out = {}
 
-    targets = ['lib', 'cli', 'test', 'fuzzer', 'examples']
+    targets = ['lib', 'cli', 'test', 'fuzzer']
 
     out['isa_build_info'] = []
 
     fuzzer_bin = []
-    example_bin = []
-
     for t in targets:
         src_list, src_dir = build_paths.src_info(t)
 
@@ -1938,15 +1916,12 @@ def generate_build_info(build_paths, modules, cc, arch, osinfo, options):
 
             if t == 'fuzzer':
                 fuzzer_bin = [b['exe'] for b in build_info]
-            elif t == 'examples':
-                example_bin = [b['exe'] for b in build_info]
 
         out[src_key] = src_list if src_list else []
         out[obj_key] = objects
         out[build_key] = build_info
 
     out['fuzzer_bin'] = ' '.join(fuzzer_bin)
-    out['example_bin'] = ' '.join(example_bin)
     out['cli_headers'] = build_paths.cli_headers
 
     return out
@@ -2040,8 +2015,6 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
             yield 'fuzzers'
         if 'bogo_shim' in options.build_targets:
             yield 'bogo_shim'
-        if 'examples' in options.build_targets:
-            yield 'examples'
 
     def install_targets(options):
         yield 'libs'
@@ -2155,7 +2128,6 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
         'build_shared_lib': options.build_shared_lib,
 
         'build_fuzzers': options.build_fuzzers,
-        'build_examples': 'examples' in options.build_targets,
 
         'build_coverage' : options.with_coverage_info or options.with_coverage,
 
@@ -2191,8 +2163,6 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
         'linker': cc.linker_name or choose_cxx_exe(),
         'make_supports_phony': osinfo.basename != 'windows',
 
-        'cxx_supports_gcc_inline_asm': cc.supports_gcc_inline_asm,
-
         'sanitizer_types' : sorted(cc.sanitizer_types),
 
         'cc_compile_opt_flags': cc.cc_compile_flags(options, False, True),
@@ -3216,10 +3186,8 @@ def calculate_cc_min_version(options, ccinfo, source_paths):
 
     unknown_pattern = r'UNKNOWN 0 0'
 
-    cxx = ccinfo.basename
-
-    if cxx not in version_patterns:
-        logging.info("No compiler version detection available for %s", cxx)
+    if ccinfo.basename not in version_patterns:
+        logging.info("No compiler version detection available for %s", ccinfo.basename)
         return "0.0"
 
     detect_version_source = os.path.join(source_paths.build_data_dir, "detect_version.cpp")
@@ -3227,28 +3195,19 @@ def calculate_cc_min_version(options, ccinfo, source_paths):
     cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, "0.0")
 
     if re.search(unknown_pattern, cc_output) is not None:
-        logging.warning('Failed to get version for %s from macro check', cxx)
+        logging.warning('Failed to get version for %s from macro check', ccinfo.basename)
         return "0.0"
 
-    match = re.search(version_patterns[cxx], cc_output, flags=re.MULTILINE)
+    match = re.search(version_patterns[ccinfo.basename], cc_output, flags=re.MULTILINE)
     if match is None:
         logging.warning("Tried to get %s version, but output '%s' is unexpected",
-                        cxx, cc_output)
+                        ccinfo.basename, cc_output)
         return "0.0"
 
     major_version = int(match.group(1), 0)
     minor_version = int(match.group(2), 0)
     cc_version = "%d.%d" % (major_version, minor_version)
-    logging.info('Auto-detected compiler version %s %s', cxx, cc_version)
-
-    if ccinfo.minimum_supported_version:
-        # compare as floats
-        min_ver = float(ccinfo.minimum_supported_version)
-        our_ver = float(cc_version)
-
-        if our_ver < min_ver:
-            logging.error("This version of Botan requires at least %s %s",
-                          cxx, ccinfo.minimum_supported_version)
+    logging.info('Auto-detected compiler version %s', cc_version)
 
     return cc_version
 
diff --git a/doc/api_ref/env_vars.rst b/doc/api_ref/env_vars.rst
index 50d3d52d1..e00ff6e84 100644
--- a/doc/api_ref/env_vars.rst
+++ b/doc/api_ref/env_vars.rst
@@ -23,8 +23,3 @@ library. The variables and their behavior are described here.
   will print the text message of the exception to stderr. This is primarily
   intended for debugging.
 
-* ``BOTAN_CLEAR_CPUID``: this variable can be set to a comma-separated list of
-  CPUID fields to ignore. For example setting ``BOTAN_CLEAR_CPUID=avx2,avx512``
-  will cause AVX2 and AVX-512 codepaths to be avoided. Note that disabling basic
-  features (notably NEON or SSE2/SSSE3) can cause other higher level features
-  like AES-NI to also become disabled.
diff --git a/doc/api_ref/pubkey.rst b/doc/api_ref/pubkey.rst
index 6e11d0f3a..b7975c8b2 100644
--- a/doc/api_ref/pubkey.rst
+++ b/doc/api_ref/pubkey.rst
@@ -556,13 +556,12 @@ Botan implements the following encryption algorithms and padding schemes:
 
 Code Example
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
 The following Code sample reads a PKCS #8 keypair from the passed location and
 subsequently encrypts a fixed plaintext with the included public key, using OAEP
 with SHA-256. For the sake of completeness, the ciphertext is then decrypted using
 the private key.
 
-.. literalinclude:: /../src/examples/rsa_encrypt.cpp
+.. literalinclude:: /../src/examples/encrypt_with_pkcs8_key.cpp
    :language: cpp
 
 
diff --git a/doc/building.rst b/doc/building.rst
index ac9537685..ccdb23a1b 100644
--- a/doc/building.rst
+++ b/doc/building.rst
@@ -527,7 +527,7 @@ Building the Python wrappers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The Python wrappers for Botan use ctypes and the C89 API so no special
-build step is required, just import botan3.py
+build step is required, just import botan2.py
 
 See :doc:`Python Bindings <api_ref/python>` for more information about
 the Python bindings.
@@ -889,7 +889,7 @@ Skip installing Python module.
 ``--with-python-versions=N.M``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Where to install botan3.py. By default this is chosen to be the
+Where to install botan2.py. By default this is chosen to be the
 version of Python that is running ``configure.py``.
 
 ``--with-valgrind``
diff --git a/doc/dev_ref/contributing.rst b/doc/dev_ref/contributing.rst
index 601754511..25344caef 100644
--- a/doc/dev_ref/contributing.rst
+++ b/doc/dev_ref/contributing.rst
@@ -19,7 +19,7 @@ Under ``src`` there are directories
 * ``scripts`` contains misc scripts: install, distribution, various
   codegen things. Scripts controlling CI go under ``scripts/ci``.
 * ``configs`` contains configuration files for emacs, astyle, pylint, etc
-* ``python/botan3.py`` is the Python ctypes wrapper
+* ``python/botan2.py`` is the Python ctypes wrapper
 
 Under ``doc`` one finds the sources of this documentation
 
@@ -98,7 +98,7 @@ FFI Additions
 ----------------
 
 If adding a new function declaration to ``ffi.h``, the same PR must
-also add the same declaration in the Python binding ``botan3.py``, in
+also add the same declaration in the Python binding ``botan2.py``, in
 addition the new API functionality must be exposed to Python and a
 test written in Python.
 
@@ -129,7 +129,7 @@ for 3.x, and not requiring huge blocks of version dependent code). As running
 this program successfully is required for a working build, making it as portable
 as possible is considered key.
 
-The python wrapper botan3.py targets CPython 3.x, and latest PyPy. Note that
+The python wrapper botan2.py targets CPython 3.x, and latest PyPy. Note that
 a single file is used to avoid dealing with any of Python's various crazy module
 distribution issues.
 
diff --git a/src/bogo_shim/bogo_shim.cpp b/src/bogo_shim/bogo_shim.cpp
index 467893396..53f04c314 100644
--- a/src/bogo_shim/bogo_shim.cpp
+++ b/src/bogo_shim/bogo_shim.cpp
@@ -1270,21 +1270,6 @@ class Shim_Credentials final : public Botan::Credentials_Manager
             }
          }
 
-      std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(const std::string& type,
-                                                                             const std::string& context) override
-         {
-         if(m_args.flag_set("server") && type != "tls-server")
-            { throw Shim_Exception("TLS server implementation asked for unexpected trusted CA type: " + type); }
-         if(!m_args.flag_set("server") && type != "tls-client")
-            { throw Shim_Exception("TLS client implementation asked for unexpected trusted CA type: " + type); }
-
-         const auto expected_hostname = m_args.get_string_opt_or_else("host-name", "none");
-         if(expected_hostname != "none" && expected_hostname != context)
-            { throw Shim_Exception("Unexpected host name in trusted CA request: " + context); }
-
-         return Botan::Credentials_Manager::trusted_certificate_authorities(type, context);
-         }
-
       std::string psk_identity(const std::string& /*type*/,
                                const std::string& /*context*/,
                                const std::string& /*identity_hint*/) override
diff --git a/src/build-data/arch/x86_64.txt b/src/build-data/arch/x86_64.txt
index cd4654255..729363e6f 100644
--- a/src/build-data/arch/x86_64.txt
+++ b/src/build-data/arch/x86_64.txt
@@ -22,5 +22,4 @@ sse2
 sse41
 sse42
 ssse3
-avx512
 </isa_extensions>
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index 67a6293b6..6abcb43a7 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -89,10 +89,6 @@
 
 #define BOTAN_BUILD_COMPILER_IS_%{cc_macro}
 
-%{if cxx_supports_gcc_inline_asm}
-#define BOTAN_USE_GCC_INLINE_ASM
-%{endif}
-
 %{for sanitizer_types}
 #define BOTAN_HAS_SANITIZER_%{i|upper}
 %{endfor}
@@ -236,4 +232,6 @@
     #error "Trying to compile Botan configured as x86_32 with non-x86_32 compiler."
 #endif
 
+#include <botan/compiler.h>
+
 #endif
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt
index 7b4bc3b0b..48397542d 100644
--- a/src/build-data/cc/clang.txt
+++ b/src/build-data/cc/clang.txt
@@ -2,8 +2,6 @@ macro_name CLANG
 
 binary_name clang++
 
-minimum_supported_version 14.0
-
 lang_flags "-std=c++20 -D_REENTRANT"
 
 warning_flags "-Wall -Wextra -Wpedantic -Wshadow -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wshorten-64-to-32 -Wcomma -Wdocumentation"
@@ -12,8 +10,6 @@ werror_flags "-Werror -Wno-error=unused-parameter -Wno-error=unreachable-code -W
 
 maintainer_warning_flags "-Wunreachable-code -Qunused-arguments"
 
-supports_gcc_inline_asm yes
-
 optimization_flags "-O3"
 sanitizer_optimization_flags "-O1 -fno-optimize-sibling-calls -fno-omit-frame-pointer"
 size_optimization_flags "-Os"
@@ -58,8 +54,6 @@ ssse3  -> "-mssse3"
 sse41  -> "-msse4.1"
 sse42  -> "-msse4.2"
 avx2   -> "-mavx2"
-avx512  -> "-mavx512f -mavx512bw -mavx512dq -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vl -mavx512ifma"
-
 bmi2   -> "-mbmi -mbmi2"
 aesni  -> "-maes -mpclmul"
 rdrand -> "-mrdrnd"
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index edf2e5fb6..5fc48b0de 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -2,21 +2,16 @@ macro_name GCC
 
 binary_name g++
 
-minimum_supported_version 11.0
-
 lang_flags "-std=c++20 -D_REENTRANT"
 
 # This should only contain flags which are included in GCC 11
 warning_flags "-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wzero-as-null-pointer-constant -Wnon-virtual-dtor -Wold-style-cast -Wsuggest-override -Wshadow -Wextra-semi"
 
 # Boost headers have 0 as nullptr and non-virtual-dtor issues so we can't werror on them
-# Have to disable maybe-uninitialized due to GCC bugs like https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105937
-werror_flags "-Werror -Wno-error=strict-overflow -Wno-error=zero-as-null-pointer-constant -Wno-error=non-virtual-dtor -Wno-error=maybe-uninitialized"
+werror_flags "-Werror -Wno-error=strict-overflow -Wno-error=zero-as-null-pointer-constant -Wno-error=non-virtual-dtor"
 
 maintainer_warning_flags "-Wstrict-overflow=5"
 
-supports_gcc_inline_asm yes
-
 optimization_flags "-O3"
 sanitizer_optimization_flags "-O1 -fno-optimize-sibling-calls -fno-omit-frame-pointer"
 size_optimization_flags "-Os"
@@ -61,8 +56,6 @@ ssse3   -> "-mssse3"
 sse41   -> "-msse4.1"
 sse42   -> "-msse4.2"
 avx2    -> "-mavx2"
-avx512  -> "-mavx512f -mavx512bw -mavx512dq -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vl -mavx512ifma"
-
 bmi2    -> "-mbmi -mbmi2"
 aesni   -> "-maes -mpclmul"
 rdrand  -> "-mrdrnd"
diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt
index d844af368..eb791ddbe 100644
--- a/src/build-data/cc/icc.txt
+++ b/src/build-data/cc/icc.txt
@@ -9,8 +9,6 @@ lang_flags "-std=c++20"
 warning_flags "-w1"
 shared_flags "-fPIC"
 
-supports_gcc_inline_asm yes
-
 <isa_flags>
 sse2    -> "-msse2"
 ssse3   -> "-mssse3"
diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt
index b4c2f25dd..d65177d37 100644
--- a/src/build-data/cc/msvc.txt
+++ b/src/build-data/cc/msvc.txt
@@ -1,7 +1,5 @@
 macro_name MSVC
 
-minimum_supported_version 19.30
-
 binary_name cl
 linker_name link
 
@@ -56,7 +54,6 @@ ssse3  -> ""
 sse41 -> ""
 sse42 -> ""
 x86_64:avx2   -> "/arch:AVX"
-x86_64:avx512 -> "/arch:AVX512"
 bmi2   -> ""
 aesni  -> ""
 clmul  -> ""
diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt
index 7bae84f6e..85ce9b346 100644
--- a/src/build-data/cc/sunstudio.txt
+++ b/src/build-data/cc/sunstudio.txt
@@ -11,8 +11,6 @@ lang_flags "-std=c++20 +p -features=extensions"
 ar_command CC
 ar_options "-xar -o"
 
-supports_gcc_inline_asm yes
-
 <so_link_commands>
 default -> "{cxx} -G -h{soname_abi}"
 </so_link_commands>
diff --git a/src/build-data/cc/xlc.txt b/src/build-data/cc/xlc.txt
index 1b796c695..c43d3bd37 100644
--- a/src/build-data/cc/xlc.txt
+++ b/src/build-data/cc/xlc.txt
@@ -9,8 +9,6 @@ lang_flags "-std=c++20"
 visibility_build_flags "-fvisibility=hidden"
 visibility_attribute '__attribute__((visibility("default")))'
 
-supports_gcc_inline_asm yes
-
 <isa_flags>
 altivec -> "-qaltivec"
 </isa_flags>
diff --git a/src/build-data/detect_version.cpp b/src/build-data/detect_version.cpp
index 7553be007..2279318e6 100644
--- a/src/build-data/detect_version.cpp
+++ b/src/build-data/detect_version.cpp
@@ -35,28 +35,24 @@
 
    Wikipedia has a mapping table from Apple Clang version to underlying
    LLVM version: https://en.wikipedia.org/wiki/Xcode
-
-   We omit any mapping logic for versions before XCode 13 since we no longer
-   support those versions. The only reason to detect them is so we can tell that
-   the version of Clang is too old and stop configuration immediately.
    */
 
-   #if __clang_major__ < 13
-      CLANG __clang_major__ 0
+   #if __clang_major__ == 11 && __clang_minor__ >= 4
+     CLANG 9 0
+   #elif __clang_major__ == 12
+      #if __clang_minor__ < 5
+         CLANG 10 0
+      #else
+         CLANG 11 0
+      #endif
    #elif __clang_major__ == 13
       #if __clang_minor__ < 3
          CLANG 12 0
       #else
          CLANG 13 0
       #endif
-   #elif __clang_major__ == 14
-      #if __clang_minor__ < 3
-         CLANG 14 0
-      #else
-         CLANG 15 0
-      #endif
-   #elif __clang_major__ >= 15
-      CLANG 15 0
+   #elif __clang_major__ >= 14
+     CLANG 14 0
    #endif
 
 #elif defined(__clang__)
diff --git a/src/build-data/makefile.in b/src/build-data/makefile.in
index 21c1a96a2..27fe3164a 100644
--- a/src/build-data/makefile.in
+++ b/src/build-data/makefile.in
@@ -95,14 +95,6 @@ fuzzer_corpus_zip: fuzzer_corpus
 
 %{endif}
 
-%{if build_examples}
-
-EXAMPLES = %{example_bin}
-
-examples: $(LIBRARIES) $(EXAMPLES)
-
-%{endif}
-
 %{if build_bogo_shim}
 
 bogo_shim: %{out_dir}/botan_bogo_shim
@@ -156,11 +148,3 @@ bogo_shim: %{out_dir}/botan_bogo_shim
 %{exe}: %{obj} $(LIBRARIES)
 	$(EXE_LINK_CMD) $(ABI_FLAGS) %{obj} $(BUILD_DIR_LINK_PATH) $(LANG_EXE_FLAGS) $(LDFLAGS) $(EXE_LINKS_TO) %{fuzzer_lib} %{output_to_exe}$@
 %{endfor}
-
-%{for examples_build_info}
-%{obj}: %{src}
-	$(CXX) $(BUILD_FLAGS) %{isa_flags} %{include_paths} %{dash_c} %{src} %{dash_o}$@
-
-%{exe}: %{obj} $(LIBRARIES)
-	$(EXE_LINK_CMD) $(ABI_FLAGS) %{obj} $(BUILD_DIR_LINK_PATH) $(LANG_EXE_FLAGS) $(LDFLAGS) $(EXE_LINKS_TO) %{fuzzer_lib} %{output_to_exe}$@
-%{endfor}
diff --git a/src/build-data/policy/bsi.txt b/src/build-data/policy/bsi.txt
index 0034a1c27..745d57f81 100644
--- a/src/build-data/policy/bsi.txt
+++ b/src/build-data/policy/bsi.txt
@@ -38,6 +38,8 @@ iso9796
 # pubkey
 dlies
 dh
+#dilithium // not (yet) recommended
+#dilithium_aes // not (yet) recommended
 rsa
 dsa
 ecdsa
@@ -45,8 +47,8 @@ ecgdsa
 ecies
 eckcdsa
 ecdh
-kyber
-kyber_90s
+#kyber // not (yet) recommended
+#kyber_90s // not (yet) recommended
 xmss
 
 # rng
@@ -73,10 +75,12 @@ sha2_64_bmi2
 sha3_bmi2
 
 # entropy sources
+getentropy
 rdseed
 win32_stats
 
 # pbkdf
+argon2_avx2
 argon2_ssse3
 
 # rng
@@ -134,7 +138,7 @@ salsa20
 #shake_cipher # not recommended, but needed for kyber
 
 # kdf
-hkdf
+#hkdf // needed for tls 1.3
 kdf1
 kdf2
 prf_x942
@@ -153,6 +157,7 @@ sm2
 # pk_pad
 #eme_pkcs1 // needed for tls
 #emsa_pkcs1 // needed for tls
+#eme_raw // allows custom paddings
 emsa_raw
 emsa_x931
 
diff --git a/src/cli/cli.h b/src/cli/cli.h
index 4caee5ec1..55b03aee8 100644
--- a/src/cli/cli.h
+++ b/src/cli/cli.h
@@ -7,7 +7,7 @@
 #ifndef BOTAN_CLI_H_
 #define BOTAN_CLI_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include <functional>
 #include <ostream>
 #include <optional>
diff --git a/src/cli/socket_utils.h b/src/cli/socket_utils.h
index 10291c3df..d52b5a0e7 100644
--- a/src/cli/socket_utils.h
+++ b/src/cli/socket_utils.h
@@ -8,7 +8,7 @@
 #ifndef BOTAN_CLI_SOCKET_UTILS_H_
 #define BOTAN_CLI_SOCKET_UTILS_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include "cli_exceptions.h"
 
 #if defined(BOTAN_TARGET_OS_HAS_WINSOCK2)
diff --git a/src/examples/Makefile b/src/examples/Makefile
new file mode 100644
index 000000000..195c1b15f
--- /dev/null
+++ b/src/examples/Makefile
@@ -0,0 +1,57 @@
+# Build examples using make
+# Target OS: Linux
+# Compiler: gcc
+# Target processor: x86_64
+
+# Paths to relevant programs
+CXX            = g++
+LINKER         = $(CXX)
+
+# Compiler Flags
+ABI_FLAGS      = -fstack-protector -m64 -pthread
+LANG_FLAGS     = -std=c++20 -D_REENTRANT
+LANG_EXE_FLAGS =
+CXXFLAGS       = -O3
+WARN_FLAGS     = -Wall -Wextra -Wpedantic -Wstrict-aliasing -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wzero-as-null-pointer-constant -Wnon-virtual-dtor -Wold-style-cast -Wsuggest-override -Wshadow -Wextra-semi -Werror -Wno-error=strict-overflow -Wno-error=zero-as-null-pointer-constant -Wno-error=non-virtual-dtor -Wno-unused-parameter
+LDFLAGS        =
+COMPILE_FLAGS    = -c
+OUTPUT_TO_OBJECT = -o
+OUTPUT_TO_EXE    = -o
+
+EXE_LINK_CMD   = $(LINKER)
+
+LIB_LINKS_TO        = -ldl -lrt
+BUILD_DIR_LINK_PATH =
+EXE_LINKS_TO        = -lbotan-3 $(LIB_LINKS_TO)
+
+BUILD_FLAGS    = $(ABI_FLAGS) $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
+
+INCLUDES =
+
+# OS specific suffic
+OBJ_SUFFIX = .o
+
+
+# The primary target
+all: examples
+
+# Misc targets
+
+build:
+	mkdir -p build
+
+clean:
+	rm -rf build
+
+# Executable targets
+
+PKCS11_EXAMPLES = pkcs11_low_level pkcs11_module pkcs11_slot pkcs11_session pkcs11_objects pkcs11_rsa pkcs11_ecdsa pkcs11_ecdh pkcs11_rng pkcs11_token_management pkcs11_x509
+
+EXAMPLES = aes aes_cbc chacha check_key cmac dl_group ecdh ecdsa encrypt_with_pkcs8_key gmac hash hmac kdf kyber pwdhash tls_client tls_custom_curves_client tls_proxy tls_stream_client xmss $(PKCS11_EXAMPLES)
+
+examples: $(addprefix build/, $(EXAMPLES))
+
+$(addprefix build/, $(addsuffix $(OBJ_SUFFIX),$(EXAMPLES))): build/%$(OBJ_SUFFIX): %.cpp | build
+	$(CXX) $(BUILD_FLAGS) $(INCLUDES) $(COMPILE_FLAGS) $< $(OUTPUT_TO_OBJECT)$@
+$(addprefix build/, $(EXAMPLES)): build/%: build/%$(OBJ_SUFFIX)
+	$(EXE_LINK_CMD) $(ABI_FLAGS) $< $(BUILD_DIR_LINK_PATH) $(LANG_EXE_FLAGS) $(LDFLAGS) $(EXE_LINKS_TO) $(OUTPUT_TO_EXE)$@
diff --git a/src/examples/rsa_encrypt.cpp b/src/examples/encrypt_with_pkcs8_key.cpp
similarity index 100%
rename from src/examples/rsa_encrypt.cpp
rename to src/examples/encrypt_with_pkcs8_key.cpp
diff --git a/src/examples/tls_client.cpp b/src/examples/tls_client.cpp
index 4fa449251..92e6af3cc 100644
--- a/src/examples/tls_client.cpp
+++ b/src/examples/tls_client.cpp
@@ -14,18 +14,15 @@ class Callbacks : public Botan::TLS::Callbacks {
 public:
   void tls_emit_data(std::span<const uint8_t> data) override {
     // send data to tls server, e.g., using BSD sockets or boost asio
-    BOTAN_UNUSED(data);
   }
 
   void tls_record_received(uint64_t seq_no, std::span<const uint8_t> data) override {
     // process full TLS record received by tls server, e.g.,
     // by passing it to the application
-    BOTAN_UNUSED(seq_no, data);
   }
 
   void tls_alert(Botan::TLS::Alert alert) override {
     // handle a tls alert received from the tls server
-    BOTAN_UNUSED(alert);
   }
 };
 
@@ -40,7 +37,6 @@ class Client_Credentials : public Botan::Credentials_Manager {
 public:
   std::vector<Botan::Certificate_Store *>
   trusted_certificate_authorities(const std::string &type, const std::string &context) override {
-    BOTAN_UNUSED(type, context);
     // return a list of certificates of CAs we trust for tls server certificates
     // ownership of the pointers remains with Credentials_Manager
     return {&m_cert_store};
@@ -50,8 +46,6 @@ public:
                                                   const std::vector<Botan::AlgorithmIdentifier> &cert_signature_schemes,
                                                   const std::string &type,
                                                   const std::string &context) override {
-    BOTAN_UNUSED(cert_key_types, cert_signature_schemes, type, context);
-
     // when using tls client authentication (optional), return
     // a certificate chain being sent to the tls server,
     // else an empty list
@@ -61,7 +55,6 @@ public:
   std::shared_ptr<Botan::Private_Key>
   private_key_for(const Botan::X509_Certificate &cert, const std::string &type,
                   const std::string &context) override {
-    BOTAN_UNUSED(cert, type, context);
     // when returning a chain in cert_chain(), return the private key
     // associated with the leaf certificate here
     return nullptr;
diff --git a/src/examples/tls_custom_curves_client.cpp b/src/examples/tls_custom_curves_client.cpp
index 3793b1cec..acbf1eb37 100644
--- a/src/examples/tls_custom_curves_client.cpp
+++ b/src/examples/tls_custom_curves_client.cpp
@@ -13,18 +13,15 @@
 class Callbacks : public Botan::TLS::Callbacks {
 public:
   void tls_emit_data(std::span<const uint8_t> data) override {
-    BOTAN_UNUSED(data);
     // send data to tls server, e.g., using BSD sockets or boost asio
   }
 
   void tls_record_received(uint64_t seq_no, std::span<const uint8_t> data) override {
-    BOTAN_UNUSED(seq_no, data);
     // process full TLS record received by tls server, e.g.,
     // by passing it to the application
   }
 
   void tls_alert(Botan::TLS::Alert alert) override {
-    BOTAN_UNUSED(alert);
     // handle a tls alert received from the tls server
   }
 
@@ -71,12 +68,29 @@ class Client_Credentials : public Botan::Credentials_Manager {
 public:
   std::vector<Botan::Certificate_Store *>
   trusted_certificate_authorities(const std::string &type, const std::string &context) override {
-    BOTAN_UNUSED(type, context);
     // return a list of certificates of CAs we trust for tls server certificates,
     // e.g., all the certificates in the local directory "cas"
     return {&m_cert_store};
   }
 
+  std::vector<Botan::X509_Certificate> cert_chain(const std::vector<std::string> &cert_key_types,
+                                                  const std::vector<Botan::AlgorithmIdentifier> &cert_signature_schemes,
+                                                  const std::string &type,
+                                                  const std::string &context) override {
+    // when using tls client authentication (optional), return
+    // a certificate chain being sent to the tls server,
+    // else an empty list
+    return {};
+  }
+
+  std::shared_ptr<Botan::Private_Key>
+  private_key_for(const Botan::X509_Certificate &cert, const std::string &type,
+                  const std::string &context) override {
+    // when returning a chain in cert_chain(), return the private key
+    // associated with the leaf certificate here
+    return nullptr;
+  }
+
 private:
   Botan::Certificate_Store_In_Memory m_cert_store{"cas"};
 };
diff --git a/src/examples/tls_proxy.cpp b/src/examples/tls_proxy.cpp
index a84d1606a..3854b9c0f 100644
--- a/src/examples/tls_proxy.cpp
+++ b/src/examples/tls_proxy.cpp
@@ -17,18 +17,15 @@ class Callbacks : public Botan::TLS::Callbacks {
 public:
   void tls_emit_data(std::span<const uint8_t> data) override {
     // send data to tls client, e.g., using BSD sockets or boost asio
-    BOTAN_UNUSED(data);
   }
 
   void tls_record_received(uint64_t seq_no, std::span<const uint8_t> data) override {
     // process full TLS record received by tls client, e.g.,
     // by passing it to the application
-    BOTAN_UNUSED(seq_no, data);
   }
 
   void tls_alert(Botan::TLS::Alert alert) override {
     // handle a tls alert received from the tls server
-    BOTAN_UNUSED(alert);
   }
 };
 
@@ -49,7 +46,6 @@ public:
 
   std::vector<Botan::Certificate_Store *>
   trusted_certificate_authorities(const std::string &type, const std::string &context) override {
-    BOTAN_UNUSED(type, context);
     // if client authentication is required, this function
     // shall return a list of certificates of CAs we trust
     // for tls client certificates, otherwise return an empty list
@@ -60,8 +56,6 @@ public:
                                                   const std::vector<Botan::AlgorithmIdentifier> &cert_signature_schemes,
                                                   const std::string &type,
                                                   const std::string &context) override {
-    BOTAN_UNUSED(cert_key_types, cert_signature_schemes, type, context);
-
     // return the certificate chain being sent to the tls client
     // e.g., the certificate file "botan.randombit.net.crt"
     return {Botan::X509_Certificate("botan.randombit.net.crt")};
@@ -70,7 +64,6 @@ public:
   std::shared_ptr<Botan::Private_Key>
   private_key_for(const Botan::X509_Certificate &cert, const std::string &type,
                   const std::string &context) override {
-    BOTAN_UNUSED(cert, type, context);
     // return the private key associated with the leaf certificate,
     // in this case the one associated with "botan.randombit.net.crt"
     return m_key;
diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp
index e70a1dd9a..1916f5578 100644
--- a/src/lib/block/serpent/serpent.cpp
+++ b/src/lib/block/serpent/serpent.cpp
@@ -11,7 +11,7 @@
 #include <botan/internal/rotate.h>
 #include <botan/internal/serpent_sbox.h>
 
-#if defined(BOTAN_HAS_SERPENT_SIMD) || defined(BOTAN_HAS_SERPENT_AVX2) || defined(BOTAN_HAS_SERPENT_AVX512)
+#if defined(BOTAN_HAS_SERPENT_SIMD) || defined(BOTAN_HAS_SERPENT_AVX2)
   #include <botan/internal/cpuid.h>
 #endif
 
@@ -26,19 +26,6 @@ void Serpent::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
 
    assert_key_material_set();
 
-#if defined(BOTAN_HAS_SERPENT_AVX512)
-   if(CPUID::has_avx512())
-      {
-      while(blocks >= 16)
-         {
-         avx512_encrypt_16(in, out);
-         in += 16 * BLOCK_SIZE;
-         out += 16 * BLOCK_SIZE;
-         blocks -= 16;
-         }
-      }
-#endif
-
 #if defined(BOTAN_HAS_SERPENT_AVX2)
    if(CPUID::has_avx2())
       {
@@ -118,19 +105,6 @@ void Serpent::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
 
    assert_key_material_set();
 
-#if defined(BOTAN_HAS_SERPENT_AVX512)
-   if(CPUID::has_avx512())
-      {
-      while(blocks >= 16)
-         {
-         avx512_decrypt_16(in, out);
-         in += 16 * BLOCK_SIZE;
-         out += 16 * BLOCK_SIZE;
-         blocks -= 16;
-         }
-      }
-#endif
-
 #if defined(BOTAN_HAS_SERPENT_AVX2)
    if(CPUID::has_avx2())
       {
@@ -278,13 +252,6 @@ void Serpent::clear()
 
 std::string Serpent::provider() const
    {
-#if defined(BOTAN_HAS_SERPENT_AVX512)
-   if(CPUID::has_avx512())
-      {
-      return "avx512";
-      }
-#endif
-
 #if defined(BOTAN_HAS_SERPENT_AVX2)
    if(CPUID::has_avx2())
       {
diff --git a/src/lib/block/serpent/serpent.h b/src/lib/block/serpent/serpent.h
index 805ffa0d5..66518bf3a 100644
--- a/src/lib/block/serpent/serpent.h
+++ b/src/lib/block/serpent/serpent.h
@@ -33,18 +33,13 @@ class Serpent final : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
    private:
 
 #if defined(BOTAN_HAS_SERPENT_SIMD)
-      void simd_encrypt_4(const uint8_t in[16*4], uint8_t out[16*4]) const;
-      void simd_decrypt_4(const uint8_t in[16*4], uint8_t out[16*4]) const;
+      void simd_encrypt_4(const uint8_t in[64], uint8_t out[64]) const;
+      void simd_decrypt_4(const uint8_t in[64], uint8_t out[64]) const;
 #endif
 
 #if defined(BOTAN_HAS_SERPENT_AVX2)
-      void avx2_encrypt_8(const uint8_t in[16*8], uint8_t out[16*8]) const;
-      void avx2_decrypt_8(const uint8_t in[16*8], uint8_t out[16*8]) const;
-#endif
-
-#if defined(BOTAN_HAS_SERPENT_AVX512)
-      void avx512_encrypt_16(const uint8_t in[16*16], uint8_t out[16*16]) const;
-      void avx512_decrypt_16(const uint8_t in[16*16], uint8_t out[16*16]) const;
+      void avx2_encrypt_8(const uint8_t in[128], uint8_t out[128]) const;
+      void avx2_decrypt_8(const uint8_t in[128], uint8_t out[128]) const;
 #endif
 
       void key_schedule(const uint8_t key[], size_t length) override;
diff --git a/src/lib/block/serpent/serpent_avx512/info.txt b/src/lib/block/serpent/serpent_avx512/info.txt
deleted file mode 100644
index ec7396d0d..000000000
--- a/src/lib/block/serpent/serpent_avx512/info.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-<defines>
-SERPENT_AVX512 -> 20230101
-</defines>
-
-<module_info>
-name -> "Serpent AVX512"
-brief -> "Serpent using AVX512 instructions"
-</module_info>
-
-<isa>
-avx512
-</isa>
-
-<requires>
-simd_avx512
-</requires>
diff --git a/src/lib/block/serpent/serpent_avx512/serpent_avx512.cpp b/src/lib/block/serpent/serpent_avx512/serpent_avx512.cpp
deleted file mode 100644
index 35f24e0e2..000000000
--- a/src/lib/block/serpent/serpent_avx512/serpent_avx512.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/serpent.h>
-#include <botan/internal/simd_avx512.h>
-#include <botan/internal/serpent_sbox.h>
-
-namespace Botan {
-
-BOTAN_AVX512_FN
-void Serpent::avx512_encrypt_16(const uint8_t in[16*16], uint8_t out[16*16]) const
-   {
-   using namespace Botan::Serpent_F;
-
-   SIMD_16x32 B0 = SIMD_16x32::load_le(in);
-   SIMD_16x32 B1 = SIMD_16x32::load_le(in + 64);
-   SIMD_16x32 B2 = SIMD_16x32::load_le(in + 128);
-   SIMD_16x32 B3 = SIMD_16x32::load_le(in + 192);
-
-   SIMD_16x32::transpose(B0, B1, B2, B3);
-
-   const Key_Inserter key_xor(m_round_key.data());
-
-   key_xor( 0,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 1,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 2,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 3,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 4,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 5,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 6,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 7,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-
-   key_xor( 8,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor( 9,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(10,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(11,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(12,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(13,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(14,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(15,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-
-   key_xor(16,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(17,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(18,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(19,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(20,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(21,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(22,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(23,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-
-   key_xor(24,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(25,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(26,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(27,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(28,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(29,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(30,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
-   key_xor(31,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
-
-   SIMD_16x32::transpose(B0, B1, B2, B3);
-   B0.store_le(out);
-   B1.store_le(out + 64);
-   B2.store_le(out + 128);
-   B3.store_le(out + 192);
-
-   SIMD_16x32::zero_registers();
-   }
-
-BOTAN_AVX512_FN
-void Serpent::avx512_decrypt_16(const uint8_t in[16*16], uint8_t out[16*16]) const
-   {
-   using namespace Botan::Serpent_F;
-
-   SIMD_16x32 B0 = SIMD_16x32::load_le(in);
-   SIMD_16x32 B1 = SIMD_16x32::load_le(in + 64);
-   SIMD_16x32 B2 = SIMD_16x32::load_le(in + 128);
-   SIMD_16x32 B3 = SIMD_16x32::load_le(in + 192);
-
-   SIMD_16x32::transpose(B0, B1, B2, B3);
-
-   const Key_Inserter key_xor(m_round_key.data());
-
-   key_xor(32,B0,B1,B2,B3);  SBoxD7(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
-
-   i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
-
-   i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
-
-   i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
-   i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
-
-   SIMD_16x32::transpose(B0, B1, B2, B3);
-
-   B0.store_le(out);
-   B1.store_le(out + 64);
-   B2.store_le(out + 128);
-   B3.store_le(out + 192);
-
-   SIMD_16x32::zero_registers();
-   }
-
-}
diff --git a/src/lib/block/serpent/serpent_sbox.h b/src/lib/block/serpent/serpent_sbox.h
index 0a5e37232..07208fb66 100644
--- a/src/lib/block/serpent/serpent_sbox.h
+++ b/src/lib/block/serpent/serpent_sbox.h
@@ -10,8 +10,7 @@
 #ifndef BOTAN_SERPENT_FUNCS_H_
 #define BOTAN_SERPENT_FUNCS_H_
 
-#include <botan/types.h>
-#include <botan/internal/rotate.h>
+#include <botan/build.h>
 
 namespace Botan::Serpent_F {
 
diff --git a/src/lib/codec/base58/base58.h b/src/lib/codec/base58/base58.h
index 4df8845d7..54fd0f1ee 100644
--- a/src/lib/codec/base58/base58.h
+++ b/src/lib/codec/base58/base58.h
@@ -7,7 +7,7 @@
 #ifndef BOTAN_BASE58_CODEC_H_
 #define BOTAN_BASE58_CODEC_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 #include <span>
 #include <string>
diff --git a/src/lib/codec/base64/base64.cpp b/src/lib/codec/base64/base64.cpp
index 407f490ad..10bd9a697 100644
--- a/src/lib/codec/base64/base64.cpp
+++ b/src/lib/codec/base64/base64.cpp
@@ -92,7 +92,7 @@ char lookup_base64_char(uint8_t x)
    {
    BOTAN_DEBUG_ASSERT(x < 64);
 
-   const auto in_AZ = CT::Mask<uint8_t>::is_lt(x, 26);
+   const auto in_az = CT::Mask<uint8_t>::is_within_range(x, 26, 51);
    const auto in_09 = CT::Mask<uint8_t>::is_within_range(x, 52, 61);
    const auto eq_plus = CT::Mask<uint8_t>::is_equal(x, 62);
    const auto eq_slash = CT::Mask<uint8_t>::is_equal(x, 63);
@@ -103,8 +103,8 @@ char lookup_base64_char(uint8_t x)
    const char c_plus = '+';
    const char c_slash = '/';
 
-   char ret = c_az;
-   ret = in_AZ.select(c_AZ, ret);
+   char ret = c_AZ;
+   ret = in_az.select(c_az, ret);
    ret = in_09.select(c_09, ret);
    ret = eq_plus.select(c_plus, ret);
    ret = eq_slash.select(c_slash, ret);
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index dab2319fd..8596ec6a6 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -60,25 +60,6 @@ API follows a few simple rules:
 #include <stdint.h>
 #include <stddef.h>
 
-/**
-* Notes the version that this FFI function was first added
-*/
-#define BOTAN_FFI_EXPORT(maj,min) BOTAN_DLL
-
-#if !defined(BOTAN_NO_DEPRECATED_WARNINGS)
-  #if defined(__has_attribute)
-    #if __has_attribute(deprecated)
-      #define BOTAN_FFI_DEPRECATED(msg) __attribute__((deprecated(msg)))
-    #endif
-  #elif defined(_MSC_VER)
-    #define BOTAN_FFI_DEPRECATED(msg) __declspec(deprecated(msg))
-  #endif
-#endif
-
-#if !defined(BOTAN_FFI_DEPRECATED)
-  #define BOTAN_FFI_DEPRECATED(msg) /**/
-#endif
-
 /**
 * Error codes
 *
@@ -141,7 +122,7 @@ typedef int (*botan_view_str_fn)(botan_view_ctx view_ctx, const char* str, size_
 * Convert an error code into a string. Returns "Unknown error"
 * if the error code is not a known one.
 */
-BOTAN_FFI_EXPORT(2,8) const char* botan_error_description(int err);
+BOTAN_PUBLIC_API(2,8) const char* botan_error_description(int err);
 
 /**
 * Return the message of the last exception caught in this thread.
@@ -150,63 +131,63 @@ BOTAN_FFI_EXPORT(2,8) const char* botan_error_description(int err);
 * this thread calls any other Botan FFI function and must be copied
 * to persistent storage first.
 */
-BOTAN_FFI_EXPORT(3,0) const char* botan_error_last_exception_message(void);
+BOTAN_PUBLIC_API(3,0) const char* botan_error_last_exception_message(void);
 
 /**
 * Return the version of the currently supported FFI API. This is
 * expressed in the form YYYYMMDD of the release date of this version
 * of the API.
 */
-BOTAN_FFI_EXPORT(2,0) uint32_t botan_ffi_api_version(void);
+BOTAN_PUBLIC_API(2,0) uint32_t botan_ffi_api_version(void);
 
 /**
 * Return 0 (ok) if the version given is one this library supports.
 * botan_ffi_supports_api(botan_ffi_api_version()) will always return 0.
 */
-BOTAN_FFI_EXPORT(2,0) int botan_ffi_supports_api(uint32_t api_version);
+BOTAN_PUBLIC_API(2,0) int botan_ffi_supports_api(uint32_t api_version);
 
 /**
 * Return a free-form version string, e.g., 2.0.0
 */
-BOTAN_FFI_EXPORT(2,0) const char* botan_version_string(void);
+BOTAN_PUBLIC_API(2,0) const char* botan_version_string(void);
 
 /**
 * Return the major version of the library
 */
-BOTAN_FFI_EXPORT(2,0) uint32_t botan_version_major(void);
+BOTAN_PUBLIC_API(2,0) uint32_t botan_version_major(void);
 
 /**
 * Return the minor version of the library
 */
-BOTAN_FFI_EXPORT(2,0) uint32_t botan_version_minor(void);
+BOTAN_PUBLIC_API(2,0) uint32_t botan_version_minor(void);
 
 /**
 * Return the patch version of the library
 */
-BOTAN_FFI_EXPORT(2,0) uint32_t botan_version_patch(void);
+BOTAN_PUBLIC_API(2,0) uint32_t botan_version_patch(void);
 
 /**
 * Return the date this version was released as
 * an integer, or 0 if an unreleased version
 */
-BOTAN_FFI_EXPORT(2,0) uint32_t botan_version_datestamp(void);
+BOTAN_PUBLIC_API(2,0) uint32_t botan_version_datestamp(void);
 
 /**
 * Returns 0 if x[0..len] == y[0..len], or otherwise -1
 */
-BOTAN_FFI_EXPORT(2,3) int botan_constant_time_compare(const uint8_t* x, const uint8_t* y, size_t len);
+BOTAN_PUBLIC_API(2,3) int botan_constant_time_compare(const uint8_t* x, const uint8_t* y, size_t len);
 
 /**
 * Deprecated equivalent to botan_constant_time_compare
 */
-BOTAN_FFI_DEPRECATED("Use botan_constant_time_compare")
-BOTAN_FFI_EXPORT(2,0) int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len);
+BOTAN_DEPRECATED("Use botan_constant_time_compare")
+BOTAN_PUBLIC_API(2,0) int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len);
 
 /**
 * Clear out memory using a system specific approach to bypass elision by the
 * compiler (currently using RtlSecureZeroMemory or tricks with volatile pointers).
 */
-BOTAN_FFI_EXPORT(2,2) int botan_scrub_mem(void* mem, size_t bytes);
+BOTAN_PUBLIC_API(2,2) int botan_scrub_mem(void* mem, size_t bytes);
 
 #define BOTAN_FFI_HEX_LOWER_CASE 1
 
@@ -218,7 +199,7 @@ BOTAN_FFI_EXPORT(2,2) int botan_scrub_mem(void* mem, size_t bytes);
 * @param flags flags out be upper or lower case?
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags);
 
 /**
 * Perform hex decoding
@@ -228,18 +209,18 @@ BOTAN_FFI_EXPORT(2,0) int botan_hex_encode(const uint8_t* x, size_t len, char* o
 * @param out_len the size of the output buffer on input, set to the number of bytes written
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,3) int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len);
+BOTAN_PUBLIC_API(2,3) int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len);
 
 /**
 * Perform base64 encoding
 */
-BOTAN_FFI_EXPORT(2,3) int botan_base64_encode(const uint8_t* x, size_t len, char* out, size_t* out_len);
+BOTAN_PUBLIC_API(2,3) int botan_base64_encode(const uint8_t* x, size_t len, char* out, size_t* out_len);
 
 
 /**
 * Perform base64 decoding
 */
-BOTAN_FFI_EXPORT(2,3) int botan_base64_decode(const char* base64_str, size_t in_len,
+BOTAN_PUBLIC_API(2,3) int botan_base64_decode(const char* base64_str, size_t in_len,
                                               uint8_t* out, size_t* out_len);
 
 /**
@@ -257,7 +238,7 @@ typedef struct botan_rng_struct* botan_rng_t;
 *    "rdrand": directly read RDRAND
 * Set rng_type to null to let the library choose some default.
 */
-BOTAN_FFI_EXPORT(2,0) int botan_rng_init(botan_rng_t* rng, const char* rng_type);
+BOTAN_PUBLIC_API(2,0) int botan_rng_init(botan_rng_t* rng, const char* rng_type);
 
 /**
 * Initialize a custom random number generator from a set of callback functions
@@ -268,7 +249,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_rng_init(botan_rng_t* rng, const char* rng_type)
 * @param add_entropy_cb Callback for adding entropy to the rng, return 0 for success, may be NULL
 * @param destroy_cb Callback called when rng is destroyed, may be NULL
 */
-BOTAN_FFI_EXPORT(3,0) int botan_rng_init_custom(botan_rng_t* rng_out, const char* rng_name, void* context,
+BOTAN_PUBLIC_API(3,0) int botan_rng_init_custom(botan_rng_t* rng_out, const char* rng_name, void* context,
                                                  int(* get_cb)(void* context, uint8_t* out, size_t out_len),
                                                  int(* add_entropy_cb)(void* context, const uint8_t input[], size_t length),
                                                  void(* destroy_cb)(void* context));
@@ -280,7 +261,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_rng_init_custom(botan_rng_t* rng_out, const char
 * @param out_len number of requested bytes
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len);
+BOTAN_PUBLIC_API(2,0) int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len);
 
 /**
 * Get random bytes from system random number generator
@@ -288,7 +269,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t ou
 * @param out_len number of requested bytes
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(3,0) int botan_system_rng_get(uint8_t* out, size_t out_len);
+BOTAN_PUBLIC_API(3,0) int botan_system_rng_get(uint8_t* out, size_t out_len);
 
 /**
 * Reseed a random number generator
@@ -298,7 +279,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_system_rng_get(uint8_t* out, size_t out_len);
 * @param bits number of bits to reseed with
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_rng_reseed(botan_rng_t rng, size_t bits);
+BOTAN_PUBLIC_API(2,0) int botan_rng_reseed(botan_rng_t rng, size_t bits);
 
 /**
 * Reseed a random number generator
@@ -308,7 +289,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_rng_reseed(botan_rng_t rng, size_t bits);
 * @param bits number of bits to reseed with
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,8) int botan_rng_reseed_from_rng(botan_rng_t rng,
+BOTAN_PUBLIC_API(2,8) int botan_rng_reseed_from_rng(botan_rng_t rng,
                                                     botan_rng_t source_rng,
                                                     size_t bits);
 
@@ -320,7 +301,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_rng_reseed_from_rng(botan_rng_t rng,
 * @param entropy_len length of entropy buffer
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,8) int botan_rng_add_entropy(botan_rng_t rng,
+BOTAN_PUBLIC_API(2,8) int botan_rng_add_entropy(botan_rng_t rng,
                                                 const uint8_t* entropy,
                                                 size_t entropy_len);
 
@@ -329,7 +310,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_rng_add_entropy(botan_rng_t rng,
 * @param rng rng object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_rng_destroy(botan_rng_t rng);
+BOTAN_PUBLIC_API(2,0) int botan_rng_destroy(botan_rng_t rng);
 
 /*
 * Hash type
@@ -343,7 +324,7 @@ typedef struct botan_hash_struct* botan_hash_t;
 * @param flags should be 0 in current API revision, all other uses are reserved
 *       and return BOTAN_FFI_ERROR_BAD_FLAG
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags);
 
 /**
 * Copy the state of a hash function object
@@ -351,7 +332,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_hash_init(botan_hash_t* hash, const char* hash_n
 * @param source source hash object
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,2) int botan_hash_copy_state(botan_hash_t *dest, const botan_hash_t source);
+BOTAN_PUBLIC_API(2,2) int botan_hash_copy_state(botan_hash_t *dest, const botan_hash_t source);
 
 /**
 * Writes the output length of the hash function to *output_length
@@ -359,7 +340,7 @@ BOTAN_FFI_EXPORT(2,2) int botan_hash_copy_state(botan_hash_t *dest, const botan_
 * @param output_length output buffer to hold the hash function output length
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_output_length(botan_hash_t hash, size_t* output_length);
+BOTAN_PUBLIC_API(2,0) int botan_hash_output_length(botan_hash_t hash, size_t* output_length);
 
 /**
 * Writes the block size of the hash function to *block_size
@@ -367,7 +348,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_hash_output_length(botan_hash_t hash, size_t* ou
 * @param block_size output buffer to hold the hash function output length
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,2) int botan_hash_block_size(botan_hash_t hash, size_t* block_size);
+BOTAN_PUBLIC_API(2,2) int botan_hash_block_size(botan_hash_t hash, size_t* block_size);
 
 /**
 * Send more input to the hash function
@@ -376,7 +357,7 @@ BOTAN_FFI_EXPORT(2,2) int botan_hash_block_size(botan_hash_t hash, size_t* block
 * @param in_len number of bytes to read from the input buffer
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_update(botan_hash_t hash, const uint8_t* in, size_t in_len);
+BOTAN_PUBLIC_API(2,0) int botan_hash_update(botan_hash_t hash, const uint8_t* in, size_t in_len);
 
 /**
 * Finalizes the hash computation and writes the output to
@@ -386,7 +367,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_hash_update(botan_hash_t hash, const uint8_t* in
 * @param out output buffer
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_final(botan_hash_t hash, uint8_t out[]);
+BOTAN_PUBLIC_API(2,0) int botan_hash_final(botan_hash_t hash, uint8_t out[]);
 
 /**
 * Reinitializes the state of the hash computation. A hash can
@@ -394,14 +375,14 @@ BOTAN_FFI_EXPORT(2,0) int botan_hash_final(botan_hash_t hash, uint8_t out[]);
 * @param hash hash object
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_clear(botan_hash_t hash);
+BOTAN_PUBLIC_API(2,0) int botan_hash_clear(botan_hash_t hash);
 
 /**
 * Frees all resources of the hash object
 * @param hash hash object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_hash_destroy(botan_hash_t hash);
+BOTAN_PUBLIC_API(2,0) int botan_hash_destroy(botan_hash_t hash);
 
 /**
 * Get the name of this hash function
@@ -409,7 +390,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_hash_destroy(botan_hash_t hash);
 * @param name output buffer
 * @param name_len on input, the length of buffer, on success the number of bytes written
 */
-BOTAN_FFI_EXPORT(2,8) int botan_hash_name(botan_hash_t hash, char* name, size_t* name_len);
+BOTAN_PUBLIC_API(2,8) int botan_hash_name(botan_hash_t hash, char* name, size_t* name_len);
 
 /*
 * Message Authentication type
@@ -424,7 +405,7 @@ typedef struct botan_mac_struct* botan_mac_t;
 *       and return a negative value (error code)
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags);
 
 /**
 * Writes the output length of the message authentication code to *output_length
@@ -432,7 +413,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_init(botan_mac_t* mac, const char* mac_name,
 * @param output_length output buffer to hold the MAC output length
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_output_length(botan_mac_t mac, size_t* output_length);
+BOTAN_PUBLIC_API(2,0) int botan_mac_output_length(botan_mac_t mac, size_t* output_length);
 
 /**
 * Sets the key on the MAC
@@ -441,7 +422,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_output_length(botan_mac_t mac, size_t* outpu
 * @param key_len size of the key buffer in bytes
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len);
+BOTAN_PUBLIC_API(2,0) int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len);
 
 /**
 * Sets the nonce on the MAC
@@ -450,7 +431,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_set_key(botan_mac_t mac, const uint8_t* key,
 * @param nonce_len size of the key buffer in bytes
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(3,0) int botan_mac_set_nonce(botan_mac_t mac, const uint8_t* nonce, size_t nonce_len);
+BOTAN_PUBLIC_API(3,0) int botan_mac_set_nonce(botan_mac_t mac, const uint8_t* nonce, size_t nonce_len);
 
 /**
 * Send more input to the message authentication code
@@ -459,7 +440,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_mac_set_nonce(botan_mac_t mac, const uint8_t* no
 * @param len number of bytes to read from the input buffer
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_update(botan_mac_t mac, const uint8_t* buf, size_t len);
+BOTAN_PUBLIC_API(2,0) int botan_mac_update(botan_mac_t mac, const uint8_t* buf, size_t len);
 
 /**
 * Finalizes the MAC computation and writes the output to
@@ -469,7 +450,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_update(botan_mac_t mac, const uint8_t* buf,
 * @param out output buffer
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_final(botan_mac_t mac, uint8_t out[]);
+BOTAN_PUBLIC_API(2,0) int botan_mac_final(botan_mac_t mac, uint8_t out[]);
 
 /**
 * Reinitializes the state of the MAC computation. A MAC can
@@ -477,7 +458,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_final(botan_mac_t mac, uint8_t out[]);
 * @param mac mac object
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_clear(botan_mac_t mac);
+BOTAN_PUBLIC_API(2,0) int botan_mac_clear(botan_mac_t mac);
 
 /**
 * Get the name of this MAC
@@ -485,7 +466,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_mac_clear(botan_mac_t mac);
 * @param name output buffer
 * @param name_len on input, the length of buffer, on success the number of bytes written
 */
-BOTAN_FFI_EXPORT(2,8) int botan_mac_name(botan_mac_t mac, char* name, size_t* name_len);
+BOTAN_PUBLIC_API(2,8) int botan_mac_name(botan_mac_t mac, char* name, size_t* name_len);
 
 /**
 * Get the key length limits of this auth code
@@ -494,7 +475,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_mac_name(botan_mac_t mac, char* name, size_t* na
 * @param out_maximum_keylength if non-NULL, will be set to maximum keylength of MAC
 * @param out_keylength_modulo if non-NULL will be set to byte multiple of valid keys
 */
-BOTAN_FFI_EXPORT(2,8) int botan_mac_get_keyspec(botan_mac_t mac,
+BOTAN_PUBLIC_API(2,8) int botan_mac_get_keyspec(botan_mac_t mac,
                                                  size_t* out_minimum_keylength,
                                                  size_t* out_maximum_keylength,
                                                  size_t* out_keylength_modulo);
@@ -504,7 +485,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_mac_get_keyspec(botan_mac_t mac,
 * @param mac mac object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_mac_destroy(botan_mac_t mac);
+BOTAN_PUBLIC_API(2,0) int botan_mac_destroy(botan_mac_t mac);
 
 /*
 * Cipher modes
@@ -518,56 +499,56 @@ typedef struct botan_cipher_struct* botan_cipher_t;
 /**
 * Initialize a cipher object
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_init(botan_cipher_t* cipher, const char* name, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_init(botan_cipher_t* cipher, const char* name, uint32_t flags);
 
 /**
 * Return the name of the cipher object
 */
-BOTAN_FFI_EXPORT(2,8) int botan_cipher_name(botan_cipher_t cipher, char* name, size_t* name_len);
+BOTAN_PUBLIC_API(2,8) int botan_cipher_name(botan_cipher_t cipher, char* name, size_t* name_len);
 
 /**
 * Return the output length of this cipher, for a particular input length.
 */
-BOTAN_FFI_EXPORT(2,8) int botan_cipher_output_length(botan_cipher_t cipher, size_t in_len, size_t* out_len);
+BOTAN_PUBLIC_API(2,8) int botan_cipher_output_length(botan_cipher_t cipher, size_t in_len, size_t* out_len);
 
 /**
 * Return if the specified nonce length is valid for this cipher
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl);
 
 /**
 * Get the tag length of the cipher (0 for non-AEAD modes)
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_size);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_size);
 
 /**
 * Get the default nonce length of this cipher
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl);
 
 /**
 * Return the update granularity of the cipher; botan_cipher_update must be
 * called with blocks of this size, except for the final.
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_get_update_granularity(botan_cipher_t cipher, size_t* ug);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_get_update_granularity(botan_cipher_t cipher, size_t* ug);
 
 /**
 * Return the ideal update granularity of the cipher. This is some multiple of the
 * update granularity, reflecting possibilities for optimization.
 */
-BOTAN_FFI_EXPORT(3,0) int botan_cipher_get_ideal_update_granularity(botan_cipher_t cipher, size_t* ug);
+BOTAN_PUBLIC_API(3,0) int botan_cipher_get_ideal_update_granularity(botan_cipher_t cipher, size_t* ug);
 
 /**
 * Get information about the key lengths. Prefer botan_cipher_get_keyspec
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_query_keylen(botan_cipher_t,
+BOTAN_PUBLIC_API(2,0) int botan_cipher_query_keylen(botan_cipher_t,
                                         size_t* out_minimum_keylength,
                                         size_t* out_maximum_keylength);
 
 /**
 * Get information about the supported key lengths.
 */
-BOTAN_FFI_EXPORT(2,8) int botan_cipher_get_keyspec(botan_cipher_t,
+BOTAN_PUBLIC_API(2,8) int botan_cipher_get_keyspec(botan_cipher_t,
                                                    size_t* min_keylen,
                                                    size_t* max_keylen,
                                                    size_t* mod_keylen);
@@ -575,7 +556,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_cipher_get_keyspec(botan_cipher_t,
 /**
 * Set the key for this cipher object
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_set_key(botan_cipher_t cipher,
+BOTAN_PUBLIC_API(2,0) int botan_cipher_set_key(botan_cipher_t cipher,
                                                const uint8_t* key, size_t key_len);
 
 /**
@@ -586,18 +567,18 @@ BOTAN_FFI_EXPORT(2,0) int botan_cipher_set_key(botan_cipher_t cipher,
 * It is conceptually equivalent to calling botan_cipher_clear followed
 * by botan_cipher_set_key with the original key.
 */
-BOTAN_FFI_EXPORT(2,8) int botan_cipher_reset(botan_cipher_t cipher);
+BOTAN_PUBLIC_API(2,8) int botan_cipher_reset(botan_cipher_t cipher);
 
 /**
 * Set the associated data. Will fail if cipher is not an AEAD
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_set_associated_data(botan_cipher_t cipher,
+BOTAN_PUBLIC_API(2,0) int botan_cipher_set_associated_data(botan_cipher_t cipher,
                                                const uint8_t* ad, size_t ad_len);
 
 /**
 * Begin processing a new message using the provided nonce
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_start(botan_cipher_t cipher,
+BOTAN_PUBLIC_API(2,0) int botan_cipher_start(botan_cipher_t cipher,
                                  const uint8_t* nonce, size_t nonce_len);
 
 #define BOTAN_CIPHER_UPDATE_FLAG_FINAL (1U << 0)
@@ -605,7 +586,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_cipher_start(botan_cipher_t cipher,
 /**
 * Encrypt some data
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_update(botan_cipher_t cipher,
+BOTAN_PUBLIC_API(2,0) int botan_cipher_update(botan_cipher_t cipher,
                                   uint32_t flags,
                                   uint8_t output[],
                                   size_t output_size,
@@ -617,13 +598,13 @@ BOTAN_FFI_EXPORT(2,0) int botan_cipher_update(botan_cipher_t cipher,
 /**
 * Reset the key, nonce, AD and all other state on this cipher object
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_clear(botan_cipher_t hash);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_clear(botan_cipher_t hash);
 
 /**
 * Destroy the cipher object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_cipher_destroy(botan_cipher_t cipher);
+BOTAN_PUBLIC_API(2,0) int botan_cipher_destroy(botan_cipher_t cipher);
 
 /*
 * Derive a key from a passphrase for a number of iterations
@@ -640,8 +621,8 @@ BOTAN_FFI_EXPORT(2,0) int botan_cipher_destroy(botan_cipher_t cipher);
 *  botan_pwdhash(pbkdf_algo, iterations, 0, 0, out, out_len,
 *                passphrase, 0, salt, salt_len);
 */
-BOTAN_FFI_DEPRECATED("Use botan_pwdhash")
-BOTAN_FFI_EXPORT(2,0) int
+BOTAN_DEPRECATED("Use botan_pwdhash")
+BOTAN_PUBLIC_API(2,0) int
 botan_pbkdf(const char* pbkdf_algo,
             uint8_t out[], size_t out_len,
             const char* passphrase,
@@ -672,7 +653,7 @@ botan_pbkdf(const char* pbkdf_algo,
 *                     password, 0,
 *                     salt, salt_len);
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pbkdf_timed(const char* pbkdf_algo,
+BOTAN_PUBLIC_API(2,0) int botan_pbkdf_timed(const char* pbkdf_algo,
                                 uint8_t out[], size_t out_len,
                                 const char* passphrase,
                                 const uint8_t salt[], size_t salt_len,
@@ -695,7 +676,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_pbkdf_timed(const char* pbkdf_algo,
 * @param salt_len length of salt in bytes
 * @return 0 on success, a negative value on failure
 */
-int BOTAN_FFI_EXPORT(2,8) botan_pwdhash(
+int BOTAN_PUBLIC_API(2,8) botan_pwdhash(
    const char* algo,
    size_t param1,
    size_t param2,
@@ -723,7 +704,7 @@ int BOTAN_FFI_EXPORT(2,8) botan_pwdhash(
 * @param salt_len length of salt in bytes
 * @return 0 on success, a negative value on failure
 */
-int BOTAN_FFI_EXPORT(2,8) botan_pwdhash_timed(
+int BOTAN_PUBLIC_API(2,8) botan_pwdhash_timed(
    const char* algo,
    uint32_t msec,
    size_t* param1,
@@ -741,8 +722,8 @@ int BOTAN_FFI_EXPORT(2,8) botan_pwdhash_timed(
 * Deprecated; use
 * botan_pwdhash("Scrypt", N, r, p, out, out_len, password, 0, salt, salt_len);
 */
-BOTAN_FFI_DEPRECATED("Use botan_pwdhash")
-BOTAN_FFI_EXPORT(2,8) int
+BOTAN_DEPRECATED("Use botan_pwdhash")
+BOTAN_PUBLIC_API(2,8) int
 botan_scrypt(uint8_t out[], size_t out_len,
              const char* passphrase,
              const uint8_t salt[], size_t salt_len,
@@ -761,7 +742,7 @@ botan_scrypt(uint8_t out[], size_t out_len,
 * @param label_len size of label in bytes
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_kdf(const char* kdf_algo,
+BOTAN_PUBLIC_API(2,0) int botan_kdf(const char* kdf_algo,
                         uint8_t out[], size_t out_len,
                         const uint8_t secret[], size_t secret_len,
                         const uint8_t salt[], size_t salt_len,
@@ -775,37 +756,37 @@ typedef struct botan_block_cipher_struct* botan_block_cipher_t;
 /**
 * Initialize a block cipher object
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_init(botan_block_cipher_t* bc,
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_init(botan_block_cipher_t* bc,
                                                   const char* cipher_name);
 
 /**
 * Destroy a block cipher object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_destroy(botan_block_cipher_t bc);
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_destroy(botan_block_cipher_t bc);
 
 /**
 * Reinitializes the block cipher
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_clear(botan_block_cipher_t bc);
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_clear(botan_block_cipher_t bc);
 
 /**
 * Set the key for a block cipher instance
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_set_key(botan_block_cipher_t bc,
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_set_key(botan_block_cipher_t bc,
                                                      const uint8_t key[], size_t len);
 
 /**
 * Return the positive block size of this block cipher, or negative to
 * indicate an error
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_block_size(botan_block_cipher_t bc);
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_block_size(botan_block_cipher_t bc);
 
 /**
 * Encrypt one or more blocks with the cipher
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc,
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc,
                                                             const uint8_t in[],
                                                             uint8_t out[],
                                                             size_t blocks);
@@ -813,7 +794,7 @@ BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_encrypt_blocks(botan_block_cipher_t
 /**
 * Decrypt one or more blocks with the cipher
 */
-BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc,
+BOTAN_PUBLIC_API(2,1) int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc,
                                                             const uint8_t in[],
                                                             uint8_t out[],
                                                             size_t blocks);
@@ -824,7 +805,7 @@ BOTAN_FFI_EXPORT(2,1) int botan_block_cipher_decrypt_blocks(botan_block_cipher_t
 * @param name output buffer
 * @param name_len on input, the length of buffer, on success the number of bytes written
 */
-BOTAN_FFI_EXPORT(2,8) int botan_block_cipher_name(botan_block_cipher_t cipher,
+BOTAN_PUBLIC_API(2,8) int botan_block_cipher_name(botan_block_cipher_t cipher,
                                                   char* name, size_t* name_len);
 
 
@@ -835,7 +816,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_block_cipher_name(botan_block_cipher_t cipher,
 * @param out_maximum_keylength if non-NULL, will be set to maximum keylength of cipher
 * @param out_keylength_modulo if non-NULL will be set to byte multiple of valid keys
 */
-BOTAN_FFI_EXPORT(2,8) int botan_block_cipher_get_keyspec(botan_block_cipher_t cipher,
+BOTAN_PUBLIC_API(2,8) int botan_block_cipher_get_keyspec(botan_block_cipher_t cipher,
                                                          size_t* out_minimum_keylength,
                                                          size_t* out_maximum_keylength,
                                                          size_t* out_keylength_modulo);
@@ -848,108 +829,108 @@ typedef struct botan_mp_struct* botan_mp_t;
 /**
 * Initialize an MPI
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_init(botan_mp_t* mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_init(botan_mp_t* mp);
 
 /**
 * Destroy (deallocate) an MPI
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_destroy(botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_destroy(botan_mp_t mp);
 
 /**
 * Convert the MPI to a hex string. Writes botan_mp_num_bytes(mp)*2 + 1 bytes
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_to_hex(const botan_mp_t mp, char* out);
+BOTAN_PUBLIC_API(2,1) int botan_mp_to_hex(const botan_mp_t mp, char* out);
 
 /**
 * Convert the MPI to a string. Currently base == 10 and base == 16 are supported.
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_to_str(const botan_mp_t mp, uint8_t base, char* out, size_t* out_len);
+BOTAN_PUBLIC_API(2,1) int botan_mp_to_str(const botan_mp_t mp, uint8_t base, char* out, size_t* out_len);
 
 /**
 * Set the MPI to zero
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_clear(botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_clear(botan_mp_t mp);
 
 /**
 * Set the MPI value from an int
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_set_from_int(botan_mp_t mp, int initial_value);
+BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_int(botan_mp_t mp, int initial_value);
 
 /**
 * Set the MPI value from another MP object
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source);
+BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source);
 
 /**
 * Set the MPI value from a string
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_set_from_str(botan_mp_t dest, const char* str);
+BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_str(botan_mp_t dest, const char* str);
 
 /**
 * Set the MPI value from a string with arbitrary radix.
 * For arbitrary being 10 or 16.
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_set_from_radix_str(botan_mp_t dest, const char* str, size_t radix);
+BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_radix_str(botan_mp_t dest, const char* str, size_t radix);
 
 /**
 * Return the number of significant bits in the MPI
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_num_bits(const botan_mp_t n, size_t* bits);
+BOTAN_PUBLIC_API(2,1) int botan_mp_num_bits(const botan_mp_t n, size_t* bits);
 
 /**
 * Return the number of significant bytes in the MPI
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_num_bytes(const botan_mp_t n, size_t* bytes);
+BOTAN_PUBLIC_API(2,1) int botan_mp_num_bytes(const botan_mp_t n, size_t* bytes);
 
 /*
 * Convert the MPI to a big-endian binary string. Writes botan_mp_num_bytes to vec
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]);
+BOTAN_PUBLIC_API(2,1) int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]);
 
 /*
 * Set an MP to the big-endian binary value
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_from_bin(const botan_mp_t mp, const uint8_t vec[], size_t vec_len);
+BOTAN_PUBLIC_API(2,1) int botan_mp_from_bin(const botan_mp_t mp, const uint8_t vec[], size_t vec_len);
 
 /*
 * Convert the MPI to a uint32_t, if possible. Fails if MPI is negative or too large.
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val);
+BOTAN_PUBLIC_API(2,1) int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val);
 
 /**
 * This function should have been named mp_is_non_negative. Returns 1
 * iff mp is greater than *or equal to* zero. Use botan_mp_is_negative
 * to detect negative numbers, botan_mp_is_zero to check for zero.
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_is_positive(const botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_is_positive(const botan_mp_t mp);
 
 /**
 * Return 1 iff mp is less than 0
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_is_negative(const botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_is_negative(const botan_mp_t mp);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_flip_sign(botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_flip_sign(botan_mp_t mp);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_is_zero(const botan_mp_t mp);
+BOTAN_PUBLIC_API(2,1) int botan_mp_is_zero(const botan_mp_t mp);
 
-BOTAN_FFI_DEPRECATED("Use botan_mp_get_bit(0)") BOTAN_FFI_EXPORT(2,1)
+BOTAN_DEPRECATED("Use botan_mp_get_bit(0)") BOTAN_PUBLIC_API(2,1)
 int botan_mp_is_odd(const botan_mp_t mp);
-BOTAN_FFI_DEPRECATED("Use botan_mp_get_bit(0)") BOTAN_FFI_EXPORT(2,1)
+BOTAN_DEPRECATED("Use botan_mp_get_bit(0)") BOTAN_PUBLIC_API(2,1)
 int botan_mp_is_even(const botan_mp_t mp);
 
-BOTAN_FFI_EXPORT(2,8) int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
-BOTAN_FFI_EXPORT(2,8) int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
+BOTAN_PUBLIC_API(2,8) int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
+BOTAN_PUBLIC_API(2,8) int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
-BOTAN_FFI_EXPORT(2,1) int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
-BOTAN_FFI_EXPORT(2,1) int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_div(botan_mp_t quotient,
+BOTAN_PUBLIC_API(2,1) int botan_mp_div(botan_mp_t quotient,
                                        botan_mp_t remainder,
                                        const botan_mp_t x, const botan_mp_t y);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_mod_mul(botan_mp_t result, const botan_mp_t x,
+BOTAN_PUBLIC_API(2,1) int botan_mp_mod_mul(botan_mp_t result, const botan_mp_t x,
                                            const botan_mp_t y, const botan_mp_t mod);
 
 /*
@@ -957,58 +938,58 @@ BOTAN_FFI_EXPORT(2,1) int botan_mp_mod_mul(botan_mp_t result, const botan_mp_t x
 * Returns 1 if x == y
 * Returns negative number on error
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_equal(const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_equal(const botan_mp_t x, const botan_mp_t y);
 
 /*
 * Sets *result to comparison result:
 * -1 if x < y, 0 if x == y, 1 if x > y
 * Returns negative number on error or zero on success
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_cmp(int* result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_cmp(int* result, const botan_mp_t x, const botan_mp_t y);
 
 /*
 * Swap two botan_mp_t
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_swap(botan_mp_t x, botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_swap(botan_mp_t x, botan_mp_t y);
 
 /* Return (base^exponent) % modulus */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus);
+BOTAN_PUBLIC_API(2,1) int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift);
-BOTAN_FFI_EXPORT(2,1) int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift);
+BOTAN_PUBLIC_API(2,1) int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift);
+BOTAN_PUBLIC_API(2,1) int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus);
+BOTAN_PUBLIC_API(2,1) int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits);
+BOTAN_PUBLIC_API(2,1) int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng,
+BOTAN_PUBLIC_API(2,1) int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng,
                                   const botan_mp_t lower_bound, const botan_mp_t upper_bound);
 
-BOTAN_FFI_EXPORT(2,1) int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y);
+BOTAN_PUBLIC_API(2,1) int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y);
 
 /**
 * Returns 0 if n is not prime
 * Returns 1 if n is prime
 * Returns negative number on error
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_is_prime(const botan_mp_t n, botan_rng_t rng, size_t test_prob);
+BOTAN_PUBLIC_API(2,1) int botan_mp_is_prime(const botan_mp_t n, botan_rng_t rng, size_t test_prob);
 
 /**
 * Returns 0 if specified bit of n is not set
 * Returns 1 if specified bit of n is set
 * Returns negative number on error
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_get_bit(const botan_mp_t n, size_t bit);
+BOTAN_PUBLIC_API(2,1) int botan_mp_get_bit(const botan_mp_t n, size_t bit);
 
 /**
 * Set the specified bit
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_set_bit(botan_mp_t n, size_t bit);
+BOTAN_PUBLIC_API(2,1) int botan_mp_set_bit(botan_mp_t n, size_t bit);
 
 /**
 * Clear the specified bit
 */
-BOTAN_FFI_EXPORT(2,1) int botan_mp_clear_bit(botan_mp_t n, size_t bit);
+BOTAN_PUBLIC_API(2,1) int botan_mp_clear_bit(botan_mp_t n, size_t bit);
 
 /* Bcrypt password hashing */
 
@@ -1025,7 +1006,7 @@ BOTAN_FFI_EXPORT(2,1) int botan_mp_clear_bit(botan_mp_t n, size_t bit);
 
 * Output is formatted bcrypt $2a$...
 */
-BOTAN_FFI_EXPORT(2,0) int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
+BOTAN_PUBLIC_API(2,0) int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
                                     const char* password,
                                     botan_rng_t rng,
                                     size_t work_factor,
@@ -1039,7 +1020,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
 *       1 if the combination is not valid (but otherwise well formed),
 *       negative on error
 */
-BOTAN_FFI_EXPORT(2,0) int botan_bcrypt_is_valid(const char* pass, const char* hash);
+BOTAN_PUBLIC_API(2,0) int botan_bcrypt_is_valid(const char* pass, const char* hash);
 
 /*
 * Public/private key creation, import, ...
@@ -1054,24 +1035,24 @@ typedef struct botan_privkey_struct* botan_privkey_t;
 *        the modulus bit length. For ECC is the name of the curve.
 * @param rng a random number generator
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_create(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_create(botan_privkey_t* key,
                                                const char* algo_name,
                                                const char* algo_params,
                                                botan_rng_t rng);
 
 #define BOTAN_CHECK_KEY_EXPENSIVE_TESTS 1
 
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_check_key(botan_privkey_t key, botan_rng_t rng, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_privkey_check_key(botan_privkey_t key, botan_rng_t rng, uint32_t flags);
 
-BOTAN_FFI_DEPRECATED("Use botan_privkey_create") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_create") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng, size_t n_bits);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_create") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_create") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng, const char* params);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_create") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_create") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng, const char* params);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_create") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_create") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_create") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_create") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, const char* param);
 
 /**
@@ -1092,7 +1073,7 @@ int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, const char* p
  * @returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED functionality not implemented
  *
 */
-BOTAN_FFI_EXPORT(2,5) int botan_privkey_create_dsa(
+BOTAN_PUBLIC_API(2,5) int botan_privkey_create_dsa(
                                 botan_privkey_t* key,
                                 botan_rng_t rng,
                                 size_t pbits,
@@ -1117,7 +1098,7 @@ BOTAN_FFI_EXPORT(2,5) int botan_privkey_create_dsa(
  * @returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED functionality not implemented
  *
 */
-BOTAN_FFI_EXPORT(2,5) int botan_privkey_create_elgamal(
+BOTAN_PUBLIC_API(2,5) int botan_privkey_create_elgamal(
                             botan_privkey_t* key,
                             botan_rng_t rng,
                             size_t pbits,
@@ -1128,7 +1109,7 @@ BOTAN_FFI_EXPORT(2,5) int botan_privkey_create_elgamal(
 * Set password to NULL to indicate no encryption expected
 * Starting in 2.8.0, the rng parameter is unused and may be set to null
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_load(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load(botan_privkey_t* key,
                                              botan_rng_t rng,
                                              const uint8_t bits[], size_t len,
                                              const char* password);
@@ -1136,7 +1117,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_load(botan_privkey_t* key,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_destroy(botan_privkey_t key);
+BOTAN_PUBLIC_API(2,0) int botan_privkey_destroy(botan_privkey_t key);
 
 #define BOTAN_PRIVKEY_EXPORT_FLAG_DER 0
 #define BOTAN_PRIVKEY_EXPORT_FLAG_PEM 1
@@ -1148,14 +1129,14 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_destroy(botan_privkey_t key);
 * Returns 0 on success and sets
 * If some other error occurs a negative integer is returned.
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_export(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_export(botan_privkey_t key,
                                    uint8_t out[], size_t* out_len,
                                    uint32_t flags);
 
 /**
 * View the private key's DER encoding
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_der(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_der(
    botan_privkey_t key,
    botan_view_ctx ctx,
    botan_view_bin_fn view);
@@ -1163,18 +1144,18 @@ BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_der(
 /**
 * View the private key's PEM encoding
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_pem(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_pem(
    botan_privkey_t key,
    botan_view_ctx ctx,
    botan_view_str_fn view);
 
-BOTAN_FFI_EXPORT(2,8) int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,8) int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t* out_len);
 
 /**
 * Set encryption_algo to NULL or "" to have the library choose a default (recommended)
 */
-BOTAN_FFI_DEPRECATED("Use botan_privkey_export_encrypted_pbkdf_{msec,iter}")
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted(botan_privkey_t key,
+BOTAN_DEPRECATED("Use botan_privkey_export_encrypted_pbkdf_{msec,iter}")
+BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted(botan_privkey_t key,
                                              uint8_t out[], size_t* out_len,
                                              botan_rng_t rng,
                                              const char* passphrase,
@@ -1187,7 +1168,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted(botan_privkey_t key,
 *
 * Note: starting in 3.0, the output iterations count is not provided
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key,
                                                         uint8_t out[], size_t* out_len,
                                                         botan_rng_t rng,
                                                         const char* passphrase,
@@ -1200,7 +1181,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted_pbkdf_msec(botan_privke
 /**
 * Export a private key using the specified number of iterations.
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key,
                                                         uint8_t out[], size_t* out_len,
                                                         botan_rng_t rng,
                                                         const char* passphrase,
@@ -1215,7 +1196,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_encrypted_pbkdf_iter(botan_privke
 * Set cipher_algo, pbkdf_algo to NULL to use defaults
 * Set pbkdf_iterations to 0 to use defaults
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_der(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_encrypted_der(
    botan_privkey_t key,
    botan_rng_t rng,
    const char* passphrase,
@@ -1230,7 +1211,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_der(
 *
 * Set cipher_algo, pbkdf_algo to NULL to use defaults
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_der_timed(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_encrypted_der_timed(
    botan_privkey_t key,
    botan_rng_t rng,
    const char* passphrase,
@@ -1246,7 +1227,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_der_timed(
 * Set cipher_algo, pbkdf_algo to NULL to use defaults
 * Set pbkdf_iterations to 0 to use defaults
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_pem(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_encrypted_pem(
    botan_privkey_t key,
    botan_rng_t rng,
    const char* passphrase,
@@ -1261,7 +1242,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_pem(
 *
 * Set cipher_algo, pbkdf_algo to NULL to use defaults
 */
-BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_pem_timed(
+BOTAN_PUBLIC_API(3,0) int botan_privkey_view_encrypted_pem_timed(
    botan_privkey_t key,
    botan_rng_t rng,
    const char* passphrase,
@@ -1273,16 +1254,16 @@ BOTAN_FFI_EXPORT(3,0) int botan_privkey_view_encrypted_pem_timed(
 
 typedef struct botan_pubkey_struct* botan_pubkey_t;
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load(botan_pubkey_t* key, const uint8_t bits[], size_t len);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_load(botan_pubkey_t* key, const uint8_t bits[], size_t len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_export_pubkey(botan_pubkey_t* out, botan_privkey_t in);
+BOTAN_PUBLIC_API(2,0) int botan_privkey_export_pubkey(botan_pubkey_t* out, botan_privkey_t in);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags);
 
 /**
 * View the public key's DER encoding
 */
-BOTAN_FFI_EXPORT(3,0) int botan_pubkey_view_der(
+BOTAN_PUBLIC_API(3,0) int botan_pubkey_view_der(
    botan_pubkey_t key,
    botan_view_ctx ctx,
    botan_view_bin_fn view);
@@ -1290,100 +1271,100 @@ BOTAN_FFI_EXPORT(3,0) int botan_pubkey_view_der(
 /**
 * View the public key's PEM encoding
 */
-BOTAN_FFI_EXPORT(3,0) int botan_pubkey_view_pem(
+BOTAN_PUBLIC_API(3,0) int botan_pubkey_view_pem(
    botan_pubkey_t key,
    botan_view_ctx ctx,
    botan_view_str_fn view);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len);
 
 /**
 * Returns 0 if key is valid, negative if invalid key or some other error
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_check_key(botan_pubkey_t key, botan_rng_t rng, uint32_t flags);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_check_key(botan_pubkey_t key, botan_rng_t rng, uint32_t flags);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash,
                                        uint8_t out[], size_t* out_len);
 
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_destroy(botan_pubkey_t key);
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_destroy(botan_pubkey_t key);
 
 /*
 * Get arbitrary named fields from public or private keys
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_get_field(botan_mp_t output,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_get_field(botan_mp_t output,
                                      botan_pubkey_t key,
                                      const char* field_name);
 
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_get_field(botan_mp_t output,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_get_field(botan_mp_t output,
                                       botan_privkey_t key,
                                       const char* field_name);
 
 /*
 * Algorithm specific key operations: RSA
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_rsa(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load_rsa(botan_privkey_t* key,
                                      botan_mp_t p,
                                      botan_mp_t q,
                                      botan_mp_t e);
 
-BOTAN_FFI_EXPORT(2,8) int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,8) int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
                                                        const uint8_t bits[],
                                                        size_t len);
 
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t rsa_key);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t rsa_key);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t rsa_key);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t rsa_key);
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t rsa_key);
 
-BOTAN_FFI_EXPORT(2,8) int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
+BOTAN_PUBLIC_API(2,8) int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
                                                         uint8_t out[], size_t* out_len,
                                                         uint32_t flags);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_rsa(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_rsa(botan_pubkey_t* key,
                                                 botan_mp_t n,
                                                 botan_mp_t e);
 
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t rsa_key);
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t rsa_key);
 
 /*
 * Algorithm specific key operations: DSA
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_dsa(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load_dsa(botan_privkey_t* key,
                                      botan_mp_t p,
                                      botan_mp_t q,
                                      botan_mp_t g,
                                      botan_mp_t x);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_dsa(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_dsa(botan_pubkey_t* key,
                                     botan_mp_t p,
                                     botan_mp_t q,
                                     botan_mp_t g,
                                     botan_mp_t y);
 
-BOTAN_FFI_DEPRECATED("Use botan_privkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_privkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_privkey_dsa_get_x(botan_mp_t n, botan_privkey_t key);
 
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key);
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key);
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_dsa_get_g(botan_mp_t d, botan_pubkey_t key);
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_get_field") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("Use botan_pubkey_get_field") BOTAN_PUBLIC_API(2,0)
 int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key);
 
 /*
@@ -1399,7 +1380,7 @@ int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key);
 *
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_dh(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load_dh(botan_privkey_t* key,
                                          botan_mp_t p,
                                          botan_mp_t g,
                                          botan_mp_t x);
@@ -1416,7 +1397,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_dh(botan_privkey_t* key,
 *
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_dh(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_dh(botan_pubkey_t* key,
                                         botan_mp_t p,
                                         botan_mp_t g,
                                         botan_mp_t y);
@@ -1437,7 +1418,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_dh(botan_pubkey_t* key,
 *
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_elgamal(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_elgamal(botan_pubkey_t* key,
                                         botan_mp_t p,
                                         botan_mp_t g,
                                         botan_mp_t y);
@@ -1455,7 +1436,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_pubkey_load_elgamal(botan_pubkey_t* key,
 *
 * @return 0 on success, a negative value on failure
 */
-BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_elgamal(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load_elgamal(botan_privkey_t* key,
                                          botan_mp_t p,
                                          botan_mp_t g,
                                          botan_mp_t x);
@@ -1464,82 +1445,82 @@ BOTAN_FFI_EXPORT(2,0) int botan_privkey_load_elgamal(botan_privkey_t* key,
 * Algorithm specific key operations: Ed25519
 */
 
-BOTAN_FFI_EXPORT(2,2) int botan_privkey_load_ed25519(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,2) int botan_privkey_load_ed25519(botan_privkey_t* key,
                                          const uint8_t privkey[32]);
 
-BOTAN_FFI_EXPORT(2,2) int botan_pubkey_load_ed25519(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,2) int botan_pubkey_load_ed25519(botan_pubkey_t* key,
                                         const uint8_t pubkey[32]);
 
-BOTAN_FFI_EXPORT(2,2) int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,2) int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
                                                 uint8_t output[64]);
 
-BOTAN_FFI_EXPORT(2,2) int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
+BOTAN_PUBLIC_API(2,2) int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
                                               uint8_t pubkey[32]);
 
 /*
 * Algorithm specific key operations: X25519
 */
 
-BOTAN_FFI_EXPORT(2,8) int botan_privkey_load_x25519(botan_privkey_t* key,
+BOTAN_PUBLIC_API(2,8) int botan_privkey_load_x25519(botan_privkey_t* key,
                                                     const uint8_t privkey[32]);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pubkey_load_x25519(botan_pubkey_t* key,
+BOTAN_PUBLIC_API(2,8) int botan_pubkey_load_x25519(botan_pubkey_t* key,
                                                    const uint8_t pubkey[32]);
 
-BOTAN_FFI_EXPORT(2,8) int botan_privkey_x25519_get_privkey(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,8) int botan_privkey_x25519_get_privkey(botan_privkey_t key,
                                                            uint8_t output[32]);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key,
+BOTAN_PUBLIC_API(2,8) int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key,
                                                          uint8_t pubkey[32]);
 
 /*
 * Algorithm specific key operations: ECDSA and ECDH
 */
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_privkey_load_ecdsa(botan_privkey_t* key,
                              const botan_mp_t scalar,
                              const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
                             const botan_mp_t public_x,
                             const botan_mp_t public_y,
                             const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_pubkey_load_ecdh(botan_pubkey_t* key,
                            const botan_mp_t public_x,
                            const botan_mp_t public_y,
                            const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_privkey_load_ecdh(botan_privkey_t* key,
                             const botan_mp_t scalar,
                             const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_pubkey_load_sm2(botan_pubkey_t* key,
                           const botan_mp_t public_x,
                           const botan_mp_t public_y,
                           const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_PUBLIC_API(2,2)
 int botan_privkey_load_sm2(botan_privkey_t* key,
                            const botan_mp_t scalar,
                            const char* curve_name);
 
-BOTAN_FFI_DEPRECATED("Use botan_pubkey_load_sm2") BOTAN_FFI_EXPORT(2,2)
+BOTAN_DEPRECATED("Use botan_pubkey_load_sm2") BOTAN_PUBLIC_API(2,2)
 int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
                               const botan_mp_t public_x,
                               const botan_mp_t public_y,
                               const char* curve_name);
 
-BOTAN_FFI_DEPRECATED("Use botan_privkey_load_sm2") BOTAN_FFI_EXPORT(2,2)
+BOTAN_DEPRECATED("Use botan_privkey_load_sm2") BOTAN_PUBLIC_API(2,2)
 int botan_privkey_load_sm2_enc(botan_privkey_t* key,
                                const botan_mp_t scalar,
                                const char* curve_name);
 
-BOTAN_FFI_EXPORT(2,3)
+BOTAN_PUBLIC_API(2,3)
 int botan_pubkey_sm2_compute_za(uint8_t out[],
                                 size_t* out_len,
                                 const char* ident,
@@ -1549,7 +1530,7 @@ int botan_pubkey_sm2_compute_za(uint8_t out[],
 /**
 * View the uncompressed public point associated with the key
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_pubkey_view_ec_public_point(
    const botan_pubkey_t key,
    botan_view_ctx ctx,
@@ -1560,7 +1541,7 @@ int botan_pubkey_view_ec_public_point(
 */
 typedef struct botan_pk_op_encrypt_struct* botan_pk_op_encrypt_t;
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
                                          botan_pubkey_t key,
                                          const char* padding,
                                          uint32_t flags);
@@ -1568,13 +1549,13 @@ BOTAN_FFI_EXPORT(2,0) int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op,
+BOTAN_PUBLIC_API(2,8) int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op,
                                                             size_t ptext_len,
                                                             size_t* ctext_len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
                                               botan_rng_t rng,
                                               uint8_t out[],
                                               size_t* out_len,
@@ -1586,7 +1567,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
 */
 typedef struct botan_pk_op_decrypt_struct* botan_pk_op_decrypt_t;
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
                                          botan_privkey_t key,
                                          const char* padding,
                                          uint32_t flags);
@@ -1594,13 +1575,13 @@ BOTAN_FFI_EXPORT(2,0) int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op,
+BOTAN_PUBLIC_API(2,8) int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op,
                                                             size_t ctext_len,
                                                             size_t* ptext_len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
                                   uint8_t out[], size_t* out_len,
                                   const uint8_t ciphertext[], size_t ciphertext_len);
 
@@ -1612,7 +1593,7 @@ BOTAN_FFI_EXPORT(2,0) int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
 
 typedef struct botan_pk_op_sign_struct* botan_pk_op_sign_t;
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
                             botan_privkey_t key,
                             const char* hash_and_padding,
@@ -1621,13 +1602,13 @@ int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_sign_destroy(botan_pk_op_sign_t op);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_sign_destroy(botan_pk_op_sign_t op);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t* olen);
+BOTAN_PUBLIC_API(2,8) int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t* olen);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len);
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng,
                             uint8_t sig[], size_t* sig_len);
 
@@ -1636,7 +1617,7 @@ int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng,
 */
 typedef struct botan_pk_op_verify_struct* botan_pk_op_verify_t;
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
                               botan_pubkey_t key,
                               const char* hash_and_padding,
@@ -1645,17 +1626,17 @@ int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_verify_destroy(botan_pk_op_verify_t op);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_destroy(botan_pk_op_verify_t op);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len);
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len);
 
 /*
 * Key Agreement
 */
 typedef struct botan_pk_op_ka_struct* botan_pk_op_ka_t;
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
                                      botan_privkey_t key,
                                      const char* kdf,
@@ -1664,19 +1645,19 @@ int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op);
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op);
 
-BOTAN_FFI_EXPORT(2,0) int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
+BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
                                                       uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_key_agreement_view_public(
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_key_agreement_view_public(
    botan_privkey_t key,
    botan_view_ctx ctx,
    botan_view_bin_fn view);
 
-BOTAN_FFI_EXPORT(2,8) int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len);
+BOTAN_PUBLIC_API(2,8) int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
                               uint8_t out[], size_t* out_len,
                               const uint8_t other_key[], size_t other_key_len,
@@ -1687,7 +1668,7 @@ int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
 */
 typedef struct botan_pk_op_kem_encrypt_struct* botan_pk_op_kem_encrypt_t;
 
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_encrypt_create(
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_encrypt_create(
    botan_pk_op_kem_encrypt_t* op,
    botan_pubkey_t key,
    const char* kdf);
@@ -1695,20 +1676,20 @@ BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_encrypt_create(
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_encrypt_destroy(botan_pk_op_kem_encrypt_t op);
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_encrypt_destroy(botan_pk_op_kem_encrypt_t op);
 
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_pk_op_kem_encrypt_shared_key_length(
    botan_pk_op_kem_encrypt_t op,
    size_t desired_shared_key_length,
    size_t* output_shared_key_length);
 
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_pk_op_kem_encrypt_encapsulated_key_length(
    botan_pk_op_kem_encrypt_t op,
    size_t* output_encapsulated_key_length);
 
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_encrypt_create_shared_key(
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_encrypt_create_shared_key(
    botan_pk_op_kem_encrypt_t op,
    botan_rng_t rng,
    const uint8_t salt[],
@@ -1721,7 +1702,7 @@ BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_encrypt_create_shared_key(
 
 typedef struct botan_pk_op_kem_decrypt_struct* botan_pk_op_kem_decrypt_t;
 
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_decrypt_create(
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_decrypt_create(
    botan_pk_op_kem_decrypt_t* op,
    botan_privkey_t key,
    const char* kdf);
@@ -1729,15 +1710,15 @@ BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_decrypt_create(
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_decrypt_destroy(botan_pk_op_kem_decrypt_t op);
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_decrypt_destroy(botan_pk_op_kem_decrypt_t op);
 
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_pk_op_kem_decrypt_shared_key_length(
    botan_pk_op_kem_decrypt_t op,
    size_t desired_shared_key_length,
    size_t* output_shared_key_length);
 
-BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_decrypt_shared_key(
+BOTAN_PUBLIC_API(3,0) int botan_pk_op_kem_decrypt_shared_key(
    botan_pk_op_kem_decrypt_t op,
    const uint8_t salt[],
    size_t salt_len,
@@ -1751,13 +1732,13 @@ BOTAN_FFI_EXPORT(3,0) int botan_pk_op_kem_decrypt_shared_key(
 * Signature Scheme Utility Functions
 */
 
-BOTAN_FFI_EXPORT(2,0) int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len);
+BOTAN_PUBLIC_API(2,0) int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len);
 
 
 /*
 * Always returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED
 */
-BOTAN_FFI_DEPRECATED("No longer implemented") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("No longer implemented") BOTAN_PUBLIC_API(2,0)
 int botan_mceies_encrypt(botan_pubkey_t mce_key,
                          botan_rng_t rng,
                          const char* aead,
@@ -1768,7 +1749,7 @@ int botan_mceies_encrypt(botan_pubkey_t mce_key,
 /*
 * Always returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED
 */
-BOTAN_FFI_DEPRECATED("No longer implemented") BOTAN_FFI_EXPORT(2,0)
+BOTAN_DEPRECATED("No longer implemented") BOTAN_PUBLIC_API(2,0)
 int botan_mceies_decrypt(botan_privkey_t mce_key,
                          const char* aead,
                          const uint8_t ct[], size_t ct_len,
@@ -1781,52 +1762,52 @@ int botan_mceies_decrypt(botan_privkey_t mce_key,
 
 typedef struct botan_x509_cert_struct* botan_x509_cert_t;
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert[], size_t cert_len);
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* filename);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert[], size_t cert_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* filename);
 
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_destroy(botan_x509_cert_t cert);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_destroy(botan_x509_cert_t cert);
 
-BOTAN_FFI_EXPORT(2,8) int botan_x509_cert_dup(botan_x509_cert_t* new_cert, botan_x509_cert_t cert);
+BOTAN_PUBLIC_API(2,8) int botan_x509_cert_dup(botan_x509_cert_t* new_cert, botan_x509_cert_t cert);
 
 /* Prefer botan_x509_cert_not_before and botan_x509_cert_not_after */
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len);
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,8) int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch);
-BOTAN_FFI_EXPORT(2,8) int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch);
+BOTAN_PUBLIC_API(2,8) int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch);
+BOTAN_PUBLIC_API(2,8) int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch);
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert,
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert,
                                                   uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(3,0) int botan_x509_cert_view_public_key_bits(
+BOTAN_PUBLIC_API(3,0) int botan_x509_cert_view_public_key_bits(
    botan_x509_cert_t cert,
    botan_view_ctx ctx,
    botan_view_bin_fn view);
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key);
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert,
                                   const char* key, size_t index,
                                   uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,0)
+BOTAN_PUBLIC_API(2,0)
 int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert,
                                    const char* key, size_t index,
                                    uint8_t out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len);
 
-BOTAN_FFI_EXPORT(3,0) int botan_x509_cert_view_as_string(
+BOTAN_PUBLIC_API(3,0) int botan_x509_cert_view_as_string(
    botan_x509_cert_t cert,
    botan_view_ctx ctx,
    botan_view_str_fn view);
@@ -1845,13 +1826,13 @@ enum botan_x509_cert_key_constraints {
    DECIPHER_ONLY      = 128
 };
 
-BOTAN_FFI_EXPORT(2,0) int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage);
+BOTAN_PUBLIC_API(2,0) int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage);
 
 /**
 * Check if the certificate matches the specified hostname via alternative name or CN match.
 * RFC 5280 wildcards also supported.
 */
-BOTAN_FFI_EXPORT(2,5) int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname);
+BOTAN_PUBLIC_API(2,5) int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname);
 
 /**
 * Returns 0 if the validation was successful, 1 if validation failed,
@@ -1861,7 +1842,7 @@ BOTAN_FFI_EXPORT(2,5) int botan_x509_cert_hostname_match(botan_x509_cert_t cert,
 * Intermediates or trusted lists can be null
 * Trusted path can be null
 */
-BOTAN_FFI_EXPORT(2,8) int botan_x509_cert_verify(
+BOTAN_PUBLIC_API(2,8) int botan_x509_cert_verify(
    int* validation_result,
    botan_x509_cert_t cert,
    const botan_x509_cert_t* intermediates,
@@ -1877,7 +1858,7 @@ BOTAN_FFI_EXPORT(2,8) int botan_x509_cert_verify(
 * Returns a pointer to a static character string explaining the status code,
 * or else NULL if unknown.
 */
-BOTAN_FFI_EXPORT(2,8) const char* botan_x509_cert_validation_status(int code);
+BOTAN_PUBLIC_API(2,8) const char* botan_x509_cert_validation_status(int code);
 
 /*
 * X.509 CRL
@@ -1885,22 +1866,22 @@ BOTAN_FFI_EXPORT(2,8) const char* botan_x509_cert_validation_status(int code);
 
 typedef struct botan_x509_crl_struct* botan_x509_crl_t;
 
-BOTAN_FFI_EXPORT(2,13) int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path);
-BOTAN_FFI_EXPORT(2,13) int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len);
+BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path);
+BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len);
 
-BOTAN_FFI_EXPORT(2,13) int botan_x509_crl_destroy(botan_x509_crl_t crl);
+BOTAN_PUBLIC_API(2,13) int botan_x509_crl_destroy(botan_x509_crl_t crl);
 
 /**
  * Given a CRL and a certificate,
  * check if the certificate is revoked on that particular CRL
  */
-BOTAN_FFI_EXPORT(2,13) int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert);
+BOTAN_PUBLIC_API(2,13) int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert);
 
 /**
  * Different flavor of `botan_x509_cert_verify`, supports revocation lists.
  * CRLs are passed as an array, same as intermediates and trusted CAs
  */
-BOTAN_FFI_EXPORT(2,13) int botan_x509_cert_verify_with_crl(
+BOTAN_PUBLIC_API(2,13) int botan_x509_cert_verify_with_crl(
    int* validation_result,
    botan_x509_cert_t cert,
    const botan_x509_cert_t* intermediates,
@@ -1917,25 +1898,25 @@ BOTAN_FFI_EXPORT(2,13) int botan_x509_cert_verify_with_crl(
 /**
  * Key wrapping as per RFC 3394
  */
-BOTAN_FFI_DEPRECATED("Use botan_nist_kw_enc")
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_DEPRECATED("Use botan_nist_kw_enc")
+BOTAN_PUBLIC_API(2,2)
 int botan_key_wrap3394(const uint8_t key[], size_t key_len,
                        const uint8_t kek[], size_t kek_len,
                        uint8_t wrapped_key[], size_t *wrapped_key_len);
 
-BOTAN_FFI_DEPRECATED("Use botan_nist_kw_dec")
-BOTAN_FFI_EXPORT(2,2)
+BOTAN_DEPRECATED("Use botan_nist_kw_dec")
+BOTAN_PUBLIC_API(2,2)
 int botan_key_unwrap3394(const uint8_t wrapped_key[], size_t wrapped_key_len,
                          const uint8_t kek[], size_t kek_len,
                          uint8_t key[], size_t *key_len);
 
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_nist_kw_enc(const char* cipher_algo, int padded,
                       const uint8_t key[], size_t key_len,
                       const uint8_t kek[], size_t kek_len,
                       uint8_t wrapped_key[], size_t *wrapped_key_len);
 
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_nist_kw_dec(const char* cipher_algo, int padded,
                       const uint8_t wrapped_key[], size_t wrapped_key_len,
                       const uint8_t kek[], size_t kek_len,
@@ -1950,7 +1931,7 @@ typedef struct botan_hotp_struct* botan_hotp_t;
 /**
 * Initialize a HOTP instance
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_hotp_init(botan_hotp_t* hotp,
                     const uint8_t key[], size_t key_len,
                     const char* hash_algo,
@@ -1960,13 +1941,13 @@ int botan_hotp_init(botan_hotp_t* hotp,
 * Destroy a HOTP instance
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_hotp_destroy(botan_hotp_t hotp);
 
 /**
 * Generate a HOTP code for the provided counter
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_hotp_generate(botan_hotp_t hotp,
                         uint32_t* hotp_code,
                         uint64_t hotp_counter);
@@ -1974,7 +1955,7 @@ int botan_hotp_generate(botan_hotp_t hotp,
 /**
 * Verify a HOTP code
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_hotp_check(botan_hotp_t hotp,
                      uint64_t* next_hotp_counter,
                      uint32_t hotp_code,
@@ -1991,7 +1972,7 @@ typedef struct botan_totp_struct* botan_totp_t;
 /**
 * Initialize a TOTP instance
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_totp_init(botan_totp_t* totp,
                     const uint8_t key[], size_t key_len,
                     const char* hash_algo,
@@ -2002,7 +1983,7 @@ int botan_totp_init(botan_totp_t* totp,
 * Destroy a TOTP instance
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_totp_destroy(botan_totp_t totp);
 
 /**
@@ -2011,7 +1992,7 @@ int botan_totp_destroy(botan_totp_t totp);
 * @param totp_code the OTP code will be written here
 * @param timestamp the current local timestamp
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_totp_generate(botan_totp_t totp,
                         uint32_t* totp_code,
                         uint64_t timestamp);
@@ -2024,7 +2005,7 @@ int botan_totp_generate(botan_totp_t totp,
 * @param acceptable_clock_drift specifies the acceptable amount
 * of clock drift (in terms of time steps) between the two hosts.
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_totp_check(botan_totp_t totp,
                      uint32_t totp_code,
                      uint64_t timestamp,
@@ -2039,7 +2020,7 @@ typedef struct botan_fpe_struct* botan_fpe_t;
 
 #define BOTAN_FPE_FLAG_FE1_COMPAT_MODE 1
 
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,
                        const uint8_t key[], size_t key_len,
                        size_t rounds, uint32_t flags);
@@ -2047,13 +2028,13 @@ int botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,
 /**
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_fpe_destroy(botan_fpe_t fpe);
 
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len);
 
-BOTAN_FFI_EXPORT(2,8)
+BOTAN_PUBLIC_API(2,8)
 int botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len);
 
 /**
@@ -2065,7 +2046,7 @@ typedef struct botan_srp6_server_session_struct* botan_srp6_server_session_t;
 * Initialize an SRP-6 server session object
 * @param srp6 SRP-6 server session object
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_server_session_init(botan_srp6_server_session_t *srp6);
 
 /**
@@ -2073,7 +2054,7 @@ int botan_srp6_server_session_init(botan_srp6_server_session_t *srp6);
 * @param srp6 SRP-6 server session object
 * @return 0 if success, error if invalid object handle
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_server_session_destroy(botan_srp6_server_session_t srp6);
 
 /**
@@ -2088,7 +2069,7 @@ int botan_srp6_server_session_destroy(botan_srp6_server_session_t srp6);
 * @param B_pub_len SRP-6 B value length
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_server_session_step1(botan_srp6_server_session_t srp6,
                                     const uint8_t verifier[],
                                     size_t verifier_len, const char *group_id,
@@ -2104,7 +2085,7 @@ int botan_srp6_server_session_step1(botan_srp6_server_session_t srp6,
 * @param key_len symmetric key length
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_server_session_step2(botan_srp6_server_session_t srp6,
                                     const uint8_t A[], size_t A_len,
                                     uint8_t key[], size_t *key_len);
@@ -2121,7 +2102,7 @@ int botan_srp6_server_session_step2(botan_srp6_server_session_t srp6,
 * @param verifier_len SRP-6 verifier value length
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_generate_verifier(const char *identifier, const char *password,
                                  const uint8_t salt[], size_t salt_len,
                                  const char *group_id, const char *hash_id,
@@ -2144,7 +2125,7 @@ int botan_srp6_generate_verifier(const char *identifier, const char *password,
 * @param K_len symmetric key length
 * @return 0 on success, negative on failure
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_client_agree(const char *username, const char *password,
                             const char *group_id, const char *hash_id,
                             const uint8_t salt[], size_t salt_len,
@@ -2155,7 +2136,7 @@ int botan_srp6_client_agree(const char *username, const char *password,
 /**
 * Return the size, in bytes, of the prime associated with group_id
 */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_srp6_group_size(const char* group_id, size_t* group_p_bytes);
 
 /**
@@ -2176,7 +2157,7 @@ int botan_srp6_group_size(const char* group_id, size_t* group_p_bytes);
  *
  * @return 0 on success, negative on failure
  */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_zfec_encode(size_t K, size_t N,
                       const uint8_t *input,
                       size_t size,
@@ -2200,7 +2181,7 @@ int botan_zfec_encode(size_t K, size_t N,
  *
  * @return 0 on success, negative on failure
  */
-BOTAN_FFI_EXPORT(3,0)
+BOTAN_PUBLIC_API(3,0)
 int botan_zfec_decode(size_t K, size_t N,
                       const size_t *indexes,
                       uint8_t *const*const inputs,
diff --git a/src/lib/pubkey/xmss/xmss_parameters.h b/src/lib/pubkey/xmss/xmss_parameters.h
index c5d9ea820..f78d3cbd6 100644
--- a/src/lib/pubkey/xmss/xmss_parameters.h
+++ b/src/lib/pubkey/xmss/xmss_parameters.h
@@ -11,7 +11,7 @@
 #include <string>
 #include <map>
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include <botan/secmem.h>
 
 namespace Botan {
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index 78e1a58b6..0d2cfdd77 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -1,6 +1,6 @@
 /*
 * ChaCha
-* (C) 2014,2018,2023 Jack Lloyd
+* (C) 2014,2018 Jack Lloyd
 *
 * Botan is released under the Simplified BSD License (see license.txt)
 */
@@ -73,11 +73,6 @@ ChaCha::ChaCha(size_t rounds) : m_rounds(rounds)
 
 size_t ChaCha::parallelism()
    {
-#if defined(BOTAN_HAS_CHACHA_AVX512)
-   if(CPUID::has_avx512())
-      return 16;
-#endif
-
 #if defined(BOTAN_HAS_CHACHA_AVX2)
    if(CPUID::has_avx2())
       return 8;
@@ -88,13 +83,6 @@ size_t ChaCha::parallelism()
 
 std::string ChaCha::provider() const
    {
-#if defined(BOTAN_HAS_CHACHA_AVX512)
-   if(CPUID::has_avx512())
-      {
-      return "avx512";
-      }
-#endif
-
 #if defined(BOTAN_HAS_CHACHA_AVX2)
    if(CPUID::has_avx2())
       {
@@ -118,18 +106,6 @@ void ChaCha::chacha(uint8_t output[],
    {
    BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
 
-#if defined(BOTAN_HAS_CHACHA_AVX512)
-   if(CPUID::has_avx512())
-      {
-      while(output_blocks >= 16)
-         {
-         ChaCha::chacha_avx512_x16(output, state, rounds);
-         output += 16*64;
-         output_blocks -= 16;
-         }
-      }
-#endif
-
 #if defined(BOTAN_HAS_CHACHA_AVX2)
    if(CPUID::has_avx2())
       {
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index 174f7f9d3..ac02c05e5 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -76,10 +76,6 @@ class ChaCha final : public StreamCipher
       static void chacha_avx2_x8(uint8_t output[64*8], uint32_t state[16], size_t rounds);
 #endif
 
-#if defined(BOTAN_HAS_CHACHA_AVX512)
-      static void chacha_avx512_x16(uint8_t output[64*16], uint32_t state[16], size_t rounds);
-#endif
-
       size_t m_rounds;
       secure_vector<uint32_t> m_key;
       secure_vector<uint32_t> m_state;
diff --git a/src/lib/stream/chacha/chacha_avx512/chacha_avx512.cpp b/src/lib/stream/chacha/chacha_avx512/chacha_avx512.cpp
deleted file mode 100644
index ccaf56eed..000000000
--- a/src/lib/stream/chacha/chacha_avx512/chacha_avx512.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/chacha.h>
-#include <botan/internal/simd_avx512.h>
-
-namespace Botan {
-
-//static
-BOTAN_AVX512_FN
-void ChaCha::chacha_avx512_x16(uint8_t output[64*16], uint32_t state[16], size_t rounds)
-   {
-   BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
-   const SIMD_16x32 CTR0 = SIMD_16x32(
-      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
-
-   const uint32_t C = 0xFFFFFFFF - state[12];
-   const SIMD_16x32 CTR1 = SIMD_16x32(
-      0, C < 1, C < 2, C < 3, C < 4, C < 5, C < 6, C < 7,
-      C < 8, C < 9, C < 10, C < 11, C < 12, C < 13, C < 14, C < 15
-      );
-
-   SIMD_16x32 R00 = SIMD_16x32::splat(state[ 0]);
-   SIMD_16x32 R01 = SIMD_16x32::splat(state[ 1]);
-   SIMD_16x32 R02 = SIMD_16x32::splat(state[ 2]);
-   SIMD_16x32 R03 = SIMD_16x32::splat(state[ 3]);
-   SIMD_16x32 R04 = SIMD_16x32::splat(state[ 4]);
-   SIMD_16x32 R05 = SIMD_16x32::splat(state[ 5]);
-   SIMD_16x32 R06 = SIMD_16x32::splat(state[ 6]);
-   SIMD_16x32 R07 = SIMD_16x32::splat(state[ 7]);
-   SIMD_16x32 R08 = SIMD_16x32::splat(state[ 8]);
-   SIMD_16x32 R09 = SIMD_16x32::splat(state[ 9]);
-   SIMD_16x32 R10 = SIMD_16x32::splat(state[10]);
-   SIMD_16x32 R11 = SIMD_16x32::splat(state[11]);
-   SIMD_16x32 R12 = SIMD_16x32::splat(state[12]) + CTR0;
-   SIMD_16x32 R13 = SIMD_16x32::splat(state[13]) + CTR1;
-   SIMD_16x32 R14 = SIMD_16x32::splat(state[14]);
-   SIMD_16x32 R15 = SIMD_16x32::splat(state[15]);
-
-   for(size_t r = 0; r != rounds / 2; ++r)
-      {
-      R00 += R04;
-      R01 += R05;
-      R02 += R06;
-      R03 += R07;
-
-      R12 ^= R00;
-      R13 ^= R01;
-      R14 ^= R02;
-      R15 ^= R03;
-
-      R12 = R12.rotl<16>();
-      R13 = R13.rotl<16>();
-      R14 = R14.rotl<16>();
-      R15 = R15.rotl<16>();
-
-      R08 += R12;
-      R09 += R13;
-      R10 += R14;
-      R11 += R15;
-
-      R04 ^= R08;
-      R05 ^= R09;
-      R06 ^= R10;
-      R07 ^= R11;
-
-      R04 = R04.rotl<12>();
-      R05 = R05.rotl<12>();
-      R06 = R06.rotl<12>();
-      R07 = R07.rotl<12>();
-
-      R00 += R04;
-      R01 += R05;
-      R02 += R06;
-      R03 += R07;
-
-      R12 ^= R00;
-      R13 ^= R01;
-      R14 ^= R02;
-      R15 ^= R03;
-
-      R12 = R12.rotl<8>();
-      R13 = R13.rotl<8>();
-      R14 = R14.rotl<8>();
-      R15 = R15.rotl<8>();
-
-      R08 += R12;
-      R09 += R13;
-      R10 += R14;
-      R11 += R15;
-
-      R04 ^= R08;
-      R05 ^= R09;
-      R06 ^= R10;
-      R07 ^= R11;
-
-      R04 = R04.rotl<7>();
-      R05 = R05.rotl<7>();
-      R06 = R06.rotl<7>();
-      R07 = R07.rotl<7>();
-
-      R00 += R05;
-      R01 += R06;
-      R02 += R07;
-      R03 += R04;
-
-      R15 ^= R00;
-      R12 ^= R01;
-      R13 ^= R02;
-      R14 ^= R03;
-
-      R15 = R15.rotl<16>();
-      R12 = R12.rotl<16>();
-      R13 = R13.rotl<16>();
-      R14 = R14.rotl<16>();
-
-      R10 += R15;
-      R11 += R12;
-      R08 += R13;
-      R09 += R14;
-
-      R05 ^= R10;
-      R06 ^= R11;
-      R07 ^= R08;
-      R04 ^= R09;
-
-      R05 = R05.rotl<12>();
-      R06 = R06.rotl<12>();
-      R07 = R07.rotl<12>();
-      R04 = R04.rotl<12>();
-
-      R00 += R05;
-      R01 += R06;
-      R02 += R07;
-      R03 += R04;
-
-      R15 ^= R00;
-      R12 ^= R01;
-      R13 ^= R02;
-      R14 ^= R03;
-
-      R15 = R15.rotl<8>();
-      R12 = R12.rotl<8>();
-      R13 = R13.rotl<8>();
-      R14 = R14.rotl<8>();
-
-      R10 += R15;
-      R11 += R12;
-      R08 += R13;
-      R09 += R14;
-
-      R05 ^= R10;
-      R06 ^= R11;
-      R07 ^= R08;
-      R04 ^= R09;
-
-      R05 = R05.rotl<7>();
-      R06 = R06.rotl<7>();
-      R07 = R07.rotl<7>();
-      R04 = R04.rotl<7>();
-      }
-
-   R00 += SIMD_16x32::splat(state[0]);
-   R01 += SIMD_16x32::splat(state[1]);
-   R02 += SIMD_16x32::splat(state[2]);
-   R03 += SIMD_16x32::splat(state[3]);
-   R04 += SIMD_16x32::splat(state[4]);
-   R05 += SIMD_16x32::splat(state[5]);
-   R06 += SIMD_16x32::splat(state[6]);
-   R07 += SIMD_16x32::splat(state[7]);
-   R08 += SIMD_16x32::splat(state[8]);
-   R09 += SIMD_16x32::splat(state[9]);
-   R10 += SIMD_16x32::splat(state[10]);
-   R11 += SIMD_16x32::splat(state[11]);
-   R12 += SIMD_16x32::splat(state[12]) + CTR0;
-   R13 += SIMD_16x32::splat(state[13]) + CTR1;
-   R14 += SIMD_16x32::splat(state[14]);
-   R15 += SIMD_16x32::splat(state[15]);
-
-   SIMD_16x32::transpose(
-      R00, R01, R02, R03,
-      R04, R05, R06, R07,
-      R08, R09, R10, R11,
-      R12, R13, R14, R15);
-
-   R00.store_le(output);
-   R01.store_le(output + 64*1);
-   R02.store_le(output + 64*2);
-   R03.store_le(output + 64*3);
-   R04.store_le(output + 64*4);
-   R05.store_le(output + 64*5);
-   R06.store_le(output + 64*6);
-   R07.store_le(output + 64*7);
-   R08.store_le(output + 64*8);
-   R09.store_le(output + 64*9);
-   R10.store_le(output + 64*10);
-   R11.store_le(output + 64*11);
-   R12.store_le(output + 64*12);
-   R13.store_le(output + 64*13);
-   R14.store_le(output + 64*14);
-   R15.store_le(output + 64*15);
-
-   SIMD_16x32::zero_registers();
-
-   state[12] += 16;
-   if(state[12] < 16)
-      state[13]++;
-   }
-}
diff --git a/src/lib/stream/chacha/chacha_avx512/info.txt b/src/lib/stream/chacha/chacha_avx512/info.txt
deleted file mode 100644
index 84385bd98..000000000
--- a/src/lib/stream/chacha/chacha_avx512/info.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-<defines>
-CHACHA_AVX512 -> 20230101
-</defines>
-
-<module_info>
-name -> "ChaCha20 AVX512"
-brief -> "ChaCha20 using AVX512 instructions"
-</module_info>
-
-<isa>
-avx512
-</isa>
-
-<requires>
-simd_avx512
-</requires>
diff --git a/src/lib/tls/asio/asio_async_ops.h b/src/lib/tls/asio/asio_async_ops.h
index 4d2d12fe9..47267a569 100644
--- a/src/lib/tls/asio/asio_async_ops.h
+++ b/src/lib/tls/asio/asio_async_ops.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_ASIO_ASYNC_OPS_H_
 #define BOTAN_ASIO_ASYNC_OPS_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 #include <boost/version.hpp>
 #if BOOST_VERSION >= 106600
diff --git a/src/lib/tls/asio/asio_context.h b/src/lib/tls/asio/asio_context.h
index 6db1a1bba..4c1160661 100644
--- a/src/lib/tls/asio/asio_context.h
+++ b/src/lib/tls/asio/asio_context.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_ASIO_TLS_CONTEXT_H_
 #define BOTAN_ASIO_TLS_CONTEXT_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 #include <boost/version.hpp>
 #if BOOST_VERSION >= 106600
diff --git a/src/lib/tls/asio/asio_error.h b/src/lib/tls/asio/asio_error.h
index cf866e929..c860ded4c 100644
--- a/src/lib/tls/asio/asio_error.h
+++ b/src/lib/tls/asio/asio_error.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_ASIO_ERROR_H_
 #define BOTAN_ASIO_ERROR_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 #include <boost/version.hpp>
 #if BOOST_VERSION >= 106600
diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h
index a02309249..0c0de114f 100644
--- a/src/lib/tls/asio/asio_stream.h
+++ b/src/lib/tls/asio/asio_stream.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_ASIO_STREAM_H_
 #define BOTAN_ASIO_STREAM_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 // first version to be compatible with Networking TS (N4656) and boost::beast
 #include <boost/version.hpp>
diff --git a/src/lib/tls/tls12/msg_client_kex.cpp b/src/lib/tls/tls12/msg_client_kex.cpp
index ba8347c48..17fc44af9 100644
--- a/src/lib/tls/tls12/msg_client_kex.cpp
+++ b/src/lib/tls/tls12/msg_client_kex.cpp
@@ -289,25 +289,33 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents,
               kex_algo == Kex_Algo::ECDH ||
               kex_algo == Kex_Algo::ECDHE_PSK)
          {
-         const PK_Key_Agreement_Key& ka_key = state.server_kex()->server_kex_key();
+         const Private_Key& private_key = state.server_kex()->server_kex_key();
 
-         const std::vector<uint8_t> client_pubkey =
-            (ka_key.algo_name() == "DH") ? reader.get_range<uint8_t>(2, 0, 65535)
-                                         : reader.get_range<uint8_t>(1, 1, 255);
+         const PK_Key_Agreement_Key* ka_key =
+            dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
 
-         const auto shared_group = state.server_kex()->shared_group();
-         BOTAN_STATE_CHECK(shared_group && shared_group.value() != Group_Params::NONE);
+         if(!ka_key)
+            throw Internal_Error("Expected key agreement key type but got " +
+                                 private_key.algo_name());
+
+         std::vector<uint8_t> client_pubkey;
+
+         if(ka_key->algo_name() == "DH")
+            {
+            client_pubkey = reader.get_range<uint8_t>(2, 0, 65535);
+            }
+         else
+            {
+            client_pubkey = reader.get_range<uint8_t>(1, 1, 255);
+            }
 
          try
             {
-            auto shared_secret =
-               state.callbacks().tls_ephemeral_key_agreement(shared_group.value(),
-                                                             ka_key,
-                                                             client_pubkey,
-                                                             rng,
-                                                             policy);
+            PK_Key_Agreement ka(*ka_key, rng, "Raw");
+
+            secure_vector<uint8_t> shared_secret = ka.derive_key(0, client_pubkey).bits_of();
 
-            if(ka_key.algo_name() == "DH")
+            if(ka_key->algo_name() == "DH")
                shared_secret = CT::strip_leading_zeros(shared_secret);
 
             if(kex_algo == Kex_Algo::ECDHE_PSK)
@@ -330,7 +338,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents,
             * failure condition, randomize the pre-master output and carry on,
             * allowing the protocol to fail later in the finished checks.
             */
-            rng.random_vec(m_pre_master, ka_key.public_value().size());
+            rng.random_vec(m_pre_master, ka_key->public_value().size());
             }
 
          reader.assert_done();
diff --git a/src/lib/tls/tls12/msg_server_kex.cpp b/src/lib/tls/tls12/msg_server_kex.cpp
index 65f2fd73b..796beb0c4 100644
--- a/src/lib/tls/tls12/msg_server_kex.cpp
+++ b/src/lib/tls/tls12/msg_server_kex.cpp
@@ -51,7 +51,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
       {
       const std::vector<Group_Params> dh_groups = state.client_hello()->supported_dh_groups();
 
-      m_shared_group = Group_Params::NONE;
+      Group_Params shared_group = Group_Params::NONE;
 
       /*
       If the client does not send any DH groups in the supported groups
@@ -60,28 +60,20 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
 
       if(dh_groups.empty())
          {
-         m_shared_group = policy.default_dh_group();
+         shared_group = policy.default_dh_group();
          }
       else
          {
-         m_shared_group = policy.choose_key_exchange_group(dh_groups, {});
+         shared_group = policy.choose_key_exchange_group(dh_groups, {});
          }
 
-      if(m_shared_group.value() == Group_Params::NONE)
+      if(shared_group == Group_Params::NONE)
          throw TLS_Exception(Alert::HandshakeFailure,
                "Could not agree on a DH group with the client");
 
-      BOTAN_ASSERT(group_param_is_dh(m_shared_group.value()), "DH ciphersuite is using a finite field group");
-
-      // Note: TLS 1.2 allows defining and using arbitrary DH groups (additional
-      //       to the named and standardized ones). This API doesn't allow the
-      //       server to make use of that at the moment. TLS 1.3 does not
-      //       provide this flexibility!
-      //
-      // A possible implementation strategy in case one would ever need that:
-      // `Policy::default_dh_group()` could return a `std::variant<Group_Params,
-      // DL_Group>`, allowing it to define arbitrary groups.
-      m_kex_key = state.callbacks().tls_generate_ephemeral_key(m_shared_group.value(), rng);
+      BOTAN_ASSERT(group_param_is_dh(shared_group), "DH groups for the DH ciphersuites god");
+
+      m_kex_key = state.callbacks().tls_generate_ephemeral_key(shared_group, rng);
       auto dh = dynamic_cast<DH_PrivateKey*>(m_kex_key.get());
       if(!dh)
          {
@@ -99,16 +91,16 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
       if(ec_groups.empty())
          throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
 
-      m_shared_group = policy.choose_key_exchange_group(ec_groups, {});
+      Group_Params shared_group = policy.choose_key_exchange_group(ec_groups, {});
 
-      if(m_shared_group.value() == Group_Params::NONE)
+      if(shared_group == Group_Params::NONE)
          throw TLS_Exception(Alert::HandshakeFailure, "No shared ECC group with client");
 
       std::vector<uint8_t> ecdh_public_val;
 
-      if(m_shared_group.value() == Group_Params::X25519)
+      if(shared_group == Group_Params::X25519)
          {
-         m_kex_key = state.callbacks().tls_generate_ephemeral_key(m_shared_group.value(), rng);
+         m_kex_key = state.callbacks().tls_generate_ephemeral_key(shared_group, rng);
          if(!m_kex_key)
             {
             throw TLS_Exception(Alert::InternalError,
@@ -118,7 +110,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
          }
       else
          {
-         m_kex_key = state.callbacks().tls_generate_ephemeral_key(m_shared_group.value(), rng);
+         m_kex_key = state.callbacks().tls_generate_ephemeral_key(shared_group, rng);
          auto ecdh = dynamic_cast<ECDH_PrivateKey*>(m_kex_key.get());
          if(!ecdh)
             {
@@ -131,7 +123,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
             EC_Point_Format::Compressed : EC_Point_Format::Uncompressed);
          }
 
-      const uint16_t named_curve_id = static_cast<uint16_t>(m_shared_group.value());
+      const uint16_t named_curve_id = static_cast<uint16_t>(shared_group);
       m_params.push_back(3); // named curve
       m_params.push_back(get_byte<0>(named_curve_id));
       m_params.push_back(get_byte<1>(named_curve_id));
@@ -266,7 +258,7 @@ bool Server_Key_Exchange::verify(const Public_Key& server_key,
 #endif
    }
 
-const PK_Key_Agreement_Key& Server_Key_Exchange::server_kex_key() const
+const Private_Key& Server_Key_Exchange::server_kex_key() const
    {
    BOTAN_ASSERT_NONNULL(m_kex_key);
    return *m_kex_key;
diff --git a/src/lib/tls/tls13/msg_certificate_13.cpp b/src/lib/tls/tls13/msg_certificate_13.cpp
index d0fe77a67..fc136332e 100644
--- a/src/lib/tls/tls13/msg_certificate_13.cpp
+++ b/src/lib/tls/tls13/msg_certificate_13.cpp
@@ -110,7 +110,9 @@ void Certificate_13::verify(Callbacks& callbacks,
             }
          else
             {
-            ocsp_responses.push_back(std::nullopt);
+            // Note: The make_optional instead of simply nullopt is necessary to work around a GCC <= 10.0 bug
+            //       see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
+            ocsp_responses.push_back(std::make_optional<OCSP::Response>());
             }
          }
       }
@@ -122,9 +124,8 @@ void Certificate_13::verify(Callbacks& callbacks,
                           "Certificate usage constraints do not allow signing");
       }
 
-   // Note that m_side represents the sender, so the usages here are swapped
    const auto trusted_CAs = creds.trusted_certificate_authorities(
-                                     m_side == Connection_Side::Client ? "tls-server" : "tls-client",
+                                     m_side == Connection_Side::Client ? "tls-client" : "tls-server",
                                      std::string(hostname));
 
    const auto usage = (m_side == Connection_Side::Client) ? Usage_Type::TLS_CLIENT_AUTH : Usage_Type::TLS_SERVER_AUTH;
diff --git a/src/lib/tls/tls13/tls_client_impl_13.cpp b/src/lib/tls/tls13/tls_client_impl_13.cpp
index fed03c2c7..83198b193 100644
--- a/src/lib/tls/tls13/tls_client_impl_13.cpp
+++ b/src/lib/tls/tls13/tls_client_impl_13.cpp
@@ -15,7 +15,7 @@
 #include <botan/internal/tls_cipher_state.h>
 #include <botan/tls_client.h>
 #include <botan/tls_messages.h>
-#include <botan/types.h>
+#include <botan/build.h>
 
 #include <iterator>
 #include <utility>
diff --git a/src/lib/tls/tls13/tls_ticket_13.h b/src/lib/tls/tls13/tls_ticket_13.h
index aa1dca0a9..325a17763 100644
--- a/src/lib/tls/tls13/tls_ticket_13.h
+++ b/src/lib/tls/tls13/tls_ticket_13.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_TLS_13_TICKET_H_
 #define BOTAN_TLS_13_TICKET_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include <botan/tls_session.h>
 
 #include <chrono>
diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h
index 454cd8f38..fa017e557 100644
--- a/src/lib/tls/tls_messages.h
+++ b/src/lib/tls/tls_messages.h
@@ -871,13 +871,7 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message
                   const Policy& policy) const;
 
       // Only valid for certain kex types
-      const PK_Key_Agreement_Key& server_kex_key() const;
-
-      /**
-       * @returns the agreed upon KEX group or std::nullopt if the KEX type does
-       *          not depend on a group
-       */
-      const std::optional<Group_Params>& shared_group() const { return m_shared_group; }
+      const Private_Key& server_kex_key() const;
 
       Server_Key_Exchange(Handshake_IO& io,
                           Handshake_State& state,
@@ -895,7 +889,6 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message
       std::vector<uint8_t> serialize() const override;
 
       std::unique_ptr<PK_Key_Agreement_Key> m_kex_key;
-      std::optional<Group_Params> m_shared_group;
 
       std::vector<uint8_t> m_params;
 
diff --git a/src/lib/tls/tls_session_manager.h b/src/lib/tls/tls_session_manager.h
index 2a77f344b..d70730c4c 100644
--- a/src/lib/tls/tls_session_manager.h
+++ b/src/lib/tls/tls_session_manager.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_TLS_SESSION_MANAGER_H_
 #define BOTAN_TLS_SESSION_MANAGER_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include <botan/tls_session.h>
 #include <botan/mutex.h>
 
diff --git a/src/lib/utils/assert.h b/src/lib/utils/assert.h
index fe08c4989..f1c3274ec 100644
--- a/src/lib/utils/assert.h
+++ b/src/lib/utils/assert.h
@@ -9,7 +9,7 @@
 #ifndef BOTAN_ASSERTION_CHECKING_H_
 #define BOTAN_ASSERTION_CHECKING_H_
 
-#include <botan/compiler.h>
+#include <botan/build.h>
 
 namespace Botan {
 
@@ -124,21 +124,32 @@ namespace Botan {
 #endif
 
 /**
-* Mark variable as unused.
-*
-* Takes any number of arguments and marks all as unused, for instance
-* BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z);
+* Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused,
+* e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z);
 */
-template<typename T>
-void ignore_param(T&&) {}
-
-template<typename... T>
-void ignore_params(T&&... args)
-   {
-   (ignore_param(args) , ...);
-   }
-
-#define BOTAN_UNUSED Botan::ignore_params
+#define _BOTAN_UNUSED_IMPL1(a)                         static_cast<void>(a)
+#define _BOTAN_UNUSED_IMPL2(a, b)                      static_cast<void>(a); _BOTAN_UNUSED_IMPL1(b)
+#define _BOTAN_UNUSED_IMPL3(a, b, c)                   static_cast<void>(a); _BOTAN_UNUSED_IMPL2(b, c)
+#define _BOTAN_UNUSED_IMPL4(a, b, c, d)                static_cast<void>(a); _BOTAN_UNUSED_IMPL3(b, c, d)
+#define _BOTAN_UNUSED_IMPL5(a, b, c, d, e)             static_cast<void>(a); _BOTAN_UNUSED_IMPL4(b, c, d, e)
+#define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f)          static_cast<void>(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f)
+#define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g)       static_cast<void>(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g)
+#define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h)    static_cast<void>(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h)
+#define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast<void>(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i)
+#define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME
+
+#define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__,                      \
+                                                 _BOTAN_UNUSED_IMPL9,              \
+                                                 _BOTAN_UNUSED_IMPL8,              \
+                                                 _BOTAN_UNUSED_IMPL7,              \
+                                                 _BOTAN_UNUSED_IMPL6,              \
+                                                 _BOTAN_UNUSED_IMPL5,              \
+                                                 _BOTAN_UNUSED_IMPL4,              \
+                                                 _BOTAN_UNUSED_IMPL3,              \
+                                                 _BOTAN_UNUSED_IMPL2,              \
+                                                 _BOTAN_UNUSED_IMPL1,              \
+                                                 unused dummy rest value           \
+                          ) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__)
 
 /*
 * Define Botan::unreachable()
diff --git a/src/lib/utils/compiler.h b/src/lib/utils/compiler.h
index bf8bcca9a..96bcaeeb1 100644
--- a/src/lib/utils/compiler.h
+++ b/src/lib/utils/compiler.h
@@ -5,10 +5,21 @@
 * Botan is released under the Simplified BSD License (see license.txt)
 */
 
+/* This header is included in both C++ and C (via ffi.h) and should only
+   contain macro definitions. Avoid C++ style // comments in this file.
+*/
+
 #ifndef BOTAN_UTIL_COMPILER_FLAGS_H_
 #define BOTAN_UTIL_COMPILER_FLAGS_H_
 
-#include <botan/build.h>
+/* Should we use GCC-style inline assembler? */
+#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || \
+   defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \
+   defined(BOTAN_BUILD_COMPILER_IS_XLC) || \
+   defined(BOTAN_BUILD_COMPILER_IS_SUN_STUDIO)
+
+  #define BOTAN_USE_GCC_INLINE_ASM
+#endif
 
 /**
 * Used to annotate API exports which are public and supported.
@@ -106,7 +117,13 @@
 */
 #if !defined(BOTAN_NO_DEPRECATED_WARNINGS) && !defined(BOTAN_AMALGAMATION_H_)
 
-  #define BOTAN_DEPRECATED(msg) [[deprecated(msg)]]
+  #if defined(__cplusplus)
+    #define BOTAN_DEPRECATED(msg) [[deprecated(msg)]]
+  #elif BOTAN_COMPILER_HAS_ATTRIBUTE(deprecated)
+    #define BOTAN_DEPRECATED(msg) BOTAN_COMPILER_ATTRIBUTE(deprecated(msg))
+  #elif defined(_MSC_VER)
+    #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg))
+  #endif
 
   #if !defined(BOTAN_IS_BEING_BUILT)
     #if defined(__clang__)
diff --git a/src/lib/utils/cpuid/cpuid.cpp b/src/lib/utils/cpuid/cpuid.cpp
index 221ad000d..cd2f62c21 100644
--- a/src/lib/utils/cpuid/cpuid.cpp
+++ b/src/lib/utils/cpuid/cpuid.cpp
@@ -144,19 +144,6 @@ CPUID::CPUID_Data::CPUID_Data()
 
    if(runtime_check_if_big_endian())
       m_processor_features |= CPUID::CPUID_IS_BIG_ENDIAN_BIT;
-
-   std::string clear_cpuid_env;
-   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID"))
-      {
-      for(const auto& cpuid : split_on(clear_cpuid_env, ','))
-         {
-         for(auto& bit: CPUID::bit_from_string(cpuid))
-            {
-            const uint32_t cleared = ~static_cast<uint32_t>(bit);
-            m_processor_features &= cleared;
-            }
-         }
-      }
    }
 
 std::vector<CPUID::CPUID_bits>
diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h
index f6cd96c81..633077014 100644
--- a/src/lib/utils/cpuid/cpuid.h
+++ b/src/lib/utils/cpuid/cpuid.h
@@ -138,7 +138,7 @@ class BOTAN_TEST_API CPUID final
       * Check if the processor supports POWER8 crypto extensions
       */
       static bool has_power_crypto()
-         { return has_altivec() && has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
+         { return has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
 
       /**
       * Check if the processor supports POWER9 DARN RNG
@@ -165,49 +165,49 @@ class BOTAN_TEST_API CPUID final
       * Check if the processor supports ARMv8 SHA1
       */
       static bool has_arm_sha1()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
 
       /**
       * Check if the processor supports ARMv8 SHA2
       */
       static bool has_arm_sha2()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
 
       /**
       * Check if the processor supports ARMv8 AES
       */
       static bool has_arm_aes()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_AES_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_AES_BIT); }
 
       /**
       * Check if the processor supports ARMv8 PMULL
       */
       static bool has_arm_pmull()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
 
       /**
       * Check if the processor supports ARMv8 SHA-512
       */
       static bool has_arm_sha2_512()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
 
       /**
       * Check if the processor supports ARMv8 SHA-3
       */
       static bool has_arm_sha3()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
 
       /**
       * Check if the processor supports ARMv8 SM3
       */
       static bool has_arm_sm3()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SM3_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SM3_BIT); }
 
       /**
       * Check if the processor supports ARMv8 SM4
       */
       static bool has_arm_sm4()
-         { return has_neon() && has_cpuid_bit(CPUID_ARM_SM4_BIT); }
+         { return has_cpuid_bit(CPUID_ARM_SM4_BIT); }
 
 #endif
 
@@ -229,7 +229,7 @@ class BOTAN_TEST_API CPUID final
       * Check if the processor supports SSSE3
       */
       static bool has_ssse3()
-         { return has_sse2() && has_cpuid_bit(CPUID_SSSE3_BIT); }
+         { return has_cpuid_bit(CPUID_SSSE3_BIT); }
 
       /**
       * Check if the processor supports AVX2
@@ -249,13 +249,13 @@ class BOTAN_TEST_API CPUID final
       * Check if the processor supports AVX-512 AES (VAES)
       */
       static bool has_avx512_aes()
-         { return has_avx512() && has_cpuid_bit(CPUID_AVX512_AES_BIT); }
+         { return has_cpuid_bit(CPUID_AVX512_AES_BIT); }
 
       /**
       * Check if the processor supports AVX-512 VPCLMULQDQ
       */
       static bool has_avx512_clmul()
-         { return has_avx512() && has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
+         { return has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
 
       /**
       * Check if the processor supports BMI2 (and BMI1)
@@ -267,19 +267,19 @@ class BOTAN_TEST_API CPUID final
       * Check if the processor supports AES-NI
       */
       static bool has_aes_ni()
-         { return has_ssse3() && has_cpuid_bit(CPUID_AESNI_BIT); }
+         { return has_cpuid_bit(CPUID_AESNI_BIT); }
 
       /**
       * Check if the processor supports CLMUL
       */
       static bool has_clmul()
-         { return has_ssse3() && has_cpuid_bit(CPUID_CLMUL_BIT); }
+         { return has_cpuid_bit(CPUID_CLMUL_BIT); }
 
       /**
       * Check if the processor supports Intel SHA extension
       */
       static bool has_intel_sha()
-         { return has_sse2() && has_cpuid_bit(CPUID_SHA_BIT); }
+         { return has_cpuid_bit(CPUID_SHA_BIT); }
 
       /**
       * Check if the processor supports ADX extension
diff --git a/src/lib/utils/cpuid/cpuid_x86.cpp b/src/lib/utils/cpuid/cpuid_x86.cpp
index ca63c4361..39b6f847f 100644
--- a/src/lib/utils/cpuid/cpuid_x86.cpp
+++ b/src/lib/utils/cpuid/cpuid_x86.cpp
@@ -203,14 +203,12 @@ uint32_t CPUID::CPUID_Data::detect_cpu_features()
          bought such a processor.
          */
          if((flags7 & AVX512_PROFILE_FLAGS) == AVX512_PROFILE_FLAGS)
-            {
             features_detected |= CPUID::CPUID_AVX512_BIT;
 
-            if(flags7 & x86_CPUID_7_bits::AVX512_VAES)
-               features_detected |= CPUID::CPUID_AVX512_AES_BIT;
-            if(flags7 & x86_CPUID_7_bits::AVX512_VCLMUL)
-               features_detected |= CPUID::CPUID_AVX512_CLMUL_BIT;
-            }
+         if(flags7 & x86_CPUID_7_bits::AVX512_VAES)
+            features_detected |= CPUID::CPUID_AVX512_AES_BIT;
+         if(flags7 & x86_CPUID_7_bits::AVX512_VCLMUL)
+            features_detected |= CPUID::CPUID_AVX512_CLMUL_BIT;
          }
       }
 
diff --git a/src/lib/utils/mul128.h b/src/lib/utils/mul128.h
index 9fc88b014..39bf8e104 100644
--- a/src/lib/utils/mul128.h
+++ b/src/lib/utils/mul128.h
@@ -12,6 +12,11 @@
 
 #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
   #include <intrin.h>
+  #if defined(_M_ARM64)
+  #pragma intrinsic(__umulh)
+  #else
+  #pragma intrinsic(_umul128)
+  #endif
 #endif
 
 namespace Botan {
@@ -19,8 +24,12 @@ namespace Botan {
 #if defined(__SIZEOF_INT128__) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
    #define BOTAN_TARGET_HAS_NATIVE_UINT128
 
-   // GCC complains if this isn't marked with __extension__
-   __extension__ typedef unsigned __int128 uint128_t;
+   // Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode
+   #if defined(__GNUG__)
+     typedef unsigned int uint128_t __attribute__((mode(TI)));
+   #else
+     typedef unsigned __int128 uint128_t;
+   #endif
 #endif
 
 /**
@@ -34,12 +43,13 @@ inline void mul64x64_128(uint64_t a, uint64_t b, uint64_t* lo, uint64_t* hi)
    *hi = (r >> 64) & 0xFFFFFFFFFFFFFFFF;
    *lo = (r      ) & 0xFFFFFFFFFFFFFFFF;
 
-#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_ARCH_IS_X86_64)
-    *lo = _umul128(a, b, hi);
-
-#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
+#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
+    #if defined(_M_ARM64)
     *lo = a * b;
     *hi = __umulh(a, b);
+    #else
+    *lo = _umul128(a, b, hi);
+    #endif
 
 #elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_X86_64)
    asm("mulq %3"
diff --git a/src/lib/utils/simd/simd_avx512/info.txt b/src/lib/utils/simd/simd_avx512/info.txt
deleted file mode 100644
index 60763e6ac..000000000
--- a/src/lib/utils/simd/simd_avx512/info.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-<defines>
-SIMD_AVX512 -> 20230101
-</defines>
-
-<module_info>
-name -> "AVX512"
-brief -> "Helpers for working with AVX512 instructions"
-</module_info>
-
-<isa>
-avx512
-</isa>
-
-<header:internal>
-simd_avx512.h
-</header:internal>
-
-<cc>
-gcc
-clang
-msvc
-</cc>
diff --git a/src/lib/utils/simd/simd_avx512/simd_avx512.h b/src/lib/utils/simd/simd_avx512/simd_avx512.h
deleted file mode 100644
index acbea144e..000000000
--- a/src/lib/utils/simd/simd_avx512/simd_avx512.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SIMD_AVX512_H_
-#define BOTAN_SIMD_AVX512_H_
-
-#include <botan/types.h>
-#include <immintrin.h>
-
-namespace Botan {
-
-#define BOTAN_AVX512_FN BOTAN_FUNC_ISA("avx512f,avx512dq,avx512bw")
-
-class SIMD_16x32 final
-   {
-   public:
-
-      SIMD_16x32& operator=(const SIMD_16x32& other) = default;
-      SIMD_16x32(const SIMD_16x32& other) = default;
-
-      SIMD_16x32& operator=(SIMD_16x32&& other) = default;
-      SIMD_16x32(SIMD_16x32&& other) = default;
-
-      BOTAN_AVX512_FN
-      BOTAN_FORCE_INLINE SIMD_16x32()
-         {
-         m_avx512 = _mm512_setzero_si512();
-         }
-
-      BOTAN_AVX512_FN
-      explicit SIMD_16x32(const uint32_t B[16])
-         {
-         m_avx512 = _mm512_loadu_si512(reinterpret_cast<const __m512i*>(B));
-         }
-
-      BOTAN_AVX512_FN
-      explicit SIMD_16x32(uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3,
-                          uint32_t B4, uint32_t B5, uint32_t B6, uint32_t B7,
-                          uint32_t B8, uint32_t B9, uint32_t BA, uint32_t BB,
-                          uint32_t BC, uint32_t BD, uint32_t BE, uint32_t BF)
-         {
-         m_avx512 = _mm512_set_epi32(
-            BF, BE, BD, BC, BB, BA, B9, B8,
-            B7, B6, B5, B4, B3, B2, B1, B0);
-         }
-
-      BOTAN_AVX512_FN
-      static SIMD_16x32 splat(uint32_t B)
-         {
-         return SIMD_16x32(_mm512_set1_epi32(B));
-         }
-
-      BOTAN_AVX512_FN
-      static SIMD_16x32 load_le(const uint8_t* in)
-         {
-         return SIMD_16x32(_mm512_loadu_si512(reinterpret_cast<const __m512i*>(in)));
-         }
-
-      BOTAN_AVX512_FN
-      static SIMD_16x32 load_be(const uint8_t* in)
-         {
-         return load_le(in).bswap();
-         }
-
-      BOTAN_AVX512_FN
-      void store_le(uint8_t out[]) const
-         {
-         _mm512_storeu_si512(reinterpret_cast<__m512i*>(out), m_avx512);
-         }
-
-      BOTAN_AVX512_FN
-      void store_be(uint8_t out[]) const
-         {
-         bswap().store_le(out);
-         }
-
-      template<size_t ROT>
-      BOTAN_AVX512_FN
-      SIMD_16x32 rotl() const
-         {
-         static_assert(ROT > 0 && ROT < 32, "Invalid rotation constant");
-         return SIMD_16x32(_mm512_rol_epi32(m_avx512, ROT));
-         }
-
-      template<size_t ROT>
-      BOTAN_AVX512_FN
-      SIMD_16x32 rotr() const
-         {
-         return this->rotl<32-ROT>();
-         }
-
-      SIMD_16x32 BOTAN_AVX512_FN sigma0() const
-         {
-         const SIMD_16x32 rot1 = this->rotr<2>();
-         const SIMD_16x32 rot2 = this->rotr<13>();
-         const SIMD_16x32 rot3 = this->rotr<22>();
-         return rot1 ^ rot2 ^ rot3;
-         }
-
-      SIMD_16x32 BOTAN_AVX512_FN sigma1() const
-         {
-         const SIMD_16x32 rot1 = this->rotr<6>();
-         const SIMD_16x32 rot2 = this->rotr<11>();
-         const SIMD_16x32 rot3 = this->rotr<25>();
-         return rot1 ^ rot2 ^ rot3;
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator+(const SIMD_16x32& other) const
-         {
-         SIMD_16x32 retval(*this);
-         retval += other;
-         return retval;
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator-(const SIMD_16x32& other) const
-         {
-         SIMD_16x32 retval(*this);
-         retval -= other;
-         return retval;
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator^(const SIMD_16x32& other) const
-         {
-         SIMD_16x32 retval(*this);
-         retval ^= other;
-         return retval;
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator|(const SIMD_16x32& other) const
-         {
-         SIMD_16x32 retval(*this);
-         retval |= other;
-         return retval;
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator&(const SIMD_16x32& other) const
-         {
-         SIMD_16x32 retval(*this);
-         retval &= other;
-         return retval;
-         }
-
-      BOTAN_AVX512_FN
-      void operator+=(const SIMD_16x32& other)
-         {
-         m_avx512 = _mm512_add_epi32(m_avx512, other.m_avx512);
-         }
-
-      BOTAN_AVX512_FN
-      void operator-=(const SIMD_16x32& other)
-         {
-         m_avx512 = _mm512_sub_epi32(m_avx512, other.m_avx512);
-         }
-
-      BOTAN_AVX512_FN
-      void operator^=(const SIMD_16x32& other)
-         {
-         m_avx512 = _mm512_xor_si512(m_avx512, other.m_avx512);
-         }
-
-      BOTAN_AVX512_FN
-      void operator^=(uint32_t other)
-         {
-         *this ^= SIMD_16x32::splat(other);
-         }
-
-      BOTAN_AVX512_FN
-      void operator|=(const SIMD_16x32& other)
-         {
-         m_avx512 = _mm512_or_si512(m_avx512, other.m_avx512);
-         }
-
-      BOTAN_AVX512_FN
-      void operator&=(const SIMD_16x32& other)
-         {
-         m_avx512 = _mm512_and_si512(m_avx512, other.m_avx512);
-         }
-
-      template<int SHIFT> BOTAN_AVX512_FN SIMD_16x32 shl() const
-         {
-         return SIMD_16x32(_mm512_slli_epi32(m_avx512, SHIFT));
-         }
-
-      template<int SHIFT> BOTAN_AVX512_FN SIMD_16x32 shr() const
-         {
-         return SIMD_16x32(_mm512_srli_epi32(m_avx512, SHIFT));
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 operator~() const
-         {
-         return SIMD_16x32(_mm512_xor_si512(m_avx512, _mm512_set1_epi32(0xFFFFFFFF)));
-         }
-
-      // (~reg) & other
-      BOTAN_AVX512_FN
-      SIMD_16x32 andc(const SIMD_16x32& other) const
-         {
-         return SIMD_16x32(_mm512_andnot_si512(m_avx512, other.m_avx512));
-         }
-
-      template<uint8_t TBL>
-      BOTAN_AVX512_FN
-      static SIMD_16x32 ternary_fn(const SIMD_16x32& a,
-                                   const SIMD_16x32& b,
-                                   const SIMD_16x32& c)
-         {
-         return _mm512_ternarylogic_epi32(a.raw(), b.raw(), c.raw(), TBL);
-         }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32 bswap() const
-         {
-         const uint8_t BSWAP_MASK[64] = {
-            3, 2, 1, 0,
-            7, 6, 5, 4,
-            11, 10, 9, 8,
-            15, 14, 13, 12,
-            19, 18, 17, 16,
-            23, 22, 21, 20,
-            27, 26, 25, 24,
-            31, 30, 29, 28,
-            35, 34, 33, 32,
-            39, 38, 37, 36,
-            43, 42, 41, 40,
-            47, 46, 45, 44,
-            51, 50, 49, 48,
-            55, 54, 53, 52,
-            59, 58, 57, 56,
-            63, 62, 61, 60,
-         };
-
-         const __m512i bswap = _mm512_loadu_si512(reinterpret_cast<const __m512i*>(BSWAP_MASK));
-
-         const __m512i output = _mm512_shuffle_epi8(m_avx512, bswap);
-
-         return SIMD_16x32(output);
-         }
-
-      BOTAN_AVX512_FN
-      static void transpose(SIMD_16x32& B0, SIMD_16x32& B1,
-                            SIMD_16x32& B2, SIMD_16x32& B3)
-         {
-         const __m512i T0 = _mm512_unpacklo_epi32(B0.m_avx512, B1.m_avx512);
-         const __m512i T1 = _mm512_unpacklo_epi32(B2.m_avx512, B3.m_avx512);
-         const __m512i T2 = _mm512_unpackhi_epi32(B0.m_avx512, B1.m_avx512);
-         const __m512i T3 = _mm512_unpackhi_epi32(B2.m_avx512, B3.m_avx512);
-
-         B0.m_avx512 = _mm512_unpacklo_epi64(T0, T1);
-         B1.m_avx512 = _mm512_unpackhi_epi64(T0, T1);
-         B2.m_avx512 = _mm512_unpacklo_epi64(T2, T3);
-         B3.m_avx512 = _mm512_unpackhi_epi64(T2, T3);
-         }
-
-      BOTAN_AVX512_FN
-      static void transpose(SIMD_16x32& B0, SIMD_16x32& B1,
-                            SIMD_16x32& B2, SIMD_16x32& B3,
-                            SIMD_16x32& B4, SIMD_16x32& B5,
-                            SIMD_16x32& B6, SIMD_16x32& B7,
-                            SIMD_16x32& B8, SIMD_16x32& B9,
-                            SIMD_16x32& BA, SIMD_16x32& BB,
-                            SIMD_16x32& BC, SIMD_16x32& BD,
-                            SIMD_16x32& BE, SIMD_16x32& BF)
-         {
-         auto t0 = _mm512_unpacklo_epi32(B0.raw(), B1.raw());
-         auto t1 = _mm512_unpackhi_epi32(B0.raw(), B1.raw());
-         auto t2 = _mm512_unpacklo_epi32(B2.raw(), B3.raw());
-         auto t3 = _mm512_unpackhi_epi32(B2.raw(), B3.raw());
-         auto t4 = _mm512_unpacklo_epi32(B4.raw(), B5.raw());
-         auto t5 = _mm512_unpackhi_epi32(B4.raw(), B5.raw());
-         auto t6 = _mm512_unpacklo_epi32(B6.raw(), B7.raw());
-         auto t7 = _mm512_unpackhi_epi32(B6.raw(), B7.raw());
-         auto t8 = _mm512_unpacklo_epi32(B8.raw(), B9.raw());
-         auto t9 = _mm512_unpackhi_epi32(B8.raw(), B9.raw());
-         auto ta = _mm512_unpacklo_epi32(BA.raw(), BB.raw());
-         auto tb = _mm512_unpackhi_epi32(BA.raw(), BB.raw());
-         auto tc = _mm512_unpacklo_epi32(BC.raw(), BD.raw());
-         auto td = _mm512_unpackhi_epi32(BC.raw(), BD.raw());
-         auto te = _mm512_unpacklo_epi32(BE.raw(), BF.raw());
-         auto tf = _mm512_unpackhi_epi32(BE.raw(), BF.raw());
-
-         auto r0 = _mm512_unpacklo_epi64(t0, t2);
-         auto r1 = _mm512_unpackhi_epi64(t0, t2);
-         auto r2 = _mm512_unpacklo_epi64(t1, t3);
-         auto r3 = _mm512_unpackhi_epi64(t1, t3);
-         auto r4 = _mm512_unpacklo_epi64(t4, t6);
-         auto r5 = _mm512_unpackhi_epi64(t4, t6);
-         auto r6 = _mm512_unpacklo_epi64(t5, t7);
-         auto r7 = _mm512_unpackhi_epi64(t5, t7);
-         auto r8 = _mm512_unpacklo_epi64(t8, ta);
-         auto r9 = _mm512_unpackhi_epi64(t8, ta);
-         auto ra = _mm512_unpacklo_epi64(t9, tb);
-         auto rb = _mm512_unpackhi_epi64(t9, tb);
-         auto rc = _mm512_unpacklo_epi64(tc, te);
-         auto rd = _mm512_unpackhi_epi64(tc, te);
-         auto re = _mm512_unpacklo_epi64(td, tf);
-         auto rf = _mm512_unpackhi_epi64(td, tf);
-
-         t0 = _mm512_shuffle_i32x4(r0, r4, 0x88);
-         t1 = _mm512_shuffle_i32x4(r1, r5, 0x88);
-         t2 = _mm512_shuffle_i32x4(r2, r6, 0x88);
-         t3 = _mm512_shuffle_i32x4(r3, r7, 0x88);
-         t4 = _mm512_shuffle_i32x4(r0, r4, 0xdd);
-         t5 = _mm512_shuffle_i32x4(r1, r5, 0xdd);
-         t6 = _mm512_shuffle_i32x4(r2, r6, 0xdd);
-         t7 = _mm512_shuffle_i32x4(r3, r7, 0xdd);
-         t8 = _mm512_shuffle_i32x4(r8, rc, 0x88);
-         t9 = _mm512_shuffle_i32x4(r9, rd, 0x88);
-         ta = _mm512_shuffle_i32x4(ra, re, 0x88);
-         tb = _mm512_shuffle_i32x4(rb, rf, 0x88);
-         tc = _mm512_shuffle_i32x4(r8, rc, 0xdd);
-         td = _mm512_shuffle_i32x4(r9, rd, 0xdd);
-         te = _mm512_shuffle_i32x4(ra, re, 0xdd);
-         tf = _mm512_shuffle_i32x4(rb, rf, 0xdd);
-
-         B0.m_avx512 = _mm512_shuffle_i32x4(t0, t8, 0x88);
-         B1.m_avx512 = _mm512_shuffle_i32x4(t1, t9, 0x88);
-         B2.m_avx512 = _mm512_shuffle_i32x4(t2, ta, 0x88);
-         B3.m_avx512 = _mm512_shuffle_i32x4(t3, tb, 0x88);
-         B4.m_avx512 = _mm512_shuffle_i32x4(t4, tc, 0x88);
-         B5.m_avx512 = _mm512_shuffle_i32x4(t5, td, 0x88);
-         B6.m_avx512 = _mm512_shuffle_i32x4(t6, te, 0x88);
-         B7.m_avx512 = _mm512_shuffle_i32x4(t7, tf, 0x88);
-         B8.m_avx512 = _mm512_shuffle_i32x4(t0, t8, 0xdd);
-         B9.m_avx512 = _mm512_shuffle_i32x4(t1, t9, 0xdd);
-         BA.m_avx512 = _mm512_shuffle_i32x4(t2, ta, 0xdd);
-         BB.m_avx512 = _mm512_shuffle_i32x4(t3, tb, 0xdd);
-         BC.m_avx512 = _mm512_shuffle_i32x4(t4, tc, 0xdd);
-         BD.m_avx512 = _mm512_shuffle_i32x4(t5, td, 0xdd);
-         BE.m_avx512 = _mm512_shuffle_i32x4(t6, te, 0xdd);
-         BF.m_avx512 = _mm512_shuffle_i32x4(t7, tf, 0xdd);
-         }
-
-      BOTAN_AVX512_FN
-      static SIMD_16x32 choose(const SIMD_16x32& mask, const SIMD_16x32& a, const SIMD_16x32& b)
-         {
-         return SIMD_16x32::ternary_fn<0xca>(mask, a, b);
-         }
-
-      BOTAN_AVX512_FN
-      static SIMD_16x32 majority(const SIMD_16x32& x, const SIMD_16x32& y, const SIMD_16x32& z)
-         {
-         return SIMD_16x32::ternary_fn<0xe8>(x, y, z);
-         }
-
-      BOTAN_FUNC_ISA("avx2")
-      static void zero_registers()
-         {
-         // Unfortunately this only zeros zmm0-zmm15 and not zmm16-zmm32
-         _mm256_zeroall();
-         }
-
-      __m512i BOTAN_AVX512_FN raw() const { return m_avx512; }
-
-      BOTAN_AVX512_FN
-      SIMD_16x32(__m512i x) : m_avx512(x) {}
-
-   private:
-      __m512i m_avx512;
-   };
-
-template<size_t R>
-inline SIMD_16x32 rotl(SIMD_16x32 input)
-   {
-   return input.rotl<R>();
-   }
-
-template<size_t R>
-inline SIMD_16x32 rotr(SIMD_16x32 input)
-   {
-   return input.rotr<R>();
-   }
-
-// For Serpent:
-template<size_t S>
-inline SIMD_16x32 shl(SIMD_16x32 input)
-   {
-   return input.shl<S>();
-   }
-
-}
-
-#endif
diff --git a/src/lib/utils/types.h b/src/lib/utils/types.h
index b89c083b3..55240d88b 100644
--- a/src/lib/utils/types.h
+++ b/src/lib/utils/types.h
@@ -11,7 +11,6 @@
 #define BOTAN_TYPES_H_
 
 #include <botan/build.h> // IWYU pragma: export
-#include <botan/compiler.h> // IWYU pragma: export
 #include <botan/assert.h> // IWYU pragma: export
 #include <cstddef> // IWYU pragma: export
 #include <cstdint> // IWYU pragma: export
diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp
index 5ef06d752..ab3e76a86 100644
--- a/src/lib/x509/ocsp.cpp
+++ b/src/lib/x509/ocsp.cpp
@@ -147,34 +147,11 @@ Response::Response(const uint8_t response_bits[], size_t response_bits_len) :
 
          .decode_optional(extensions, ASN1_Type(1),
                           ASN1_Class::ContextSpecific | ASN1_Class::Constructed);
-
-      const bool has_signer = !m_signer_name.empty();
-      const bool has_key_hash = !m_key_hash.empty();
-
-      if(has_signer && has_key_hash)
-         throw Decoding_Error("OCSP response includes both byName and byKey in responderID field");
-      if(!has_signer && !has_key_hash)
-         throw Decoding_Error("OCSP response contains neither byName nor byKey in responderID field");
       }
 
    response_outer.end_cons();
    }
 
-bool Response::is_issued_by(const X509_Certificate& candidate) const
-   {
-   if(!m_signer_name.empty())
-      {
-      return (candidate.subject_dn() == m_signer_name);
-      }
-
-   if(!m_key_hash.empty())
-      {
-      return (candidate.subject_public_key_bitstring_sha1() == m_key_hash);
-      }
-
-   return false;
-   }
-
 Certificate_Status_Code Response::verify_signature(const X509_Certificate& issuer) const
    {
    if(m_dummy_response_status)
diff --git a/src/lib/x509/ocsp.h b/src/lib/x509/ocsp.h
index d57914da6..f528b8976 100644
--- a/src/lib/x509/ocsp.h
+++ b/src/lib/x509/ocsp.h
@@ -133,6 +133,11 @@ enum class Response_Status_Code {
 class BOTAN_PUBLIC_API(2,0) Response final
    {
    public:
+      /**
+      * Creates an empty OCSP response.
+      */
+      Response() = default;
+
       /**
       * Create a fake OCSP response from a given status code.
       * @param status the status code the check functions will return
@@ -236,10 +241,14 @@ class BOTAN_PUBLIC_API(2,0) Response final
       std::optional<Certificate_Status_Code> dummy_status() const { return m_dummy_response_status; }
 
    private:
-      bool is_issued_by(const X509_Certificate& candidate) const;
+      bool is_issued_by(const X509_Certificate& candidate) const
+         {
+         return (!m_signer_name.empty() && candidate.subject_dn() == m_signer_name) ||
+                (!m_key_hash.empty() && candidate.subject_public_key_bitstring_sha1() == m_key_hash);
+         }
 
    private:
-      Response_Status_Code m_status = Response_Status_Code::Internal_Error;
+      Response_Status_Code m_status;
       std::vector<uint8_t> m_response_bits;
       X509_Time m_produced_at;
       X509_DN m_signer_name;
diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp
index 3d1d4256b..24f687834 100644
--- a/src/lib/x509/x509path.cpp
+++ b/src/lib/x509/x509path.cpp
@@ -812,7 +812,7 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<X509_Certificate>>& ce
             ee_extras.find_all_certs(issuer_dn, auth_key_id);
 
          // if we could not find any issuers, the current path ends here
-         if(trusted_issuers.empty() && misc_issuers.empty())
+         if(trusted_issuers.size() + misc_issuers.size() == 0)
             {
             stats.push_back(Certificate_Status_Code::CERT_ISSUER_NOT_FOUND);
             continue;
diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py
index fbb44c3fb..4673cf243 100755
--- a/src/scripts/ci_build.py
+++ b/src/scripts/ci_build.py
@@ -71,16 +71,13 @@ def build_targets(target, target_os):
         yield 'shared'
         yield 'static'
 
-    if target not in ['examples']:
-        yield 'cli'
-        yield 'tests'
+    yield 'cli'
+    yield 'tests'
 
     if target in ['coverage']:
         yield 'bogo_shim'
     if target in ['sanitizer'] and target_os not in ['windows']:
         yield 'bogo_shim'
-    if target in ['examples']:
-        yield 'examples'
 
 def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, ccache,
                     root_dir, build_dir, test_results_dir, pkcs11_lib, use_gdb,
@@ -94,7 +91,7 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, ccache,
 
     if target_os not in ['linux', 'osx', 'windows', 'freebsd']:
         print('Error unknown OS %s' % (target_os))
-        return (None, None, None)
+        return (None, None, None, None)
 
     if is_cross_target:
         if target_os == 'osx':
@@ -397,7 +394,7 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, ccache,
         else:
             run_test_command = test_prefix + test_cmd
 
-    return flags, run_test_command, make_prefix
+    return flags, run_test_command, make_prefix, install_prefix
 
 def run_cmd(cmd, root_dir, build_dir):
     """
@@ -617,7 +614,7 @@ def main(args=None):
         if options.test_results_dir:
             os.makedirs(options.test_results_dir)
 
-        config_flags, run_test_command, make_prefix = determine_flags(
+        config_flags, run_test_command, make_prefix, install_prefix = determine_flags(
             target, options.os, options.cpu, options.cc, options.cc_bin,
             options.compiler_cache, root_dir, build_dir, options.test_results_dir,
             options.pkcs11_lib, options.use_gdb, options.disable_werror,
@@ -647,9 +644,6 @@ def main(args=None):
             if target in ['coverage', 'fuzzers']:
                 make_targets += ['fuzzer_corpus_zip', 'fuzzers']
 
-            if target in ['examples']:
-                make_targets += ['examples']
-
             if target in ['coverage', 'sanitizer'] and options.os not in ['windows']:
                 make_targets += ['bogo_shim']
 
@@ -705,6 +699,12 @@ def main(args=None):
             cmds.append([py_interp, os.path.join(root_dir, 'src/scripts/ci_check_install.py'), build_config])
             cmds.append([py_interp, os.path.join(root_dir, 'src/scripts/ci_check_headers.py'), build_config])
 
+        if target in ['examples']:
+            cmds.append(make_cmd + ['install'])
+            cmds.append([options.make_tool, '-C', os.path.join(root_dir, 'src/examples'),
+                         'INCLUDES=-I %s/include/botan-3' % (install_prefix),
+                         'BUILD_DIR_LINK_PATH=-L%s/lib' % (install_prefix)])
+
         if target in ['coverage']:
             if have_prog('coverage'):
                 cmds.append(['coverage', 'run', '--branch',


Test patch:
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index 57715d38f..06a9da691 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -22,7 +22,6 @@ import ssl
 import subprocess
 import sys
 import tempfile
-import traceback
 import threading
 import time
 from multiprocessing.pool import ThreadPool
@@ -65,14 +64,7 @@ def setup_logging(options):
 def random_port_number():
     return random.randint(1024, 65535)
 
-
-def test_cli(cmd, cmd_options,
-             expected_output=None,
-             cmd_input=None,
-             expected_stderr=None,
-             use_drbg=True,
-             extra_env=None):
-    # pylint: disable=too-many-locals
+def test_cli(cmd, cmd_options, expected_output=None, cmd_input=None, expected_stderr=None, use_drbg=True):
     global TESTS_RUN
 
     TESTS_RUN += 1
@@ -98,13 +90,7 @@ def test_cli(cmd, cmd_options,
     stderr = None
 
     if cmd_input is None:
-        proc_env = None
-        if extra_env:
-            proc_env = os.environ
-            for (k,v) in extra_env.items():
-                proc_env[k] = v
-
-        proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=proc_env)
+        proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         (stdout, stderr) = proc.communicate()
     else:
         proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -783,16 +769,6 @@ def cli_cpuid_tests(_tmp_dir):
         if flag != '' and flag_re.match(flag) is None:
             logging.error('Unexpected CPUID flag name "%s"', flag)
 
-        env = {'BOTAN_CLEAR_CPUID': flag}
-        cpuid_output = test_cli("cpuid", [], None, None, None, True, env)
-        mod_flags = cpuid_output[13:].split(' ')
-
-        for f in mod_flags:
-            if f == flag:
-                logging.error('Clearing CPUID %s did not disable it', flag)
-            if f not in flags:
-                logging.error('Clearing CPUID %s caused flag %s to appear', flag, f)
-
 def cli_cc_enc_tests(_tmp_dir):
     test_cli("cc_encrypt", ["8028028028028029", "pass"], "4308989841607208")
     test_cli("cc_decrypt", ["4308989841607208", "pass"], "8028028028028027")
@@ -1391,7 +1367,6 @@ def run_test(fn_name, fn):
     try:
         fn(tmp_dir)
     except Exception as e: # pylint: disable=broad-except
-        logging.info(traceback.format_exc())
         logging.error("Test %s threw exception: %s", fn_name, e)
 
     shutil.rmtree(tmp_dir)
diff --git a/src/tests/data/block/serpent.vec b/src/tests/data/block/serpent.vec
index 8e75f341a..1009251ba 100644
--- a/src/tests/data/block/serpent.vec
+++ b/src/tests/data/block/serpent.vec
@@ -1,5 +1,5 @@
 
-#test cpuid avx512 avx2 simd
+#test cpuid avx2 simd
 
 [Serpent]
 Key = 00000000000000000000000000000000
diff --git a/src/tests/data/stream/chacha.vec b/src/tests/data/stream/chacha.vec
index 346683b5f..41381bba0 100644
--- a/src/tests/data/stream/chacha.vec
+++ b/src/tests/data/stream/chacha.vec
@@ -1,5 +1,5 @@
 
-#test cpuid avx512 avx2 sse2
+#test cpuid avx2 sse2
 
 [ChaCha(8)]
 
diff --git a/src/tests/runner/test_xml_reporter.h b/src/tests/runner/test_xml_reporter.h
index c285fa7ea..d6583b190 100644
--- a/src/tests/runner/test_xml_reporter.h
+++ b/src/tests/runner/test_xml_reporter.h
@@ -8,7 +8,7 @@
 #ifndef BOTAN_TEST_XML_REPORTER_H_
 #define BOTAN_TEST_XML_REPORTER_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
 
 #include "test_reporter.h"
diff --git a/src/tests/test_certstor_utils.h b/src/tests/test_certstor_utils.h
index 876edcf91..d96319af5 100644
--- a/src/tests/test_certstor_utils.h
+++ b/src/tests/test_certstor_utils.h
@@ -11,7 +11,7 @@
 #include <string>
 #include <vector>
 
-#include <botan/types.h>
+#include <botan/build.h>
 
 #if defined(BOTAN_HAS_X509_CERTIFICATES)
 
diff --git a/src/tests/test_ocsp.cpp b/src/tests/test_ocsp.cpp
index 797b63f05..fc97fe77f 100644
--- a/src/tests/test_ocsp.cpp
+++ b/src/tests/test_ocsp.cpp
@@ -5,7 +5,7 @@
 * Botan is released under the Simplified BSD License (see license.txt)
 */
 
-#include "botan/types.h"
+#include "botan/build.h"
 
 #if defined(BOTAN_HAS_OCSP)
    #include <botan/ocsp.h>
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 0b750761a..7198b75d0 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -8,7 +8,7 @@
 #ifndef BOTAN_TESTS_H_
 #define BOTAN_TESTS_H_
 
-#include <botan/types.h>
+#include <botan/build.h>
 #include <botan/rng.h>
 #include <botan/hex.h>
 #include <botan/symkey.h>