diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-11 15:04:05 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-12 11:10:46 +0000 |
commit | d3cc47f7573847e18135fab9d1d80fda697fd1f0 (patch) | |
tree | a59487f55b8807d6c4af2b99971ca1796a54c017 /src/libs/3rdparty | |
parent | 8f29b0bcde277a26abc3ffd524fddb0f493ac76c (diff) |
Update bundled Botan library to version 2.8
Change-Id: Ie8fb13f096a3a8658f6bde3d21f46ea453dc627f
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/libs/3rdparty')
138 files changed, 3133 insertions, 1183 deletions
diff --git a/src/libs/3rdparty/botan/configure.py b/src/libs/3rdparty/botan/configure.py index b09f07bb5e..bf091946b2 100755 --- a/src/libs/3rdparty/botan/configure.py +++ b/src/libs/3rdparty/botan/configure.py @@ -276,7 +276,7 @@ class BuildPaths(object): # pylint: disable=too-many-instance-attributes else: raise InternalError("Unknown src info type '%s'" % (typ)) -def process_command_line(args): # pylint: disable=too-many-locals +def process_command_line(args): # pylint: disable=too-many-locals,too-many-statements """ Handle command line options Do not use logging in this method as command line options need to be @@ -469,6 +469,9 @@ def process_command_line(args): # pylint: disable=too-many-locals build_group.add_option('--with-debug-asserts', action='store_true', default=False, help=optparse.SUPPRESS_HELP) + build_group.add_option('--ack-vc2013-deprecated', action='store_true', default=False, + help=optparse.SUPPRESS_HELP) + docs_group = optparse.OptionGroup(parser, 'Documentation Options') docs_group.add_option('--with-documentation', action='store_true', @@ -520,7 +523,7 @@ def process_command_line(args): # pylint: disable=too-many-locals help='minimize build') # Should be derived from info.txt but this runs too early - third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'sqlite3', 'zlib', 'tpm'] + third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'commoncrypto', 'sqlite3', 'zlib', 'tpm'] for mod in third_party: mods_group.add_option('--with-%s' % (mod), @@ -754,6 +757,7 @@ class ModuleInfo(InfoObject): """ def __init__(self, infofile): + # pylint: disable=too-many-statements super(ModuleInfo, self).__init__(infofile) lex = lex_me_harder( infofile, @@ -850,7 +854,7 @@ class ModuleInfo(InfoObject): for key, value in defines.items(): if not re.match('^[0-9A-Za-z_]{3,30}$', key): raise InternalError('Module defines key has invalid format: "%s"' % key) - if not re.match('^[0-9]{8}$', value): + if not re.match('^20[0-9]{6}$', value): raise InternalError('Module defines value has invalid format: "%s"' % value) def cross_check(self, arch_info, cc_info, all_os_features): @@ -959,7 +963,7 @@ class ModuleInfo(InfoObject): def dependencies(self, osinfo): # base is an implicit dep for all submodules deps = ['base'] - if self.parent_module != None: + if self.parent_module is not None: deps.append(self.parent_module) for req in self.requires: @@ -1173,22 +1177,22 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes return self.visibility_attribute return '' - def mach_abi_link_flags(self, options, with_debug_info=None): + def mach_abi_link_flags(self, options, debug_mode=None): #pylint: disable=too-many-branches """ Return the machine specific ABI flags """ - if with_debug_info is None: - with_debug_info = options.with_debug_info + if debug_mode is None: + debug_mode = options.debug_mode def mach_abi_groups(): yield 'all' if options.msvc_runtime is None: - if with_debug_info: + if debug_mode: yield 'rt-debug' else: yield 'rt' @@ -1205,7 +1209,7 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes for what in mach_abi_groups(): if what in self.mach_abi_linking: flag = self.mach_abi_linking.get(what) - if flag != None and flag != '' and flag not in abi_link: + if flag is not None and flag != '' and flag not in abi_link: abi_link.add(flag) if options.msvc_runtime: @@ -1418,7 +1422,7 @@ class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes return False def building_shared_supported(self): - return self.soname_pattern_base != None + return self.soname_pattern_base is not None def enabled_features(self, options): feats = [] @@ -1466,7 +1470,7 @@ def guess_processor(archinfo): for info_part in system_cpu_info(): if info_part: match = canon_processor(archinfo, info_part) - if match != None: + if match is not None: logging.debug("Matched '%s' to processor '%s'" % (info_part, match)) return match, info_part else: @@ -1727,13 +1731,13 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, """ Figure out what external libraries/frameworks are needed based on selected modules """ - if not (module_member_name == 'libs' or module_member_name == 'frameworks'): + if module_member_name not in ['libs', 'frameworks']: raise InternalError("Invalid argument") libs = set() for module in modules: for (osname, module_link_to) in getattr(module, module_member_name).items(): - if osname == 'all' or osname == osinfo.basename: + if osname in ['all', osinfo.basename]: libs |= set(module_link_to) else: match = re.match('^all!(.*)', osname) @@ -1787,7 +1791,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, return osinfo.ar_command def choose_endian(arch_info, options): - if options.with_endian != None: + if options.with_endian is not None: return options.with_endian if options.cpu.endswith('eb') or options.cpu.endswith('be'): @@ -1795,7 +1799,8 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, elif options.cpu.endswith('el') or options.cpu.endswith('le'): return 'little' - logging.info('Defaulting to assuming %s endian', arch_info.endian) + if arch_info.endian: + logging.info('Defaulting to assuming %s endian', arch_info.endian) return arch_info.endian build_dir = options.with_build_dir or os.path.curdir @@ -1863,6 +1868,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, 'with_rst2man': options.with_rst2man, 'sphinx_config_dir': source_paths.sphinx_config_dir, 'with_doxygen': options.with_doxygen, + 'maintainer_mode': options.maintainer_mode, 'out_dir': build_dir, 'build_dir': build_paths.build_dir, @@ -1968,6 +1974,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, 'with_openmp': options.with_openmp, 'with_debug_asserts': options.with_debug_asserts, 'test_mode': options.test_mode, + 'optimize_for_size': options.optimize_for_size, 'mod_list': sorted([m.basename for m in modules]) } @@ -1980,15 +1987,15 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, variables['static_suffix']) if options.build_shared_lib: - if osinfo.soname_pattern_base != None: + if osinfo.soname_pattern_base is not None: variables['soname_base'] = osinfo.soname_pattern_base.format(**variables) variables['shared_lib_name'] = variables['soname_base'] - if osinfo.soname_pattern_abi != None: + if osinfo.soname_pattern_abi is not None: variables['soname_abi'] = osinfo.soname_pattern_abi.format(**variables) variables['shared_lib_name'] = variables['soname_abi'] - if osinfo.soname_pattern_patch != None: + if osinfo.soname_pattern_patch is not None: variables['soname_patch'] = osinfo.soname_pattern_patch.format(**variables) variables['lib_link_cmd'] = variables['lib_link_cmd'].format(**variables) @@ -2035,15 +2042,15 @@ class ModulesChooser(object): self._modules, self._options.enabled_modules, self._options.disabled_modules) def _check_usable(self, module, modname): - if not module.compatible_os(self._osinfo, self._options): + if not module.compatible_cpu(self._archinfo, self._options): + self._not_using_because['incompatible CPU'].add(modname) + return False + elif not module.compatible_os(self._osinfo, self._options): self._not_using_because['incompatible OS'].add(modname) return False elif not module.compatible_compiler(self._ccinfo, self._cc_min_version, self._archinfo.basename): self._not_using_because['incompatible compiler'].add(modname) return False - elif not module.compatible_cpu(self._archinfo, self._options): - self._not_using_because['incompatible CPU'].add(modname) - return False return True @staticmethod @@ -2265,11 +2272,13 @@ def choose_link_method(options): # Symbolic link support on Windows was introduced in Windows 6.0 (Vista) and Python 3.2 # Furthermore the SeCreateSymbolicLinkPrivilege is required in order to successfully create symlinks # So only try to use symlinks on Windows if explicitly requested - if req == 'symlink' and options.os == 'windows': - yield 'symlink' - # otherwise keep old conservative behavior - if 'symlink' in os.__dict__ and options.os != 'windows': + + if options.os in ['windows', 'mingw', 'cygwin']: + if req == 'symlink': + yield 'symlink' + elif 'symlink' in os.__dict__: yield 'symlink' + if 'link' in os.__dict__: yield 'hardlink' yield 'copy' @@ -2352,16 +2361,10 @@ class AmalgamationHeader(object): self.included_already = set() self.all_std_includes = set() - encoding_kwords = {} - if sys.version_info[0] == 3: - encoding_kwords['encoding'] = 'utf8' - self.file_contents = {} for filepath in sorted(input_filepaths): try: - with open(filepath, **encoding_kwords) as f: - raw_content = f.readlines() - contents = AmalgamationGenerator.strip_header_goop(filepath, raw_content) + contents = AmalgamationGenerator.read_header(filepath) self.file_contents[os.path.basename(filepath)] = contents except IOError as e: logging.error('Error processing file %s for amalgamation: %s' % (filepath, e)) @@ -2439,6 +2442,15 @@ class AmalgamationGenerator(object): _header_guard_pattern = re.compile('^#define BOTAN_.*_H_$') @staticmethod + def read_header(filepath): + encoding_kwords = {} + if sys.version_info[0] == 3: + encoding_kwords['encoding'] = 'utf8' + with open(filepath, **encoding_kwords) as f: + raw_content = f.readlines() + return AmalgamationGenerator.strip_header_goop(filepath, raw_content) + + @staticmethod def strip_header_goop(header_name, header_lines): lines = copy.copy(header_lines) # defensive copy @@ -2505,16 +2517,32 @@ class AmalgamationGenerator(object): logging.info('Writing amalgamation header to %s' % (header_name)) pub_header_amalag.write_to_file(header_name, "BOTAN_AMALGAMATION_H_") - internal_headers = AmalgamationHeader(self._build_paths.internal_headers) + isa_headers = {} + internal_headers = [] + + def known_isa_header(hdr): + if hdr == 'simd_avx2.h': + return 'avx2' + return None + + for hdr in self._build_paths.internal_headers: + isa = known_isa_header(os.path.basename(hdr)) + if isa: + isa_headers[isa] = ''.join(AmalgamationGenerator.read_header(hdr)) + else: + internal_headers.append(hdr) + + internal_headers = AmalgamationHeader(internal_headers) header_int_name = '%s_internal.h' % (AmalgamationGenerator.filename_prefix) logging.info('Writing amalgamation header to %s' % (header_int_name)) internal_headers.write_to_file(header_int_name, "BOTAN_AMALGAMATION_INTERNAL_H_") header_files = [header_name, header_int_name] included_in_headers = pub_header_amalag.all_std_includes | internal_headers.all_std_includes - return header_files, included_in_headers + return header_files, included_in_headers, isa_headers - def _generate_sources(self, amalgamation_headers, included_in_headers): #pylint: disable=too-many-locals,too-many-branches + def _generate_sources(self, amalgamation_headers, included_in_headers, isa_headers): + #pylint: disable=too-many-locals,too-many-branches encoding_kwords = {} if sys.version_info[0] == 3: encoding_kwords['encoding'] = 'utf8' @@ -2533,6 +2561,14 @@ class AmalgamationGenerator(object): logging.info('Writing amalgamation source to %s' % (filepath)) amalgamation_files[target] = open(filepath, 'w', **encoding_kwords) + def gcc_isa(isa): + if isa == 'sse41': + return 'sse4.1' + elif isa == 'sse42': + return 'ssse4.2' + else: + return isa + for target, f in amalgamation_files.items(): AmalgamationHeader.write_banner(f) f.write('\n') @@ -2542,13 +2578,11 @@ class AmalgamationGenerator(object): for isa in self._isas_for_target(target): - if isa == 'sse41': - isa = 'sse4.1' - elif isa == 'sse42': - isa = 'ssse4.2' + if isa in isa_headers: + f.write(isa_headers[isa]) f.write('#if defined(__GNUG__) && !defined(__clang__)\n') - f.write('#pragma GCC target ("%s")\n' % (isa)) + f.write('#pragma GCC target ("%s")\n' % (gcc_isa(isa))) f.write('#endif\n') # target to include header map @@ -2580,8 +2614,8 @@ class AmalgamationGenerator(object): return set(amalgamation_sources.values()) def generate(self): - amalgamation_headers, included_in_headers = self._generate_headers() - amalgamation_sources = self._generate_sources(amalgamation_headers, included_in_headers) + amalgamation_headers, included_in_headers, isa_headers = self._generate_headers() + amalgamation_sources = self._generate_sources(amalgamation_headers, included_in_headers, isa_headers) return (sorted(amalgamation_sources), sorted(amalgamation_headers)) @@ -2712,7 +2746,7 @@ def set_defaults_for_unset_options(options, info_arch, info_cc): # pylint: disab return 'gcc' return None - if options.compiler is None and options.compiler_binary != None: + if options.compiler is None and options.compiler_binary is not None: options.compiler = deduce_compiler_type_from_cc_bin(options.compiler_binary) if options.compiler is None: @@ -2836,7 +2870,7 @@ def validate_options(options, info_os, info_cc, available_module_policies): if options.os != options.cpu: raise UserError('LLVM target requires both CPU and OS be set to llvm') - if options.build_fuzzers != None: + if options.build_fuzzers is not None: if options.build_fuzzers not in ['libfuzzer', 'afl', 'klee', 'test']: raise UserError('Bad value to --build-fuzzers') @@ -2932,7 +2966,10 @@ def calculate_cc_min_version(options, ccinfo, source_paths): if ccinfo.basename == 'msvc': if major_version == 18: - logging.warning('MSVC 2013 support is deprecated and will be removed in a future release') + logging.warning('MSVC 2013 support is deprecated, and will be removed in Jan 2019') + if not options.ack_vc2013_deprecated: + logging.error('Acknowledge this deprecation by adding flag --ack-vc2013-deprecated') + return cc_version def check_compiler_arch(options, ccinfo, archinfo, source_paths): @@ -2941,7 +2978,10 @@ def check_compiler_arch(options, ccinfo, archinfo, source_paths): abi_flags = ccinfo.mach_abi_link_flags(options).split(' ') cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, 'UNKNOWN', abi_flags).lower() - if cc_output in ['', 'unknown']: + if cc_output == '': + cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, 'UNKNOWN').lower() + + if cc_output == 'unknown': logging.warning('Unable to detect target architecture via compiler macro checks') return None @@ -2954,7 +2994,7 @@ def check_compiler_arch(options, ccinfo, archinfo, source_paths): return cc_output def do_io_for_build(cc, arch, osinfo, using_mods, build_paths, source_paths, template_vars, options): - # pylint: disable=too-many-locals,too-many-branches + # pylint: disable=too-many-locals,too-many-branches,too-many-statements try: robust_rmtree(build_paths.build_dir) @@ -3165,10 +3205,8 @@ if __name__ == '__main__': logging.error("""%s An internal error occurred. -Don't panic, this is probably not your fault! - -Please report the entire output at https://github.com/randombit/botan or email -to the mailing list https://lists.randombit.net/mailman/listinfo/botan-devel +Don't panic, this is probably not your fault! Please open an issue +with the entire output at https://github.com/randombit/botan You'll meet friendly people happy to help!""" % traceback.format_exc()) diff --git a/src/libs/3rdparty/botan/readme.rst b/src/libs/3rdparty/botan/readme.rst index 5d96cb3829..557ce51c26 100644 --- a/src/libs/3rdparty/botan/readme.rst +++ b/src/libs/3rdparty/botan/readme.rst @@ -1,50 +1,36 @@ -Botan: Crypto and TLS for C++11 +Botan: Crypto and TLS for Modern C++ ======================================== -Botan (Japanese for peony) is a cryptography library written in C++11 -and released under the permissive `Simplified BSD -<https://botan.randombit.net/license.txt>`_ license. +Botan (Japanese for peony flower) is a C++ cryptography library released under the +permissive `Simplified BSD <https://botan.randombit.net/license.txt>`_ license. Botan's goal is to be the best option for cryptography in C++ by offering the -tools necessary to implement a range of practical systems, such as TLS/DTLS, +tools necessary to implement a range of practical systems, such as TLS protocol, X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support, -password hashing, and post quantum crypto schemes. Botan also has a C89 API -specifically designed to be easy to call from other languages. A Python binding -using ctypes is included, and several other `language bindings +password hashing, and post quantum crypto schemes. +See the `documentation <https://botan.randombit.net/manual>`_ for more information. + +A Python binding is included, and several other `language bindings <https://github.com/randombit/botan/wiki/Language-Bindings>`_ are available. -Find the full feature list below. Development is coordinated on `GitHub <https://github.com/randombit/botan>`_ -and contributions are welcome (read `doc/contributing.rst` for more info). - -If you need help with a problem, please open an `issue on GitHub -<https://github.com/randombit/botan/issues>`_ or email the -`botan-devel mailing list -<https://lists.randombit.net/mailman/listinfo/botan-devel/>`_. - -New releases are announced on the -`botan-announce mailing list +and contributions are welcome. If you need help, please open an issue on +`GitHub <https://github.com/randombit/botan/issues>`_ or email the +`botan-devel mailing list <https://lists.randombit.net/mailman/listinfo/botan-devel/>`_. +New releases are announced on the `botan-announce mailing list <https://lists.randombit.net/mailman/listinfo/botan-announce/>`_. - -If you think you have found a security bug in Botan please contact -Jack Lloyd by emailing jack@randombit.net. His PGP public key with -fingerprint 4E60C73551AF2188DF0A5A6278E9804357123B60 can can be found -in ``doc/pgpkey.txt`` in the distribution, -https://keybase.io/jacklloyd, and some public PGP key servers. - -.. highlight:: none - -For all the details on building the library, read the -`users manual <https://botan.randombit.net/manual>`_, but basically:: - - $ ./configure.py - $ make - $ ./botan-test - ... - $ make install - -Botan can also be built into a single-file amalgamation for easy inclusion into -external build systems, see the manual for details. +If you think you have found a security issue, see the `security page +<https://botan.randombit.net/security.html>`_ for contact information. + +The latest release is +`2.8.0 <https://botan.randombit.net/releases/Botan-2.8.0.tgz>`_ +`(sig) <https://botan.randombit.net/releases/Botan-2.8.0.tgz.asc>`_, +released on 2018-10-01. +All releases are signed with a `PGP key <https://botan.randombit.net/pgpkey.txt>`_. +See the `release notes <https://botan.randombit.net/news.html>`_ for +what is new. Botan is also available through most +`distributions <https://github.com/randombit/botan/wiki/Distros>`_ +such as Fedora, Debian, Arch and Homebrew. .. image:: https://travis-ci.org/randombit/botan.svg?branch=master :target: https://travis-ci.org/randombit/botan @@ -66,55 +52,10 @@ external build systems, see the manual for details. :target: https://scan.coverity.com/projects/624 :alt: Coverity results -.. image:: https://sonarcloud.io/api/project_badges/measure?project=botan&metric=ncloc - :target: https://sonarcloud.io/dashboard/index/botan - :alt: Sonarcloud analysis - .. image:: https://bestpractices.coreinfrastructure.org/projects/531/badge :target: https://bestpractices.coreinfrastructure.org/projects/531 :alt: CII Best Practices statement -Release Downloads -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -See the `release notes <https://botan.randombit.net/news.html>`_ and -`security advisories <https://botan.randombit.net/security.html>`_ - -All releases are signed with a -`PGP key <https://botan.randombit.net/pgpkey.txt>`_:: - - pub 2048R/EFBADFBC 2004-10-30 - Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC - uid Botan Distribution Key - -Some `distributions <https://github.com/randombit/botan/wiki/Distros>`_ -such as Arch, Fedora and Debian include packages for Botan. However -these are often out of date; using the latest source release is recommended. - -Current Stable Release ----------------------------------------- - -Version 2 requires a C++11 compiler; GCC 4.8 and later, Clang 3.8 and later, and -MSVC 2015/2017 are regularly tested. New releases of Botan 2 are made on a -quarterly basis. - -The latest 2.x release is -`2.7.0 <https://botan.randombit.net/releases/Botan-2.7.0.tgz>`_ -`(sig) <https://botan.randombit.net/releases/Botan-2.7.0.tgz.asc>`_ -released on 2018-07-02 - -Old Release ----------------------------------------- - -The 1.10 branch is the last version of the library written in C++98. It is no -longer supported except for critical security updates (with all support ending -in December 2018), and the developers do not recommend its use anymore. - -The latest 1.10 release is -`1.10.17 <https://botan.randombit.net/releases/Botan-1.10.17.tgz>`_ -`(sig) <https://botan.randombit.net/releases/Botan-1.10.17.tgz.asc>`_ -released on 2017-10-02 - Find Enclosed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,8 +64,8 @@ Transport Layer Security (TLS) Protocol * TLS v1.0, v1.1, and v1.2. The broken SSLv3 protocol is no longer supported. * DTLS v1.0 and v1.2 are adaptations of TLS to datagram operation. -* Extensions include session tickets, SNI, ALPN, OCSP staple requests (client - side only right now), encrypt-then-mac CBC, and extended master secret. +* Supported extensions include session tickets, SNI, ALPN, OCSP stapling, + encrypt-then-mac CBC, and extended master secret. * Supports authentication using preshared keys (PSK) or passwords (SRP) * Supports record encryption with ChaCha20Poly1305, AES/OCB, AES/GCM, AES/CCM, Camellia/GCM as well as legacy CBC ciphersuites. @@ -144,7 +85,7 @@ Public Key Cryptography * RSA signatures and encryption * DH and ECDH key agreement -* Signature schemes ECDSA, DSA, Ed25519, ECGDSA, ECKCDSA, SM2, and GOST 34.10-2001 +* Signature schemes ECDSA, DSA, Ed25519, ECGDSA, ECKCDSA, SM2, GOST 34.10-2001 * Post-quantum signature scheme XMSS * Post-quantum key agreement schemes McEliece and NewHope * ElGamal encryption @@ -153,17 +94,15 @@ Public Key Cryptography Ciphers, hashes, MACs, and checksums ---------------------------------------- -* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, and ChaCha20Poly1305 -* Cipher modes CTR, CBC, XTS, CFB, and OFB -* Block ciphers AES, ARIA, Blowfish, Camellia, CAST-128, CAST-256, - DES/3DES, GOST 28147, IDEA, KASUMI, Lion, MISTY1, Noekeon, SEED, - Serpent, SHACAL2, SM4, Threefish-512, Twofish, XTEA -* Stream ciphers ChaCha20, Salsa20/XSalsa20, SHAKE-128, and RC4 -* Hash functions SHA-1, SHA-2, SHA-3, RIPEMD-160, Skein-512, - BLAKE2b, SM3, Tiger, Whirlpool, GOST 34.11, MD5, MD4 -* Hash function combiners Parallel and Comb4P -* Authentication codes HMAC, CMAC, Poly1305, SipHash, GMAC, CBC-MAC, X9.19 DES-MAC -* Non-cryptographic checksums Adler32, CRC24, and CRC32 +* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, (X)ChaCha20Poly1305 +* Cipher modes CTR, CBC, XTS, CFB, OFB +* Block ciphers AES, ARIA, Blowfish, Camellia, CAST-128, DES/3DES, GOST 28147, + IDEA, Lion, Noekeon, SEED, Serpent, SHACAL2, SM4, Threefish-512, Twofish, XTEA +* Stream ciphers (X)ChaCha20, (X)Salsa20, SHAKE-128, RC4 +* Hash functions SHA-1, SHA-2, SHA-3, MD4, MD5, RIPEMD-160, BLAKE2b, + Skein-512, SM3, Tiger, Whirlpool, GOST 34.11 +* Authentication codes HMAC, CMAC, Poly1305, SipHash, GMAC, X9.19 DES-MAC +* Non-cryptographic checksums Adler32, CRC24, CRC32 Other Useful Things ---------------------------------------- @@ -173,8 +112,7 @@ Other Useful Things * Simple compression API wrapping zlib, bzip2, and lzma libraries * RNG wrappers for system RNG and hardware RNGs * HMAC_DRBG and entropy collection system for userspace RNGs -* Password based key derivation functions PBKDF2 and Scrypt -* Password hashing function bcrypt and passhash9 (custom PBKDF scheme) +* Password hashing schemes PBKDF2, Scrypt, bcrypt * SRP-6a password authenticated key exchange * Key derivation functions including HKDF, KDF2, SP 800-108, SP 800-56A, SP 800-56C * HOTP and TOTP algorithms diff --git a/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt b/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt index d4781c8740..056c5318ff 100644 --- a/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt +++ b/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt @@ -12,4 +12,8 @@ armv8-a <isa_extensions> neon armv8crypto +armv8sm3 +armv8sm4 +armv8sha3 +armv8sha512 </isa_extensions> diff --git a/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt b/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt index aed017f20d..9ab7cccded 100644 --- a/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt +++ b/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt @@ -6,6 +6,7 @@ wordsize 64 <aliases> powerpc64 ppc64le +ppc64el </aliases> <isa_extensions> diff --git a/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt b/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt index b9bc16939a..c8c258a00e 100644 --- a/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt +++ b/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt @@ -1 +1,2 @@ family riscv +endian little diff --git a/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt b/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt index 56130f26cf..b01c8277fd 100644 --- a/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt +++ b/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt @@ -1,2 +1,3 @@ family sparc wordsize 64 +endian big diff --git a/src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt b/src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt index 6cbc5d0b33..a36c0c5567 100644 --- a/src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt +++ b/src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt @@ -12,6 +12,7 @@ x86pc # for QNX bepc # for Haiku i686 +i586 i386 </aliases> diff --git a/src/libs/3rdparty/botan/src/build-data/botan.doxy.in b/src/libs/3rdparty/botan/src/build-data/botan.doxy.in index bbb0bbaf7c..743a6e0b4e 100644 --- a/src/libs/3rdparty/botan/src/build-data/botan.doxy.in +++ b/src/libs/3rdparty/botan/src/build-data/botan.doxy.in @@ -74,7 +74,10 @@ WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = + +%{if maintainer_mode} WARN_AS_ERROR = YES +%{endif} #--------------------------------------------------------------------------- # configuration options related to the input files @@ -154,14 +157,17 @@ PREDEFINED = BOTAN_HAS_AES_ARMV8 \ BOTAN_HAS_AES_POWER8 \ BOTAN_HAS_AES_SSSE3 \ BOTAN_HAS_CHACHA_SSE2 \ + BOTAN_HAS_CHACHA_AVX2 \ BOTAN_HAS_IDEA_SSE2 \ BOTAN_HAS_NOEKEON_SIMD \ BOTAN_HAS_SERPENT_SIMD \ + BOTAN_HAS_SERPENT_AVX2 \ BOTAN_HAS_SHA1_SSE2 \ BOTAN_HAS_SHA2_32_X86 \ BOTAN_HAS_SHA2_32_X86_BMI2 \ BOTAN_HAS_SHACAL2_SIMD \ BOTAN_HAS_SHACAL2_X86 \ + BOTAN_HAS_SM4_ARMV8 \ BOTAN_HAS_THREEFISH_512_AVX2 \ BOTAN_DEPRECATED(msg)= \ BOTAN_PUBLIC_API(maj,min)= diff --git a/src/libs/3rdparty/botan/src/build-data/buildh.in b/src/libs/3rdparty/botan/src/build-data/buildh.in index f34cf26a39..17df7791b9 100644 --- a/src/libs/3rdparty/botan/src/build-data/buildh.in +++ b/src/libs/3rdparty/botan/src/build-data/buildh.in @@ -87,6 +87,10 @@ #define BOTAN_ENABLE_DEBUG_ASSERTS %{endif} +%{if optimize_for_size} +#define BOTAN_OPTIMIZE_FOR_SIZE +%{endif} + /* * Module availability definitions */ @@ -166,8 +170,8 @@ * broken system RNG. */ #define BOTAN_ENTROPY_DEFAULT_SOURCES \ - { "rdseed", "rdrand", "darwin_secrandom", "getentropy", \ - "dev_random", "system_rng", "proc_walk", "system_stats" } + { "rdseed", "rdrand", "getentropy", "dev_random", \ + "system_rng", "proc_walk", "system_stats" } /* Multiplier on a block cipher's native parallelism */ #define BOTAN_BLOCK_CIPHER_PAR_MULT 4 @@ -176,7 +180,7 @@ * These control the RNG used by the system RNG interface */ #define BOTAN_SYSTEM_RNG_DEVICE "/dev/urandom" -#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random", "/dev/srandom" } +#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random" } /* * This directory will be monitored by ProcWalking_EntropySource and diff --git a/src/libs/3rdparty/botan/src/build-data/cc/clang.txt b/src/libs/3rdparty/botan/src/build-data/cc/clang.txt index 948a881cf8..ab9ff9dc0c 100644 --- a/src/libs/3rdparty/botan/src/build-data/cc/clang.txt +++ b/src/libs/3rdparty/botan/src/build-data/cc/clang.txt @@ -18,7 +18,7 @@ default -> address,undefined address -> "-fsanitize=address" undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined" -coverage -> "-fsanitize-coverage=edge,indirect-calls,8bit-counters" +coverage -> "-fsanitize-coverage=edge,indirect-calls,trace-pc-guard,trace-cmp,trace-gep" memory -> "-fsanitize=memory" </sanitizers> diff --git a/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt b/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt index 98f1a21674..01baeafcdc 100644 --- a/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt +++ b/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt @@ -65,6 +65,10 @@ altivec -> "-maltivec" ppccrypto -> "-mcrypto" arm64:armv8crypto -> "" +arm64:armv8sm3 -> "-march=armv8.2-a+sm4" +arm64:armv8sm4 -> "-march=armv8.2-a+sm4" +arm64:armv8sha512 -> "-march=armv8.2-a+sha3" +arm64:armv8sha3 -> "-march=armv8.2-a+sha3" # For Aarch32 -mfpu=neon is required # For Aarch64 NEON is enabled by default diff --git a/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt b/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt index ed32a3c3cd..7cebb5036d 100644 --- a/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt +++ b/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt @@ -23,7 +23,7 @@ debug_info_flags "/Zi /FS" preproc_flags "/nologo /EP" -lang_flags "/EHs /GR" +lang_flags "/EHs /GR /D_ENABLE_EXTENDED_ALIGNED_STORAGE" warning_flags "/W4 /wd4250 /wd4251 /wd4275" visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)" @@ -38,7 +38,7 @@ sse2 -> "" ssse3 -> "" sse41 -> "" sse42 -> "" -x86_64:avx2 -> "" +x86_64:avx2 -> "/arch:AVX" bmi2 -> "" aesni -> "" clmul -> "" diff --git a/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt b/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt index c5dac65de1..3dd8e00b02 100644 --- a/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt +++ b/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt @@ -5,8 +5,8 @@ binary_name CC optimization_flags "-xO2" shared_flags "-KPIC" -warning_flags "+w -erroff=truncwarn,wnoretvalue" -lang_flags "-std=c++11 +p -features=extensions -D__FUNCTION__=__func__" +warning_flags "+w -erroff=truncwarn,wnoretvalue,wlessrestrictedthrow" +lang_flags "-std=c++11 +p -features=extensions" ar_command CC ar_options "-xar -o" @@ -19,7 +19,7 @@ default -> "$(CXX) -G -h{soname_abi}" # Needed on some Linux distros linux -> "-library=stlport4" -sparc64 -> "-xarch=v9" +sparc64 -> "-m64 -xarch=sparc" x86_64 -> "-m64" </mach_abi_linking> diff --git a/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp b/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp index f5e6ecd582..028e39b3bc 100644 --- a/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp +++ b/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp @@ -57,6 +57,14 @@ #elif defined(__s390__) S390 +#elif defined(__riscv) + + #if defined(__LP64__) + RISCV64 + #else + RISCV32 + #endif + #else UNKNOWN diff --git a/src/libs/3rdparty/botan/src/build-data/makefile.in b/src/libs/3rdparty/botan/src/build-data/makefile.in index 7cd04360f1..473f0efd76 100644 --- a/src/libs/3rdparty/botan/src/build-data/makefile.in +++ b/src/libs/3rdparty/botan/src/build-data/makefile.in @@ -54,7 +54,7 @@ distclean: $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean install: libs cli docs - $(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix=%{prefix} --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir} + $(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix="%{prefix}" --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir} # Object Files LIBOBJS = %{join lib_objs} diff --git a/src/libs/3rdparty/botan/src/build-data/oids.txt b/src/libs/3rdparty/botan/src/build-data/oids.txt index 55acc0e9bd..ea8cab01f0 100644 --- a/src/libs/3rdparty/botan/src/build-data/oids.txt +++ b/src/libs/3rdparty/botan/src/build-data/oids.txt @@ -21,6 +21,7 @@ 1.3.132.1.12 = ECDH 1.2.156.10197.1.301.1 = SM2_Sig +1.2.156.10197.1.301.1 = SM2 1.2.156.10197.1.301.2 = SM2_Kex 1.2.156.10197.1.301.3 = SM2_Enc @@ -40,7 +41,6 @@ # Cipher modes 1.3.14.3.2.7 = DES/CBC 1.2.840.113549.3.7 = TripleDES/CBC -1.2.840.113549.3.2 = RC2/CBC 1.2.840.113533.7.66.10 = CAST-128/CBC 2.16.840.1.101.3.4.1.2 = AES-128/CBC 2.16.840.1.101.3.4.1.22 = AES-192/CBC @@ -80,6 +80,21 @@ 1.3.6.1.4.1.25258.3.2.3 = AES-256/OCB 1.3.6.1.4.1.25258.3.2.4 = Serpent/OCB 1.3.6.1.4.1.25258.3.2.5 = Twofish/OCB +1.3.6.1.4.1.25258.3.2.6 = Camellia-128/OCB +1.3.6.1.4.1.25258.3.2.7 = Camellia-192/OCB +1.3.6.1.4.1.25258.3.2.8 = Camellia-256/OCB + +1.2.156.10197.1.104.100 = SM4/OCB + +1.3.6.1.4.1.25258.3.4.1 = AES-128/SIV +1.3.6.1.4.1.25258.3.4.2 = AES-192/SIV +1.3.6.1.4.1.25258.3.4.3 = AES-256/SIV +1.3.6.1.4.1.25258.3.4.4 = Serpent/SIV +1.3.6.1.4.1.25258.3.4.5 = Twofish/SIV +1.3.6.1.4.1.25258.3.4.6 = Camellia-128/SIV +1.3.6.1.4.1.25258.3.4.7 = Camellia-192/SIV +1.3.6.1.4.1.25258.3.4.8 = Camellia-256/SIV +1.3.6.1.4.1.25258.3.4.9 = SM4/SIV [hash] # Hash functions @@ -115,11 +130,11 @@ 1.2.840.113549.2.9 = HMAC(SHA-256) 1.2.840.113549.2.10 = HMAC(SHA-384) 1.2.840.113549.2.11 = HMAC(SHA-512) +1.2.840.113549.2.13 = HMAC(SHA-512-256) [keywrap] # Keywrap algorithms 1.2.840.113549.1.9.16.3.6 = KeyWrap.TripleDES -1.2.840.113549.1.9.16.3.7 = KeyWrap.RC2 1.2.840.113533.7.66.15 = KeyWrap.CAST-128 2.16.840.1.101.3.4.1.5 = KeyWrap.AES-128 2.16.840.1.101.3.4.1.25 = KeyWrap.AES-192 @@ -140,6 +155,8 @@ 1.2.840.113549.1.1.14 = RSA/EMSA3(SHA-224) 1.2.840.113549.1.1.16 = RSA/EMSA3(SHA-512-256) 1.3.36.3.3.1.2 = RSA/EMSA3(RIPEMD-160) + +1.2.156.10197.1.501 = SM2_Sig/SM3 1.2.156.10197.1.504 = RSA/EMSA3(SM3) 1.2.840.10040.4.3 = DSA/EMSA1(SHA-160) @@ -208,6 +225,7 @@ [pbe] 1.2.840.113549.1.5.12 = PKCS5.PBKDF2 +1.2.840.113549.1.5.13 = PBES2 1.2.840.113549.1.5.13 = PBE-PKCS5v20 1.3.6.1.4.1.11591.4.11 = Scrypt @@ -258,6 +276,9 @@ 1.3.6.1.5.5.7.48.2 = PKIX.CertificateAuthorityIssuers 1.3.6.1.4.1.311.20.2.2 = Microsoft SmartcardLogon +1.3.6.1.4.1.311.20.2.3 = Microsoft UPN + +2.16.840.1.113730.1.13 = Certificate Comment # ECC param sets [ecc_param] diff --git a/src/libs/3rdparty/botan/src/build-data/os/darwin.txt b/src/libs/3rdparty/botan/src/build-data/os/darwin.txt index 056d535e7c..1a2f806901 100644 --- a/src/libs/3rdparty/botan/src/build-data/os/darwin.txt +++ b/src/libs/3rdparty/botan/src/build-data/os/darwin.txt @@ -14,8 +14,8 @@ posix1 posix_mlock arc4random dev_random -security_framework +commoncrypto sockets threads filesystem diff --git a/src/libs/3rdparty/botan/src/build-data/os/ios.txt b/src/libs/3rdparty/botan/src/build-data/os/ios.txt index 0e3eb7c4b0..286e10fd10 100644 --- a/src/libs/3rdparty/botan/src/build-data/os/ios.txt +++ b/src/libs/3rdparty/botan/src/build-data/os/ios.txt @@ -10,6 +10,7 @@ posix1 posix_mlock arc4random +commoncrypto sockets threads filesystem diff --git a/src/libs/3rdparty/botan/src/build-data/os/linux.txt b/src/libs/3rdparty/botan/src/build-data/os/linux.txt index 6f4f3d6443..208e13b9b1 100644 --- a/src/libs/3rdparty/botan/src/build-data/os/linux.txt +++ b/src/libs/3rdparty/botan/src/build-data/os/linux.txt @@ -10,6 +10,9 @@ proc_fs clock_gettime getauxval +# not enabled by default as only available in newer kernel/glibc +#getrandom + sockets threads filesystem diff --git a/src/libs/3rdparty/botan/src/build-data/version.txt b/src/libs/3rdparty/botan/src/build-data/version.txt index cc81f66a83..9c90765f0e 100644 --- a/src/libs/3rdparty/botan/src/build-data/version.txt +++ b/src/libs/3rdparty/botan/src/build-data/version.txt @@ -1,10 +1,10 @@ release_major = 2 -release_minor = 7 +release_minor = 8 release_patch = 0 -release_so_abi_rev = 7 +release_so_abi_rev = 8 # These are set by the distribution script -release_vc_rev = 'git:5874000d42c338ec95a7ff24cdc0c64e70f967b5' -release_datestamp = 20180702 +release_vc_rev = 'git:a792728e8941b62761052f5e0d288ba13a016c77' +release_datestamp = 20181001 release_type = 'release' diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp index 1f91782665..5c05d6589a 100644 --- a/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp @@ -174,7 +174,7 @@ void ASN1_Formatter::decode(std::ostream& output, data.decode(number, ENUMERATED, class_tag); } - std::vector<uint8_t> rep = BigInt::encode(number, BigInt::Binary); + std::vector<uint8_t> rep = BigInt::encode(number); if(rep.empty()) // if zero rep.resize(1); diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp index 43f94af6aa..8de42dfdef 100644 --- a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp @@ -262,6 +262,12 @@ std::chrono::system_clock::time_point X509_Time::to_std_timepoint() const return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint(); } +uint64_t X509_Time::time_since_epoch() const + { + auto tp = this->to_std_timepoint(); + return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count(); + } + /* * Compare two X509_Times for in various ways */ diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h index 717c58a7d9..83567e7805 100644 --- a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h @@ -49,6 +49,9 @@ class BOTAN_PUBLIC_API(2,0) X509_Time final : public ASN1_Object /// Returns a STL timepoint object std::chrono::system_clock::time_point to_std_timepoint() const; + /// Return time since epoch + uint64_t time_since_epoch() const; + private: void set_to(const std::string& t_spec, ASN1_Tag); bool passes_sanity_check() const; diff --git a/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp b/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp index 138661a809..10d82187bc 100644 --- a/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp +++ b/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp @@ -1,7 +1,7 @@ /* * OID maps * -* This file was automatically generated by ./src/scripts/oids.py on 2018-07-01 +* This file was automatically generated by ./src/scripts/oids.py on 2018-08-23 * * All manual edits to this file will be lost. Edit the script * then regenerate this source file. @@ -21,13 +21,15 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map() { "0.3.4401.5.3.1.9.46", "Camellia-256/GCM" }, { "0.3.4401.5.3.1.9.6", "Camellia-128/GCM" }, { "1.0.14888.3.0.5", "ECKCDSA" }, + { "1.2.156.10197.1.104.100", "SM4/OCB" }, { "1.2.156.10197.1.104.2", "SM4/CBC" }, { "1.2.156.10197.1.104.8", "SM4/GCM" }, { "1.2.156.10197.1.301", "sm2p256v1" }, - { "1.2.156.10197.1.301.1", "SM2_Sig" }, + { "1.2.156.10197.1.301.1", "SM2" }, { "1.2.156.10197.1.301.2", "SM2_Kex" }, { "1.2.156.10197.1.301.3", "SM2_Enc" }, { "1.2.156.10197.1.401", "SM3" }, + { "1.2.156.10197.1.501", "SM2_Sig/SM3" }, { "1.2.156.10197.1.504", "RSA/EMSA3(SM3)" }, { "1.2.250.1.223.101.256.1", "frp256v1" }, { "1.2.392.200011.61.1.1.1.2", "Camellia-128/CBC" }, @@ -78,7 +80,6 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map() { "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest" }, { "1.2.840.113549.1.9.16.3.18", "ChaCha20Poly1305" }, { "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES" }, - { "1.2.840.113549.1.9.16.3.7", "KeyWrap.RC2" }, { "1.2.840.113549.1.9.16.3.8", "Compression.Zlib" }, { "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName" }, { "1.2.840.113549.1.9.3", "PKCS9.ContentType" }, @@ -86,11 +87,11 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map() { "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword" }, { "1.2.840.113549.2.10", "HMAC(SHA-384)" }, { "1.2.840.113549.2.11", "HMAC(SHA-512)" }, + { "1.2.840.113549.2.13", "HMAC(SHA-512-256)" }, { "1.2.840.113549.2.5", "MD5" }, { "1.2.840.113549.2.7", "HMAC(SHA-160)" }, { "1.2.840.113549.2.8", "HMAC(SHA-224)" }, { "1.2.840.113549.2.9", "HMAC(SHA-256)" }, - { "1.2.840.113549.3.2", "RC2/CBC" }, { "1.2.840.113549.3.7", "TripleDES/CBC" }, { "1.3.101.110", "Curve25519" }, { "1.3.101.112", "Ed25519" }, @@ -137,10 +138,23 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map() { "1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB" }, { "1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB" }, { "1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB" }, + { "1.3.6.1.4.1.25258.3.2.6", "Camellia-128/OCB" }, + { "1.3.6.1.4.1.25258.3.2.7", "Camellia-192/OCB" }, + { "1.3.6.1.4.1.25258.3.2.8", "Camellia-256/OCB" }, { "1.3.6.1.4.1.25258.3.3", "Twofish/CBC" }, + { "1.3.6.1.4.1.25258.3.4.1", "AES-128/SIV" }, + { "1.3.6.1.4.1.25258.3.4.2", "AES-192/SIV" }, + { "1.3.6.1.4.1.25258.3.4.3", "AES-256/SIV" }, + { "1.3.6.1.4.1.25258.3.4.4", "Serpent/SIV" }, + { "1.3.6.1.4.1.25258.3.4.5", "Twofish/SIV" }, + { "1.3.6.1.4.1.25258.3.4.6", "Camellia-128/SIV" }, + { "1.3.6.1.4.1.25258.3.4.7", "Camellia-192/SIV" }, + { "1.3.6.1.4.1.25258.3.4.8", "Camellia-256/SIV" }, + { "1.3.6.1.4.1.25258.3.4.9", "SM4/SIV" }, { "1.3.6.1.4.1.3029.1.2.1", "ElGamal" }, { "1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519" }, { "1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon" }, + { "1.3.6.1.4.1.311.20.2.3", "Microsoft UPN" }, { "1.3.6.1.4.1.8301.3.1.2.9.0.38", "secp521r1" }, { "1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess" }, { "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth" }, @@ -195,6 +209,7 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map() { "2.16.840.1.101.3.4.3.7", "DSA/EMSA1(SHA-3(384))" }, { "2.16.840.1.101.3.4.3.8", "DSA/EMSA1(SHA-3(512))" }, { "2.16.840.1.101.3.4.3.9", "ECDSA/EMSA1(SHA-3(224))" }, + { "2.16.840.1.113730.1.13", "Certificate Comment" }, { "2.5.29.14", "X509v3.SubjectKeyIdentifier" }, { "2.5.29.15", "X509v3.KeyUsage" }, { "2.5.29.17", "X509v3.SubjectAlternativeName" }, @@ -237,21 +252,31 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map() { "AES-128/CCM", OID({2,16,840,1,101,3,4,1,7}) }, { "AES-128/GCM", OID({2,16,840,1,101,3,4,1,6}) }, { "AES-128/OCB", OID({1,3,6,1,4,1,25258,3,2,1}) }, + { "AES-128/SIV", OID({1,3,6,1,4,1,25258,3,4,1}) }, { "AES-192/CBC", OID({2,16,840,1,101,3,4,1,22}) }, { "AES-192/CCM", OID({2,16,840,1,101,3,4,1,27}) }, { "AES-192/GCM", OID({2,16,840,1,101,3,4,1,26}) }, { "AES-192/OCB", OID({1,3,6,1,4,1,25258,3,2,2}) }, + { "AES-192/SIV", OID({1,3,6,1,4,1,25258,3,4,2}) }, { "AES-256/CBC", OID({2,16,840,1,101,3,4,1,42}) }, { "AES-256/CCM", OID({2,16,840,1,101,3,4,1,47}) }, { "AES-256/GCM", OID({2,16,840,1,101,3,4,1,46}) }, { "AES-256/OCB", OID({1,3,6,1,4,1,25258,3,2,3}) }, + { "AES-256/SIV", OID({1,3,6,1,4,1,25258,3,4,3}) }, { "CAST-128/CBC", OID({1,2,840,113533,7,66,10}) }, { "Camellia-128/CBC", OID({1,2,392,200011,61,1,1,1,2}) }, { "Camellia-128/GCM", OID({0,3,4401,5,3,1,9,6}) }, + { "Camellia-128/OCB", OID({1,3,6,1,4,1,25258,3,2,6}) }, + { "Camellia-128/SIV", OID({1,3,6,1,4,1,25258,3,4,6}) }, { "Camellia-192/CBC", OID({1,2,392,200011,61,1,1,1,3}) }, { "Camellia-192/GCM", OID({0,3,4401,5,3,1,9,26}) }, + { "Camellia-192/OCB", OID({1,3,6,1,4,1,25258,3,2,7}) }, + { "Camellia-192/SIV", OID({1,3,6,1,4,1,25258,3,4,7}) }, { "Camellia-256/CBC", OID({1,2,392,200011,61,1,1,1,4}) }, { "Camellia-256/GCM", OID({0,3,4401,5,3,1,9,46}) }, + { "Camellia-256/OCB", OID({1,3,6,1,4,1,25258,3,2,8}) }, + { "Camellia-256/SIV", OID({1,3,6,1,4,1,25258,3,4,8}) }, + { "Certificate Comment", OID({2,16,840,1,113730,1,13}) }, { "ChaCha20Poly1305", OID({1,2,840,113549,1,9,16,3,18}) }, { "Compression.Zlib", OID({1,2,840,113549,1,9,16,3,8}) }, { "Curve25519", OID({1,3,101,110}) }, @@ -299,19 +324,21 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map() { "HMAC(SHA-256)", OID({1,2,840,113549,2,9}) }, { "HMAC(SHA-384)", OID({1,2,840,113549,2,10}) }, { "HMAC(SHA-512)", OID({1,2,840,113549,2,11}) }, + { "HMAC(SHA-512-256)", OID({1,2,840,113549,2,13}) }, { "KeyWrap.AES-128", OID({2,16,840,1,101,3,4,1,5}) }, { "KeyWrap.AES-192", OID({2,16,840,1,101,3,4,1,25}) }, { "KeyWrap.AES-256", OID({2,16,840,1,101,3,4,1,45}) }, { "KeyWrap.CAST-128", OID({1,2,840,113533,7,66,15}) }, - { "KeyWrap.RC2", OID({1,2,840,113549,1,9,16,3,7}) }, { "KeyWrap.TripleDES", OID({1,2,840,113549,1,9,16,3,6}) }, { "MD5", OID({1,2,840,113549,2,5}) }, { "MGF1", OID({1,2,840,113549,1,1,8}) }, { "McEliece", OID({1,3,6,1,4,1,25258,1,3}) }, { "Microsoft SmartcardLogon", OID({1,3,6,1,4,1,311,20,2,2}) }, + { "Microsoft UPN", OID({1,3,6,1,4,1,311,20,2,3}) }, { "OpenPGP.Curve25519", OID({1,3,6,1,4,1,3029,1,5,1}) }, { "OpenPGP.Ed25519", OID({1,3,6,1,4,1,11591,15,1}) }, { "PBE-PKCS5v20", OID({1,2,840,113549,1,5,13}) }, + { "PBES2", OID({1,2,840,113549,1,5,13}) }, { "PKCS5.PBKDF2", OID({1,2,840,113549,1,5,12}) }, { "PKCS9.ChallengePassword", OID({1,2,840,113549,1,9,7}) }, { "PKCS9.ContentType", OID({1,2,840,113549,1,9,3}) }, @@ -333,7 +360,6 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map() { "PKIX.ServerAuth", OID({1,3,6,1,5,5,7,3,1}) }, { "PKIX.TimeStamping", OID({1,3,6,1,5,5,7,3,8}) }, { "PKIX.XMPPAddr", OID({1,3,6,1,5,5,7,8,5}) }, - { "RC2/CBC", OID({1,2,840,113549,3,2}) }, { "RIPEMD-160", OID({1,3,36,3,2,1}) }, { "RSA", OID({1,2,840,113549,1,1,1}) }, { "RSA/EMSA3(MD5)", OID({1,2,840,113549,1,1,4}) }, @@ -364,16 +390,21 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map() { "SHA-512-256", OID({2,16,840,1,101,3,4,2,6}) }, { "SHAKE-128", OID({2,16,840,1,101,3,4,2,11}) }, { "SHAKE-256", OID({2,16,840,1,101,3,4,2,12}) }, + { "SM2", OID({1,2,156,10197,1,301,1}) }, { "SM2_Enc", OID({1,2,156,10197,1,301,3}) }, { "SM2_Kex", OID({1,2,156,10197,1,301,2}) }, { "SM2_Sig", OID({1,2,156,10197,1,301,1}) }, + { "SM2_Sig/SM3", OID({1,2,156,10197,1,501}) }, { "SM3", OID({1,2,156,10197,1,401}) }, { "SM4/CBC", OID({1,2,156,10197,1,104,2}) }, { "SM4/GCM", OID({1,2,156,10197,1,104,8}) }, + { "SM4/OCB", OID({1,2,156,10197,1,104,100}) }, + { "SM4/SIV", OID({1,3,6,1,4,1,25258,3,4,9}) }, { "Scrypt", OID({1,3,6,1,4,1,11591,4,11}) }, { "Serpent/CBC", OID({1,3,6,1,4,1,25258,3,1}) }, { "Serpent/GCM", OID({1,3,6,1,4,1,25258,3,101}) }, { "Serpent/OCB", OID({1,3,6,1,4,1,25258,3,2,4}) }, + { "Serpent/SIV", OID({1,3,6,1,4,1,25258,3,4,4}) }, { "Streebog-256", OID({1,2,643,7,1,1,2,2}) }, { "Streebog-512", OID({1,2,643,7,1,1,2,3}) }, { "Threefish-512/CBC", OID({1,3,6,1,4,1,25258,3,2}) }, @@ -382,6 +413,7 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map() { "Twofish/CBC", OID({1,3,6,1,4,1,25258,3,3}) }, { "Twofish/GCM", OID({1,3,6,1,4,1,25258,3,102}) }, { "Twofish/OCB", OID({1,3,6,1,4,1,25258,3,2,5}) }, + { "Twofish/SIV", OID({1,3,6,1,4,1,25258,3,4,5}) }, { "X509v3.AnyPolicy", OID({2,5,29,32,0}) }, { "X509v3.AuthorityKeyIdentifier", OID({2,5,29,35}) }, { "X509v3.BasicConstraints", OID({2,5,29,19}) }, diff --git a/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp b/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp index 59ce08b357..6a80a97a57 100644 --- a/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp +++ b/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp @@ -14,7 +14,7 @@ namespace OIDS { namespace { -class OID_Map +class OID_Map final { public: void add_oid(const OID& oid, const std::string& str) diff --git a/src/libs/3rdparty/botan/src/lib/base/secmem.h b/src/libs/3rdparty/botan/src/lib/base/secmem.h index 12ea55a3b6..92477438d4 100644 --- a/src/libs/3rdparty/botan/src/lib/base/secmem.h +++ b/src/libs/3rdparty/botan/src/lib/base/secmem.h @@ -88,7 +88,7 @@ operator!=(const secure_allocator<T>&, const secure_allocator<U>&) template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>; -// For better compatability with 1.10 API +// For better compatibility with 1.10 API template<typename T> using SecureVector = secure_vector<T>; template<typename T> diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp index 403945cc91..cbfcf8e2d9 100644 --- a/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp @@ -1,6 +1,6 @@ /* * AES -* (C) 1999-2010,2015,2017 Jack Lloyd +* (C) 1999-2010,2015,2017,2018 Jack Lloyd * * Based on the public domain reference implementation by Paulo Baretto * @@ -18,14 +18,14 @@ * countermeasures are used which may be helpful in some situations: * * - Only a single 256-word T-table is used, with rotations applied. -* Most implementations use 4 T-tables which leaks much more -* information via cache usage. +* Most implementations use 4 (or sometimes 5) T-tables, which leaks +* much more information via cache usage. * * - The TE and TD tables are computed at runtime to avoid flush+reload * attacks using clflush. As different processes will not share the * same underlying table data, an attacker can't manipulate another * processes cache lines via their shared reference to the library -* read only segment. +* read only segment. (However, prime+probe attacks are still possible.) * * - Each cache line of the lookup tables is accessed at the beginning * of each call to encrypt or decrypt. (See the Z variable below) @@ -188,7 +188,6 @@ void aes_encrypt_n(const uint8_t in[], uint8_t out[], BOTAN_ASSERT(EK.size() && ME.size() == 16, "Key was set"); const size_t cache_line_size = CPUID::cache_line_size(); - const uint32_t* TE = AES_TE(); // Hit every cache line of TE @@ -269,6 +268,10 @@ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, { Z |= TD[i]; } + for(size_t i = 0; i < 256; i += cache_line_size) + { + Z |= SD[i]; + } Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce for(size_t i = 0; i != blocks; ++i) @@ -339,8 +342,24 @@ void aes_key_schedule(const uint8_t key[], size_t length, // Can't happen, but make static analyzers happy BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size"); + const uint32_t* TD = AES_TD(); + + // Prefetch TD and SE which are used later on in this function + volatile uint32_t Z = 0; + const size_t cache_line_size = CPUID::cache_line_size(); + + for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) + { + Z |= TD[i]; + } + for(size_t i = 0; i < 256; i += cache_line_size) + { + Z |= SE[i]; + } + Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce + for(size_t i = 0; i != X; ++i) - XEK[i] = load_be<uint32_t>(key, i); + XEK[i] = Z ^ load_be<uint32_t>(key, i); for(size_t i = X; i < 4*(rounds+1); i += X) { @@ -367,8 +386,8 @@ void aes_key_schedule(const uint8_t key[], size_t length, for(size_t i = 4; i != length + 24; ++i) { - XDK[i] = SE_word(XDK[i]); - XDK[i] = AES_T(AES_TD(), 0, XDK[i], XDK[i], XDK[i], XDK[i]); + XDK[i] = Z ^ SE_word(XDK[i]); + XDK[i] = AES_T(TD, 0, XDK[i], XDK[i], XDK[i], XDK[i]); } ME.resize(16); diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt index d5d3593489..0a2f19b3ad 100644 --- a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt @@ -2,6 +2,4 @@ AES_NI -> 20131128 </defines> -load_on auto - need_isa aesni diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt index 8457eed569..3446507f72 100644 --- a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt @@ -2,8 +2,6 @@ AES_SSSE3 -> 20131128 </defines> -load_on auto - need_isa ssse3 # Intel C++ can't deal with syntax for defining constants :( diff --git a/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp b/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp index 3ace6cd4f4..fb0564646e 100644 --- a/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp +++ b/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp @@ -98,12 +98,27 @@ #include <botan/internal/openssl.h> #endif +#if defined(BOTAN_HAS_COMMONCRYPTO) + #include <botan/internal/commoncrypto.h> +#endif + namespace Botan { std::unique_ptr<BlockCipher> BlockCipher::create(const std::string& algo, const std::string& provider) { +#if defined(BOTAN_HAS_COMMONCRYPTO) + if(provider.empty() || provider == "commoncrypto") + { + if(auto bc = make_commoncrypto_block_cipher(algo)) + return bc; + + if(!provider.empty()) + return nullptr; + } +#endif + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -115,7 +130,6 @@ BlockCipher::create(const std::string& algo, } #endif - // TODO: CommonCrypto // TODO: CryptoAPI // TODO: /dev/crypto @@ -343,7 +357,7 @@ BlockCipher::create_or_throw(const std::string& algo, std::vector<std::string> BlockCipher::providers(const std::string& algo) { - return probe_providers_of<BlockCipher>(algo, { "base", "openssl" }); + return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" }); } } diff --git a/src/libs/3rdparty/botan/src/lib/block/block_cipher.h b/src/libs/3rdparty/botan/src/lib/block/block_cipher.h index a365397fa3..5d490ae493 100644 --- a/src/libs/3rdparty/botan/src/lib/block/block_cipher.h +++ b/src/libs/3rdparty/botan/src/lib/block/block_cipher.h @@ -198,35 +198,51 @@ class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm }; /** +* Tweakable block ciphers allow setting a tweak which is a non-keyed +* value which affects the encryption/decryption operation. +*/ +class BOTAN_PUBLIC_API(2,8) Tweakable_Block_Cipher : public BlockCipher + { + public: + /** + * Set the tweak value. This must be called after setting a key. The value + * persists until either set_tweak, set_key, or clear is called. + * Different algorithms support different tweak length(s). If called with + * an unsupported length, Invalid_Argument will be thrown. + */ + virtual void set_tweak(const uint8_t tweak[], size_t len) = 0; + }; + +/** * Represents a block cipher with a single fixed block size */ -template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1> -class Block_Cipher_Fixed_Params : public BlockCipher +template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1, typename BaseClass = BlockCipher> +class Block_Cipher_Fixed_Params : public BaseClass { public: enum { BLOCK_SIZE = BS }; - size_t block_size() const override { return BS; } + size_t block_size() const final override { return BS; } // override to take advantage of compile time constant block size void encrypt_n_xex(uint8_t data[], const uint8_t mask[], - size_t blocks) const override + size_t blocks) const final override { xor_buf(data, mask, blocks * BS); - encrypt_n(data, data, blocks); + this->encrypt_n(data, data, blocks); xor_buf(data, mask, blocks * BS); } void decrypt_n_xex(uint8_t data[], const uint8_t mask[], - size_t blocks) const override + size_t blocks) const final override { xor_buf(data, mask, blocks * BS); - decrypt_n(data, data, blocks); + this->decrypt_n(data, data, blocks); xor_buf(data, mask, blocks * BS); } - Key_Length_Specification key_spec() const override + Key_Length_Specification key_spec() const final override { return Key_Length_Specification(KMIN, KMAX, KMOD); } diff --git a/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp index 7f52fb5afb..b3a8dde145 100644 --- a/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp +++ b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp @@ -6,30 +6,156 @@ */ #include <botan/base64.h> +#include <botan/internal/codec_base.h> #include <botan/exceptn.h> -#include <botan/mem_ops.h> #include <botan/internal/rounding.h> namespace Botan { namespace { -static const uint8_t BIN_TO_BASE64[64] = { +class Base64 final + { + public: + static inline size_t encoding_bytes_in() BOTAN_NOEXCEPT + { + return m_encoding_bytes_in; + } + static inline size_t encoding_bytes_out() BOTAN_NOEXCEPT + { + return m_encoding_bytes_out; + } + + static inline size_t decoding_bytes_in() BOTAN_NOEXCEPT + { + return m_encoding_bytes_out; + } + static inline size_t decoding_bytes_out() BOTAN_NOEXCEPT + { + return m_encoding_bytes_in; + } + + static inline size_t bits_consumed() BOTAN_NOEXCEPT + { + return m_encoding_bits; + } + static inline size_t remaining_bits_before_padding() BOTAN_NOEXCEPT + { + return m_remaining_bits_before_padding; + } + + static inline size_t encode_max_output(size_t input_length) + { + return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out; + } + static inline size_t decode_max_output(size_t input_length) + { + return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out; + } + + static void encode(char out[8], const uint8_t in[5]) BOTAN_NOEXCEPT + { + out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2]; + out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)]; + out[3] = Base64::m_bin_to_base64[in[2] & 0x3F]; + } + + static inline uint8_t lookup_binary_value(char input) BOTAN_NOEXCEPT + { + return Base64::m_base64_to_bin[static_cast<uint8_t>(input)]; + } + + static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws) + { + if(bin <= 0x3F) + { + return true; + } + else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws))) + { + std::string bad_char(1, input); + if(bad_char == "\t") + { bad_char = "\\t"; } + else if(bad_char == "\n") + { bad_char = "\\n"; } + else if(bad_char == "\r") + { bad_char = "\\r"; } + + throw Invalid_Argument( + std::string("base64_decode: invalid base64 character '") + + bad_char + "'"); + } + return false; + } + + static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4]) + { + out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); + out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); + out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; + } + + static inline size_t bytes_to_remove(size_t final_truncate) + { + return final_truncate; + } + + private: + static const size_t m_encoding_bits = 6; + static const size_t m_remaining_bits_before_padding = 8; + + + static const size_t m_encoding_bytes_in = 3; + static const size_t m_encoding_bytes_out = 4; + + + static const uint8_t m_bin_to_base64[64]; + static const uint8_t m_base64_to_bin[256]; + }; + +const uint8_t Base64::m_bin_to_base64[64] = + { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' -}; + }; -void do_base64_encode(char out[4], const uint8_t in[3]) +/* +* base64 Decoder Lookup Table +* Warning: assumes ASCII encodings +*/ +const uint8_t Base64::m_base64_to_bin[256] = { - out[0] = BIN_TO_BASE64[(in[0] & 0xFC) >> 2]; - out[1] = BIN_TO_BASE64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - out[2] = BIN_TO_BASE64[((in[1] & 0x0F) << 2) | (in[2] >> 6)]; - out[3] = BIN_TO_BASE64[in[2] & 0x3F]; - } - + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; } size_t base64_encode(char out[], @@ -38,58 +164,24 @@ size_t base64_encode(char out[], size_t& input_consumed, bool final_inputs) { - input_consumed = 0; - - size_t input_remaining = input_length; - size_t output_produced = 0; - - while(input_remaining >= 3) - { - do_base64_encode(out + output_produced, in + input_consumed); - - input_consumed += 3; - output_produced += 4; - input_remaining -= 3; - } - - if(final_inputs && input_remaining) - { - uint8_t remainder[3] = { 0 }; - for(size_t i = 0; i != input_remaining; ++i) - remainder[i] = in[input_consumed + i]; - - do_base64_encode(out + output_produced, remainder); - - size_t empty_bits = 8 * (3 - input_remaining); - size_t index = output_produced + 4 - 1; - while(empty_bits >= 8) - { - out[index--] = '='; - empty_bits -= 6; - } - - input_consumed += input_remaining; - output_produced += 4; - } - - return output_produced; + return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs); } std::string base64_encode(const uint8_t input[], size_t input_length) { - const size_t output_length = base64_encode_max_output(input_length); + const size_t output_length = Base64::encode_max_output(input_length); std::string output(output_length, 0); size_t consumed = 0; size_t produced = 0; - if (output_length > 0) - { + if(output_length > 0) + { produced = base64_encode(&output.front(), input, input_length, consumed, true); - } + } BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input"); BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size"); @@ -97,111 +189,14 @@ std::string base64_encode(const uint8_t input[], return output; } -size_t base64_decode(uint8_t output[], - const char input[], +size_t base64_decode(uint8_t out[], + const char in[], size_t input_length, size_t& input_consumed, bool final_inputs, bool ignore_ws) { - /* - * Base64 Decoder Lookup Table - * Warning: assumes ASCII encodings - */ - static const uint8_t BASE64_TO_BIN[256] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, - 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, - 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, - 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - uint8_t* out_ptr = output; - uint8_t decode_buf[4]; - size_t decode_buf_pos = 0; - size_t final_truncate = 0; - - clear_mem(output, input_length * 3 / 4); - - for(size_t i = 0; i != input_length; ++i) - { - const uint8_t bin = BASE64_TO_BIN[static_cast<uint8_t>(input[i])]; - - if(bin <= 0x3F) - { - decode_buf[decode_buf_pos] = bin; - decode_buf_pos += 1; - } - else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws))) - { - std::string bad_char(1, input[i]); - if(bad_char == "\t") - bad_char = "\\t"; - else if(bad_char == "\n") - bad_char = "\\n"; - else if(bad_char == "\r") - bad_char = "\\r"; - - throw Invalid_Argument( - std::string("base64_decode: invalid base64 character '") + - bad_char + "'"); - } - - /* - * If we're at the end of the input, pad with 0s and truncate - */ - if(final_inputs && (i == input_length - 1)) - { - if(decode_buf_pos) - { - for(size_t j = decode_buf_pos; j != 4; ++j) - decode_buf[j] = 0; - final_truncate = (4 - decode_buf_pos); - decode_buf_pos = 4; - } - } - - if(decode_buf_pos == 4) - { - out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); - out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); - out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; - - out_ptr += 3; - decode_buf_pos = 0; - input_consumed = i+1; - } - } - - while(input_consumed < input_length && - BASE64_TO_BIN[static_cast<uint8_t>(input[input_consumed])] == 0x80) - { - ++input_consumed; - } - - size_t written = (out_ptr - output) - final_truncate; - - return written; + return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws); } size_t base64_decode(uint8_t output[], @@ -214,7 +209,7 @@ size_t base64_decode(uint8_t output[], consumed, true, ignore_ws); if(consumed != input_length) - throw Invalid_Argument("base64_decode: input did not have full bytes"); + { throw Invalid_Argument("base64_decode: input did not have full bytes"); } return written; } @@ -227,10 +222,10 @@ size_t base64_decode(uint8_t output[], } secure_vector<uint8_t> base64_decode(const char input[], - size_t input_length, - bool ignore_ws) + size_t input_length, + bool ignore_ws) { - const size_t output_length = base64_decode_max_output(input_length); + const size_t output_length = Base64::decode_max_output(input_length); secure_vector<uint8_t> bin(output_length); size_t written = base64_decode(bin.data(), @@ -243,19 +238,19 @@ secure_vector<uint8_t> base64_decode(const char input[], } secure_vector<uint8_t> base64_decode(const std::string& input, - bool ignore_ws) + bool ignore_ws) { return base64_decode(input.data(), input.size(), ignore_ws); } size_t base64_encode_max_output(size_t input_length) { - return (round_up(input_length, 3) / 3) * 4; + return Base64::encode_max_output(input_length); } size_t base64_decode_max_output(size_t input_length) { - return (round_up(input_length, 4) * 3) / 4; + return Base64::decode_max_output(input_length); } } diff --git a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp deleted file mode 100644 index 1e36136155..0000000000 --- a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -* Darwin SecRandomCopyBytes EntropySource -* (C) 2015 Daniel Seither (Kullo GmbH) -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/internal/darwin_secrandom.h> -#include <Security/Security.h> -#include <Security/SecRandom.h> - -namespace Botan { - -/** -* Gather entropy from SecRandomCopyBytes -*/ -size_t Darwin_SecRandom::poll(RandomNumberGenerator& rng) - { - secure_vector<uint8_t> buf(BOTAN_SYSTEM_RNG_POLL_REQUEST); - - if(0 == SecRandomCopyBytes(kSecRandomDefault, buf.size(), buf.data())) - { - rng.add_entropy(buf.data(), buf.size()); - return buf.size() * 8; - } - - return 0; - } - -} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.h b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.h deleted file mode 100644 index 83b4da4f50..0000000000 --- a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* Darwin SecRandomCopyBytes EntropySource -* (C) 2015 Daniel Seither (Kullo GmbH) -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H_ -#define BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H_ - -#include <botan/entropy_src.h> - -namespace Botan { - -/** -* Entropy source using SecRandomCopyBytes from Darwin's Security.framework -*/ -class Darwin_SecRandom final : public Entropy_Source - { - public: - std::string name() const override { return "darwin_secrandom"; } - - size_t poll(RandomNumberGenerator& rng) override; - }; - -} - -#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/info.txt deleted file mode 100644 index c1943a04a4..0000000000 --- a/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/info.txt +++ /dev/null @@ -1,16 +0,0 @@ -<defines> -ENTROPY_SRC_DARWIN_SECRANDOM -> 20150925 -</defines> - -<header:internal> -darwin_secrandom.h -</header:internal> - -<os_features> -security_framework -</os_features> - -<frameworks> -darwin -> Security -ios -> Security -</frameworks> diff --git a/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp b/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp index c04b3b5b26..85e0b6dc5d 100644 --- a/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp +++ b/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp @@ -30,10 +30,7 @@ #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) #include <botan/internal/proc_walk.h> -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) - #include <botan/internal/darwin_secrandom.h> + #include <botan/internal/os_utils.h> #endif #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) @@ -86,13 +83,6 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name) } #endif -#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) - if(name == "darwin_secrandom") - { - return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom); - } -#endif - #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) if(name == "getentropy") { @@ -108,7 +98,7 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name) #endif #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) - if(name == "proc_walk") + if(name == "proc_walk" && OS::running_in_privileged_state() == false) { const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH; if(!root_dir.empty()) diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp index 6a5b0f7c44..b8a74ce2f6 100644 --- a/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp @@ -8,12 +8,12 @@ #include <botan/internal/rdrand.h> #include <botan/rdrand_rng.h> -#include <botan/cpuid.h> namespace Botan { -size_t Intel_Rdrand::poll(RandomNumberGenerator& rng) { - if(CPUID::has_rdrand() && BOTAN_ENTROPY_INTEL_RNG_POLLS > 0) +size_t Intel_Rdrand::poll(RandomNumberGenerator& rng) + { + if(BOTAN_ENTROPY_INTEL_RNG_POLLS > 0 && RDRAND_RNG::available()) { RDRAND_RNG rdrand_rng; secure_vector<uint8_t> buf(4 * BOTAN_ENTROPY_INTEL_RNG_POLLS); diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp index fbb8f921e7..fccc53f6a1 100644 --- a/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp @@ -15,7 +15,8 @@ namespace Botan { BOTAN_FUNC_ISA("rdseed") -size_t Intel_Rdseed::poll(RandomNumberGenerator& rng) { +size_t Intel_Rdseed::poll(RandomNumberGenerator& rng) + { if(CPUID::has_rdseed()) { for(size_t p = 0; p != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++p) diff --git a/src/libs/3rdparty/botan/src/lib/filters/filter.h b/src/libs/3rdparty/botan/src/lib/filters/filter.h index a0857c589e..94b9c6ccd0 100644 --- a/src/libs/3rdparty/botan/src/lib/filters/filter.h +++ b/src/libs/3rdparty/botan/src/lib/filters/filter.h @@ -67,28 +67,20 @@ class BOTAN_PUBLIC_API(2,0) Filter /** * @param in some input for the filter */ - void send(const secure_vector<uint8_t>& in) { send(in.data(), in.size()); } - - /** - * @param in some input for the filter - */ - void send(const std::vector<uint8_t>& in) { send(in.data(), in.size()); } - - /** - * @param in some input for the filter - * @param length the number of bytes of in to send - */ - void send(const secure_vector<uint8_t>& in, size_t length) + template<typename Alloc> + void send(const std::vector<uint8_t, Alloc>& in) { - send(in.data(), length); + send(in.data(), in.size()); } /** * @param in some input for the filter * @param length the number of bytes of in to send */ - void send(const std::vector<uint8_t>& in, size_t length) + template<typename Alloc> + void send(const std::vector<uint8_t, Alloc>& in, size_t length) { + BOTAN_ASSERT_NOMSG(length <= in.size()); send(in.data(), length); } diff --git a/src/libs/3rdparty/botan/src/lib/hash/hash.cpp b/src/libs/3rdparty/botan/src/lib/hash/hash.cpp index e30d000802..ad1a1bf0c3 100644 --- a/src/libs/3rdparty/botan/src/lib/hash/hash.cpp +++ b/src/libs/3rdparty/botan/src/lib/hash/hash.cpp @@ -101,11 +101,27 @@ #include <botan/internal/openssl.h> #endif +#if defined(BOTAN_HAS_COMMONCRYPTO) + #include <botan/internal/commoncrypto.h> +#endif + namespace Botan { std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec, const std::string& provider) { + +#if defined(BOTAN_HAS_COMMONCRYPTO) + if(provider.empty() || provider == "commoncrypto") + { + if(auto hash = make_commoncrypto_hash(algo_spec)) + return hash; + + if(!provider.empty()) + return nullptr; + } +#endif + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -128,8 +144,6 @@ std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec, } #endif - // TODO: CommonCrypto hashes - if(provider.empty() == false && provider != "base") return nullptr; // unknown provider @@ -354,7 +368,7 @@ HashFunction::create_or_throw(const std::string& algo, std::vector<std::string> HashFunction::providers(const std::string& algo_spec) { - return probe_providers_of<HashFunction>(algo_spec, {"base", "bearssl", "openssl"}); + return probe_providers_of<HashFunction>(algo_spec, {"base", "bearssl", "openssl", "commoncrypto"}); } } diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp index 9da48c9fec..3dc9f43d85 100644 --- a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp @@ -20,15 +20,14 @@ namespace Botan { BOTAN_FUNC_ISA("+crypto") void SHA_160::sha1_armv8_compress_n(secure_vector<uint32_t>& digest, const uint8_t input8[], size_t blocks) { - uint32x4_t C0, C1, C2, C3; - uint32x4_t ABCD, ABCD_SAVED; - uint32_t E0, E0_SAVED, E1; + uint32x4_t ABCD; + uint32_t E0; - // Load initial values - C0 = vdupq_n_u32(0x5A827999); - C1 = vdupq_n_u32(0x6ED9EBA1); - C2 = vdupq_n_u32(0x8F1BBCDC); - C3 = vdupq_n_u32(0xCA62C1D6); + // Load magic constants + const uint32x4_t C0 = vdupq_n_u32(0x5A827999); + const uint32x4_t C1 = vdupq_n_u32(0x6ED9EBA1); + const uint32x4_t C2 = vdupq_n_u32(0x8F1BBCDC); + const uint32x4_t C3 = vdupq_n_u32(0xCA62C1D6); ABCD = vld1q_u32(&digest[0]); E0 = digest[4]; @@ -38,12 +37,13 @@ void SHA_160::sha1_armv8_compress_n(secure_vector<uint32_t>& digest, const uint8 while (blocks) { + // Save current hash + const uint32x4_t ABCD_SAVED = ABCD; + const uint32_t E0_SAVED = E0; + uint32x4_t MSG0, MSG1, MSG2, MSG3; uint32x4_t TMP0, TMP1; - - // Save current hash - ABCD_SAVED = ABCD; - E0_SAVED = E0; + uint32_t E1; MSG0 = vld1q_u32(input32 + 0); MSG1 = vld1q_u32(input32 + 4); diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp index c428199659..8fd528a146 100644 --- a/src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp @@ -12,6 +12,42 @@ namespace Botan { +std::string BigInt::to_dec_string() const + { + BigInt copy = *this; + copy.set_sign(Positive); + + BigInt remainder; + std::vector<uint8_t> digits; + + while(copy > 0) + { + divide(copy, 10, copy, remainder); + digits.push_back(static_cast<uint8_t>(remainder.word_at(0))); + } + + std::string s; + + for(auto i = digits.rbegin(); i != digits.rend(); ++i) + { + s.push_back(Charset::digit2char(*i)); + } + + if(s.empty()) + s += "0"; + + return s; + } + +std::string BigInt::to_hex_string() const + { + const std::vector<uint8_t> bits = BigInt::encode(*this); + if(bits.empty()) + return "00"; + else + return hex_encode(bits); + } + /* * Encode a BigInt */ @@ -53,12 +89,15 @@ void BigInt::encode(uint8_t output[], const BigInt& n, Base base) */ std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base) { + if(base == Binary) + return BigInt::encode(n); + std::vector<uint8_t> output(n.encoded_size(base)); encode(output.data(), n, base); - if(base != Binary) - for(size_t j = 0; j != output.size(); ++j) - if(output[j] == 0) - output[j] = '0'; + for(size_t j = 0; j != output.size(); ++j) + if(output[j] == 0) + output[j] = '0'; + return output; } @@ -67,12 +106,15 @@ std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base) */ secure_vector<uint8_t> BigInt::encode_locked(const BigInt& n, Base base) { + if(base == Binary) + return BigInt::encode_locked(n); + secure_vector<uint8_t> output(n.encoded_size(base)); encode(output.data(), n, base); - if(base != Binary) - for(size_t j = 0; j != output.size(); ++j) - if(output[j] == 0) - output[j] = '0'; + for(size_t j = 0; j != output.size(); ++j) + if(output[j] == 0) + output[j] = '0'; + return output; } diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp index 492a69ad05..3f34e0bf15 100644 --- a/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp @@ -126,6 +126,24 @@ BigInt operator*(const BigInt& x, const BigInt& y) } /* +* Multiplication Operator +*/ +BigInt operator*(const BigInt& x, word y) + { + const size_t x_sw = x.sig_words(); + + BigInt z(BigInt::Positive, x_sw + 1); + + if(x_sw && y) + { + bigint_linmul3(z.mutable_data(), x.data(), x_sw, y); + z.set_sign(x.sign()); + } + + return z; + } + +/* * Division Operator */ BigInt operator/(const BigInt& x, const BigInt& y) diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp index 495907d1ab..36f1d2883d 100644 --- a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp @@ -96,7 +96,7 @@ BigInt::BigInt(const uint8_t input[], size_t length, Base base) BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits) { const size_t max_bytes = std::min(length, (max_bits + 7) / 8); - *this = decode(buf, max_bytes); + binary_decode(buf, max_bytes); const size_t b = this->bits(); if(b > max_bits) @@ -163,18 +163,19 @@ void BigInt::encode_words(word out[], size_t size) const */ uint32_t BigInt::get_substring(size_t offset, size_t length) const { - if(length > 32) - throw Invalid_Argument("BigInt::get_substring: Substring size " + std::to_string(length) + " too big"); + if(length == 0 || length > 32) + throw Invalid_Argument("BigInt::get_substring invalid substring length"); - uint64_t piece = 0; - for(size_t i = 0; i != 8; ++i) - { - const uint8_t part = byte_at((offset / 8) + (7-i)); - piece = (piece << 8) | part; - } - - const uint64_t mask = (static_cast<uint64_t>(1) << length) - 1; + const size_t byte_offset = offset / 8; const size_t shift = (offset % 8); + const uint32_t mask = 0xFFFFFFFF >> (32 - length); + + const uint8_t b0 = byte_at(byte_offset); + const uint8_t b1 = byte_at(byte_offset + 1); + const uint8_t b2 = byte_at(byte_offset + 2); + const uint8_t b3 = byte_at(byte_offset + 3); + const uint8_t b4 = byte_at(byte_offset + 4); + const uint64_t piece = make_uint64(0, 0, 0, b4, b3, b2, b1, b0); return static_cast<uint32_t>((piece >> shift) & mask); } @@ -341,6 +342,21 @@ void BigInt::binary_decode(const uint8_t buf[], size_t length) m_reg[length / WORD_BYTES] = (m_reg[length / WORD_BYTES] << 8) | buf[i]; } +void BigInt::ct_cond_assign(bool predicate, BigInt& other) + { + const size_t t_words = size(); + const size_t o_words = other.size(); + + const size_t r_words = std::max(t_words, o_words); + + const word mask = CT::expand_mask<word>(predicate); + + for(size_t i = 0; i != r_words; ++i) + { + this->set_word_at(i, CT::select<word>(mask, other.word_at(i), this->word_at(i))); + } + } + #if defined(BOTAN_HAS_VALGRIND) void BigInt::const_time_poison() const { diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h index 4a07723b77..8a434e6bb6 100644 --- a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h @@ -79,6 +79,13 @@ class BOTAN_PUBLIC_API(2,0) BigInt final /** * Create a BigInt from an integer in a byte array + * @param vec the byte vector holding the value + */ + template<typename Alloc> + explicit BigInt(const std::vector<uint8_t, Alloc>& vec) : BigInt(vec.data(), vec.size()) {} + + /** + * Create a BigInt from an integer in a byte array * @param buf the byte array holding the value * @param length size of buf * @param base is the number base of the integer in buf @@ -423,6 +430,17 @@ class BOTAN_PUBLIC_API(2,0) BigInt final uint32_t to_u32bit() const; /** + * Convert this value to a decimal string. + * Warning: decimal conversions are relatively slow + */ + std::string to_dec_string() const; + + /** + * Convert this value to a hexadecimal string. + */ + std::string to_hex_string() const; + + /** * @param n the offset to get a byte from * @result byte at offset n */ @@ -616,6 +634,12 @@ class BOTAN_PUBLIC_API(2,0) BigInt final */ void encode_words(word out[], size_t size) const; + /** + * If predicate is true assign other to *this + * Uses a masked operation to avoid side channels + */ + void ct_cond_assign(bool predicate, BigInt& other); + #if defined(BOTAN_HAS_VALGRIND) void const_time_poison() const; void const_time_unpoison() const; @@ -649,10 +673,75 @@ class BOTAN_PUBLIC_API(2,0) BigInt final /** * Encode the integer value from a BigInt to a std::vector of bytes * @param n the BigInt to use as integer source + * @result secure_vector of bytes containing the bytes of the integer + */ + static std::vector<uint8_t> encode(const BigInt& n) + { + std::vector<uint8_t> output(n.bytes()); + n.binary_encode(output.data()); + return output; + } + + /** + * Encode the integer value from a BigInt to a secure_vector of bytes + * @param n the BigInt to use as integer source + * @result secure_vector of bytes containing the bytes of the integer + */ + static secure_vector<uint8_t> encode_locked(const BigInt& n) + { + secure_vector<uint8_t> output(n.bytes()); + n.binary_encode(output.data()); + return output; + } + + /** + * Encode the integer value from a BigInt to a byte array + * @param buf destination byte array for the encoded integer + * @param n the BigInt to use as integer source + */ + static void encode(uint8_t buf[], const BigInt& n) + { + n.binary_encode(buf); + } + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @param length size of buf + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const uint8_t buf[], size_t length) + { + return BigInt(buf, length); + } + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const secure_vector<uint8_t>& buf) + { + return BigInt(buf); + } + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const std::vector<uint8_t>& buf) + { + return BigInt(buf); + } + + /** + * Encode the integer value from a BigInt to a std::vector of bytes + * @param n the BigInt to use as integer source * @param base number-base of resulting byte array representation * @result secure_vector of bytes containing the integer with given base */ - static std::vector<uint8_t> encode(const BigInt& n, Base base = Binary); + static std::vector<uint8_t> encode(const BigInt& n, Base base); /** * Encode the integer value from a BigInt to a secure_vector of bytes @@ -661,7 +750,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @result secure_vector of bytes containing the integer with given base */ static secure_vector<uint8_t> encode_locked(const BigInt& n, - Base base = Binary); + Base base); /** * Encode the integer value from a BigInt to a byte array @@ -670,7 +759,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param n the BigInt to use as integer source * @param base number-base of resulting byte array representation */ - static void encode(uint8_t buf[], const BigInt& n, Base base = Binary); + static void encode(uint8_t buf[], const BigInt& n, Base base); /** * Create a BigInt from an integer in a byte array @@ -680,7 +769,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @result BigInt representing the integer in the byte array */ static BigInt decode(const uint8_t buf[], size_t length, - Base base = Binary); + Base base); /** * Create a BigInt from an integer in a byte array @@ -689,8 +778,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @result BigInt representing the integer in the byte array */ static BigInt decode(const secure_vector<uint8_t>& buf, - Base base = Binary) + Base base) { + if(base == Binary) + return BigInt(buf); return BigInt::decode(buf.data(), buf.size(), base); } @@ -700,9 +791,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param base number-base of the integer in buf * @result BigInt representing the integer in the byte array */ - static BigInt decode(const std::vector<uint8_t>& buf, - Base base = Binary) + static BigInt decode(const std::vector<uint8_t>& buf, Base base) { + if(base == Binary) + return BigInt(buf); return BigInt::decode(buf.data(), buf.size(), base); } @@ -750,6 +842,9 @@ BigInt BOTAN_PUBLIC_API(2,0) operator-(const BigInt& x, const BigInt& y); BigInt BOTAN_PUBLIC_API(2,7) operator-(const BigInt& x, word y); BigInt BOTAN_PUBLIC_API(2,0) operator*(const BigInt& x, const BigInt& y); +BigInt BOTAN_PUBLIC_API(2,8) operator*(const BigInt& x, word y); +inline BigInt operator*(word x, const BigInt& y) { return y*x; } + BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, const BigInt& d); BigInt BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, const BigInt& m); word BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m); diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt b/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt index e84061bb6d..974366b810 100644 --- a/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt @@ -2,8 +2,6 @@ BIGINT -> 20131128 </defines> -load_on auto - <header:public> bigint.h divide.h diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp b/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp index 2ae65e508f..5dbf3558a3 100644 --- a/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp @@ -353,11 +353,33 @@ void bigint_shl1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) } } +namespace { + +void bigint_shift_right_1(word x[], size_t x_size) + { + word carry = 0; + size_t top = x_size; + + while(top) + { + word w = x[top-1]; + x[top-1] = (w >> 1) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - 1)); + + top--; + } + } + +} + /* * Single Operand Right Shift */ void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) { + if(word_shift == 0 && bit_shift == 1) + return bigint_shift_right_1(x, x_size); + if(x_size < word_shift) { clear_mem(x, x_size); diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h b/src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h index 4807fcd040..43c769c7c8 100644 --- a/src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h @@ -14,15 +14,10 @@ namespace Botan { -#if (BOTAN_MP_WORD_BITS == 8) - typedef uint16_t dword; - #define BOTAN_HAS_MP_DWORD -#elif (BOTAN_MP_WORD_BITS == 16) - typedef uint32_t dword; - #define BOTAN_HAS_MP_DWORD -#elif (BOTAN_MP_WORD_BITS == 32) +#if (BOTAN_MP_WORD_BITS == 32) typedef uint64_t dword; #define BOTAN_HAS_MP_DWORD + #elif (BOTAN_MP_WORD_BITS == 64) #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) typedef uint128_t dword; @@ -32,21 +27,19 @@ namespace Botan { #endif #else - #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64 + #error BOTAN_MP_WORD_BITS must be 32 or 64 #endif #if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32) #if defined(BOTAN_USE_GCC_INLINE_ASM) #define BOTAN_MP_USE_X86_32_ASM - #define ASM(x) x "\n\t" #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) #define BOTAN_MP_USE_X86_32_MSVC_ASM #endif #elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && (BOTAN_USE_GCC_INLINE_ASM) #define BOTAN_MP_USE_X86_64_ASM - #define ASM(x) x "\n\t" #endif #if defined(BOTAN_MP_USE_X86_32_ASM) || defined(BOTAN_MP_USE_X86_64_ASM) diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h index c9936a338b..710b06deca 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h @@ -23,8 +23,6 @@ namespace Botan { BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521(); BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector<word>& ws); -#if (BOTAN_MP_WORD_BITS == 32) || (BOTAN_MP_WORD_BITS == 64) - #define BOTAN_HAS_NIST_PRIME_REDUCERS_W32 BOTAN_PUBLIC_API(2,0) const BigInt& prime_p384(); @@ -39,8 +37,6 @@ BOTAN_PUBLIC_API(2,0) void redc_p224(BigInt& x, secure_vector<word>& ws); BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192(); BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector<word>& ws); -#endif - } #endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt b/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt index 8da52f9f43..0ebd1e05fc 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt @@ -2,8 +2,6 @@ NUMBERTHEORY -> 20131128 </defines> -load_on auto - <header:public> curve_nistp.h numthry.h @@ -13,6 +11,7 @@ monty.h </header:public> <header:internal> +primality.h def_powm.h monty_exp.h </header:internal> diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp index d3e8d75572..284fc2b204 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp @@ -14,12 +14,11 @@ namespace Botan { */ int32_t jacobi(const BigInt& a, const BigInt& n) { - if(a.is_negative()) - throw Invalid_Argument("jacobi: first argument must be non-negative"); if(n.is_even() || n < 2) throw Invalid_Argument("jacobi: second argument must be odd and > 1"); - BigInt x = a, y = n; + BigInt x = a % n; + BigInt y = n; int32_t J = 1; while(y > 1) diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp index 1979fa5502..2333e2c931 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp @@ -14,7 +14,7 @@ namespace Botan { namespace { -class Prime_Sieve +class Prime_Sieve final { public: Prime_Sieve(const BigInt& init_value) : m_sieve(PRIME_TABLE_SIZE) diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp index b91560fd58..61a10eae5e 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp @@ -13,7 +13,7 @@ namespace Botan { Montgomery_Params::Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p) { - if(p.is_negative() || p.is_even()) + if(p.is_even() || p < 3) throw Invalid_Argument("Montgomery_Params invalid modulus"); m_p = p; diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp index 5674920915..2b5bbd81dc 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp @@ -44,7 +44,7 @@ Montgomery_Exponentation_State::Montgomery_Exponentation_State(std::shared_ptr<c if(m_window_bits < 1 || m_window_bits > 12) // really even 8 is too large ... throw Invalid_Argument("Invalid window bits for Montgomery exponentiation"); - const size_t window_size = (1U << m_window_bits); + const size_t window_size = (static_cast<size_t>(1) << m_window_bits); m_g.reserve(window_size); @@ -233,10 +233,10 @@ BigInt monty_multi_exp(std::shared_ptr<const Montgomery_Params> params_p, H.square_this(ws); } - const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2); - const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2); + const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2); + const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2); - const uint8_t z12 = (4*z2_b) + z1_b; + const uint32_t z12 = (4*z2_b) + z1_b; H.mul_by(*M[z12], ws); } diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp index b74a2f9c6b..ba0c5142d7 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp @@ -43,7 +43,7 @@ void redc_p521(BigInt& x, secure_vector<word>& ws) BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction"); // Now find the actual carry in bit 522 - const uint8_t bit_522_set = x.word_at(p_full_words) >> (p_top_bits); + const word bit_522_set = x.word_at(p_full_words) >> p_top_bits; #if (BOTAN_MP_WORD_BITS == 64) static const word p521_words[9] = { @@ -91,10 +91,8 @@ inline uint32_t get_uint32_t(const BigInt& x, size_t i) { #if (BOTAN_MP_WORD_BITS == 32) return x.word_at(i); -#elif (BOTAN_MP_WORD_BITS == 64) - return static_cast<uint32_t>(x.word_at(i/2) >> ((i % 2)*32)); #else - #error "Not implemented" + return static_cast<uint32_t>(x.word_at(i/2) >> ((i % 2)*32)); #endif } @@ -103,10 +101,8 @@ inline void set_words(BigInt& x, size_t i, uint32_t R0, uint32_t R1) #if (BOTAN_MP_WORD_BITS == 32) x.set_word_at(i, R0); x.set_word_at(i+1, R1); -#elif (BOTAN_MP_WORD_BITS == 64) - x.set_word_at(i/2, (static_cast<uint64_t>(R1) << 32) | R0); #else - #error "Not implemented" + x.set_word_at(i/2, (static_cast<uint64_t>(R1) << 32) | R0); #endif } diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp index a312ba3a1c..5bf649407a 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp @@ -14,6 +14,7 @@ #include <botan/internal/mp_core.h> #include <botan/internal/ct_utils.h> #include <botan/internal/monty_exp.h> +#include <botan/internal/primality.h> #include <algorithm> namespace Botan { @@ -434,78 +435,43 @@ BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) } } -namespace { -bool mr_witness(BigInt&& y, - const Modular_Reducer& reducer_n, - const BigInt& n_minus_1, size_t s) +BigInt is_perfect_square(const BigInt& C) { - if(y == 1 || y == n_minus_1) - return false; - - for(size_t i = 1; i != s; ++i) - { - y = reducer_n.square(y); - - if(y == 1) // found a non-trivial square root - return true; - - /* - -1 is the trivial square root of unity, so ``a`` is not a - witness for this number - give up - */ - if(y == n_minus_1) - return false; - } - - return true; // is a witness - } + if(C < 1) + throw Invalid_Argument("is_perfect_square requires C >= 1"); + if(C == 1) + return 1; -size_t mr_test_iterations(size_t n_bits, size_t prob, bool random) - { - const size_t base = (prob + 2) / 2; // worst case 4^-t error rate + const size_t n = C.bits(); + const size_t m = (n + 1) / 2; + const BigInt B = C + BigInt::power_of_2(m); - /* - * If the candidate prime was maliciously constructed, we can't rely - * on arguments based on p being random. - */ - if(random == false) - return base; + BigInt X = BigInt::power_of_2(m) - 1; + BigInt X2 = (X*X); - /* - * For randomly chosen numbers we can use the estimates from - * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf - * - * These values are derived from the inequality for p(k,t) given on - * the second page. - */ - if(prob <= 128) + for(;;) { - if(n_bits >= 1536) - return 4; // < 2^-133 - if(n_bits >= 1024) - return 6; // < 2^-133 - if(n_bits >= 512) - return 12; // < 2^-129 - if(n_bits >= 256) - return 29; // < 2^-128 + X = (X2 + C) / (2*X); + X2 = (X*X); + + if(X2 < B) + break; } - /* - If the user desires a smaller error probability than we have - precomputed error estimates for, just fall back to using the worst - case error rate. - */ - return base; + if(X2 == C) + return X; + else + return 0; } -} - /* * Test for primality using Miller-Rabin */ -bool is_prime(const BigInt& n, RandomNumberGenerator& rng, - size_t prob, bool is_random) +bool is_prime(const BigInt& n, + RandomNumberGenerator& rng, + size_t prob, + bool is_random) { if(n == 2) return true; @@ -520,47 +486,21 @@ bool is_prime(const BigInt& n, RandomNumberGenerator& rng, return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num); } - const size_t test_iterations = - mr_test_iterations(n.bits(), prob, is_random && rng.is_seeded()); - - const BigInt n_minus_1 = n - 1; - const size_t s = low_zero_bits(n_minus_1); - const BigInt nm1_s = n_minus_1 >> s; - const size_t n_bits = n.bits(); + const size_t t = miller_rabin_test_iterations(n.bits(), prob, is_random); - const Modular_Reducer mod_n(n); - auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n); + Modular_Reducer mod_n(n); - const size_t powm_window = 4; - - for(size_t i = 0; i != test_iterations; ++i) + if(rng.is_seeded()) { - BigInt a; - - if(rng.is_seeded()) - { - a = BigInt::random_integer(rng, 2, n_minus_1); - } - else - { - /* - * If passed a null RNG just use 2,3,5, ... as bases - * - * This is not ideal but in certain circumstances we need to - * test for primality but have no RNG available. - */ - a = PRIMES[i]; - } - - auto powm_a_n = monty_precompute(monty_n, a, powm_window); - - BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits); - - if(mr_witness(std::move(y), mod_n, n_minus_1, s)) + if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false) return false; - } - return true; + return is_lucas_probable_prime(n, mod_n); + } + else + { + return is_bailie_psw_probable_prime(n, mod_n); + } } } diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h index 7097979bd7..7a978cd3f9 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h @@ -1,6 +1,6 @@ /* * Number Theory Functions -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -22,8 +22,8 @@ class RandomNumberGenerator; * @return (a*b)+c */ BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a, - const BigInt& b, - const BigInt& c); + const BigInt& b, + const BigInt& c); /** * Fused subtract-multiply @@ -33,8 +33,8 @@ BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a, * @return (a-b)*c */ BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a, - const BigInt& b, - const BigInt& c); + const BigInt& b, + const BigInt& c); /** * Fused multiply-subtract @@ -44,8 +44,8 @@ BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a, * @return (a*b)-c */ BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a, - const BigInt& b, - const BigInt& c); + const BigInt& b, + const BigInt& c); /** * Return the absolute value @@ -108,8 +108,8 @@ BigInt BOTAN_PUBLIC_API(2,0) ct_inverse_mod_odd_modulus(const BigInt& n, const B * Not const time */ size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result, - const BigInt& a, - const BigInt& b); + const BigInt& a, + const BigInt& b); /** * Call almost_montgomery_inverse and correct the result to a^-1 mod b @@ -126,8 +126,7 @@ BigInt BOTAN_PUBLIC_API(2,0) normalized_montgomery_inverse(const BigInt& a, cons * @param n is an odd integer > 1 * @return (n / m) */ -int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, - const BigInt& n); +int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, const BigInt& n); /** * Modular exponentation @@ -137,8 +136,8 @@ int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, * @return (b^x) % m */ BigInt BOTAN_PUBLIC_API(2,0) power_mod(const BigInt& b, - const BigInt& x, - const BigInt& m); + const BigInt& x, + const BigInt& m); /** * Compute the square root of x modulo a prime using the @@ -175,9 +174,18 @@ size_t BOTAN_PUBLIC_API(2,0) low_zero_bits(const BigInt& x); */ bool BOTAN_PUBLIC_API(2,0) is_prime(const BigInt& n, RandomNumberGenerator& rng, - size_t prob = 56, + size_t prob = 64, bool is_random = false); +/** +* Test if the positive integer x is a perfect square ie if there +* exists some positive integer y st y*y == x +* See FIPS 186-4 sec C.4 +* @return 0 if the integer is not a perfect square, otherwise +* returns the positive y st y*y == x +*/ +BigInt BOTAN_PUBLIC_API(2,8) is_perfect_square(const BigInt& x); + inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) { return is_prime(n, rng, 32); } @@ -187,7 +195,6 @@ inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) { return is_prime(n, rng, 80); } - /** * Randomly generate a prime suitable for discrete logarithm parameters * @param rng a random number generator diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp index 85a0364b5a..c326ffa441 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp @@ -25,7 +25,7 @@ void Fixed_Window_Exponentiator::set_base(const BigInt& base) { m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints); - m_g.resize(1U << m_window_bits); + m_g.resize(static_cast<size_t>(1) << m_window_bits); m_g[0] = 1; m_g[1] = base; diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.cpp new file mode 100644 index 0000000000..5e683c1ff0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.cpp @@ -0,0 +1,206 @@ +/* +* (C) 2016,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/primality.h> +#include <botan/internal/monty_exp.h> +#include <botan/bigint.h> +#include <botan/monty.h> +#include <botan/reducer.h> +#include <botan/rng.h> +#include <algorithm> + +namespace Botan { + +bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) + { + if(C <= 1) + return false; + else if(C == 2) + return true; + else if(C.is_even()) + return false; + else if(C == 3 || C == 5 || C == 7 || C == 11 || C == 13) + return true; + + BigInt D = 5; + + for(;;) + { + int32_t j = jacobi(D, C); + if(j == 0) + return false; + + if(j == -1) + break; + + // Check 5, -7, 9, -11, 13, -15, 17, ... + if(D.is_negative()) + { + D.flip_sign(); + D += 2; + } + else + { + D += 2; + D.flip_sign(); + } + + if(D == 17 && is_perfect_square(C).is_nonzero()) + return false; + } + + const BigInt K = C + 1; + const size_t K_bits = K.bits() - 1; + + BigInt U = 1; + BigInt V = 1; + + BigInt Ut, Vt, U2, V2; + + for(size_t i = 0; i != K_bits; ++i) + { + const uint8_t k_bit = K.get_bit(K_bits - 1 - i); + + Ut = mod_C.multiply(U, V); + + Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U))); + if(Vt.is_odd()) + Vt += C; + Vt >>= 1; + Vt = mod_C.reduce(Vt); + + U = Ut; + V = Vt; + + U2 = mod_C.reduce(Ut + Vt); + if(U2.is_odd()) + U2 += C; + U2 >>= 1; + + V2 = mod_C.reduce(Vt + Ut*D); + if(V2.is_odd()) + V2 += C; + V2 >>= 1; + + U.ct_cond_assign(k_bit, U2); + V.ct_cond_assign(k_bit, V2); + } + + return (U == 0); + } + +bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n) + { + auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n); + return passes_miller_rabin_test(n, mod_n, monty_n, 2) && is_lucas_probable_prime(n, mod_n); + } + +bool is_bailie_psw_probable_prime(const BigInt& n) + { + Modular_Reducer mod_n(n); + return is_bailie_psw_probable_prime(n, mod_n); + } + +bool passes_miller_rabin_test(const BigInt& n, + const Modular_Reducer& mod_n, + const std::shared_ptr<Montgomery_Params>& monty_n, + const BigInt& a) + { + BOTAN_ASSERT_NOMSG(n > 1); + + const BigInt n_minus_1 = n - 1; + const size_t s = low_zero_bits(n_minus_1); + const BigInt nm1_s = n_minus_1 >> s; + const size_t n_bits = n.bits(); + + const size_t powm_window = 4; + + auto powm_a_n = monty_precompute(monty_n, a, powm_window); + + BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits); + + if(y == 1 || y == n_minus_1) + return true; + + for(size_t i = 1; i != s; ++i) + { + y = mod_n.square(y); + + if(y == 1) // found a non-trivial square root + return false; + + /* + -1 is the trivial square root of unity, so ``a`` is not a + witness for this number - give up + */ + if(y == n_minus_1) + return true; + } + + return false; + } + +bool is_miller_rabin_probable_prime(const BigInt& n, + const Modular_Reducer& mod_n, + RandomNumberGenerator& rng, + size_t test_iterations) + { + BOTAN_ASSERT_NOMSG(n > 1); + + auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n); + + for(size_t i = 0; i != test_iterations; ++i) + { + const BigInt a = BigInt::random_integer(rng, 2, n); + + if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) + return false; + } + + // Failed to find a counterexample + return true; + } + + +size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) + { + const size_t base = (prob + 2) / 2; // worst case 4^-t error rate + + /* + * If the candidate prime was maliciously constructed, we can't rely + * on arguments based on p being random. + */ + if(random == false) + return base; + + /* + * For randomly chosen numbers we can use the estimates from + * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf + * + * These values are derived from the inequality for p(k,t) given on + * the second page. + */ + if(prob <= 128) + { + if(n_bits >= 1536) + return 4; // < 2^-133 + if(n_bits >= 1024) + return 6; // < 2^-133 + if(n_bits >= 512) + return 12; // < 2^-129 + if(n_bits >= 256) + return 29; // < 2^-128 + } + + /* + If the user desires a smaller error probability than we have + precomputed error estimates for, just fall back to using the worst + case error rate. + */ + return base; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.h new file mode 100644 index 0000000000..db7a76a74d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.h @@ -0,0 +1,100 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PRIMALITY_TEST_H_ +#define BOTAN_PRIMALITY_TEST_H_ + +#include <botan/types.h> +#include <memory> + +namespace Botan { + +class BigInt; +class Modular_Reducer; +class Montgomery_Params; +class RandomNumberGenerator; + +/** +* Perform Lucas primality test +* @see FIPS 186-4 C.3.3 +* +* @warning it is possible to construct composite integers which pass +* this test alone. +* +* @param n the positive integer to test +* @param mod_n a pre-created Modular_Reducer for n +* @return true if n seems probably prime, false if n is composite +*/ +bool BOTAN_TEST_API is_lucas_probable_prime(const BigInt& n, const Modular_Reducer& mod_n); + +/** +* Perform Bailie-PSW primality test +* +* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known +* composite integer passes both tests, though it is conjectured that infinitely +* many composite counterexamples exist. +* +* @param n the positive integer to test +* @param mod_n a pre-created Modular_Reducer for n +* @return true if n seems probably prime, false if n is composite +*/ +bool BOTAN_TEST_API is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n); + +/** +* Perform Bailie-PSW primality test +* +* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known +* composite integer passes both tests, though it is conjectured that infinitely +* many composite counterexamples exist. +* +* @param n the positive integer to test +* @return true if n seems probably prime, false if n is composite +*/ +bool is_bailie_psw_probable_prime(const BigInt& n); + +/** +* Return required number of Miller-Rabin tests in order to +* reach the specified probability of error. +* +* @param n_bits the bit-length of the integer being tested +* @param prob chance of false positive is bounded by 1/2**prob +* @param random is set if (and only if) the integer was randomly generated by us +* and thus cannot have been maliciously constructed. +*/ +size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random); + +/** +* Perform a single Miller-Rabin test with specified base +* +* @param n the positive integer to test +* @param mod_n a pre-created Modular_Reducer for n +* @param monty_n Montgomery parameters for n +* @param a the base to check +* @return result of primality test +*/ +bool passes_miller_rabin_test(const BigInt& n, + const Modular_Reducer& mod_n, + const std::shared_ptr<Montgomery_Params>& monty_n, + const BigInt& a); + +/** +* Perform t iterations of a Miller-Rabin primality test with random bases +* +* @param n the positive integer to test +* @param mod_n a pre-created Modular_Reducer for n +* @param rng a random number generator +* @param t number of tests to perform +* +* @return result of primality test +*/ +bool BOTAN_TEST_API is_miller_rabin_probable_prime(const BigInt& n, + const Modular_Reducer& mod_n, + RandomNumberGenerator& rng, + size_t t); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp index 98cf698ed7..a5321c47ca 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp @@ -32,11 +32,18 @@ Modular_Reducer::Modular_Reducer(const BigInt& mod) } } -/* -* Barrett Reduction -*/ BigInt Modular_Reducer::reduce(const BigInt& x) const { + BigInt r; + secure_vector<word> ws; + reduce(r, x, ws); + return r; + } + +void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector<word>& ws) const + { + if(&t1 == &x) + throw Invalid_State("Modular_Reducer arguments cannot alias"); if(m_mod_words == 0) throw Invalid_State("Modular_Reducer: Never initalized"); @@ -45,12 +52,11 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const if(x_sw >= (2*m_mod_words - 1) && x.cmp(m_modulus_2, false) >= 0) { // too big, fall back to normal division - return (x % m_modulus); + t1 = x % m_modulus; + return; } - secure_vector<word> ws; - - BigInt t1 = x; + t1 = x; t1.set_sign(BigInt::Positive); t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1)); @@ -83,8 +89,6 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const { t1.rev_sub(m_modulus.data(), m_modulus.size(), ws); } - - return t1; } } diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h index c66c220342..5276adbbcb 100644 --- a/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h @@ -47,6 +47,8 @@ class BOTAN_PUBLIC_API(2,0) Modular_Reducer BigInt cube(const BigInt& x) const { return multiply(x, this->square(x)); } + void reduce(BigInt& out, const BigInt& x, secure_vector<word>& ws) const; + bool initialized() const { return (m_mod_words != 0); } Modular_Reducer() { m_mod_words = 0; } diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp index c67664a6e7..c01fc43284 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp @@ -2,6 +2,7 @@ * CBC Mode * (C) 1999-2007,2013,2017 Jack Lloyd * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -15,9 +16,9 @@ namespace Botan { CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : m_cipher(cipher), m_padding(padding), - m_state(m_cipher->block_size()) + m_block_size(cipher->block_size()) { - if(m_padding && !m_padding->valid_blocksize(cipher->block_size())) + if(m_padding && !m_padding->valid_blocksize(m_block_size)) throw Invalid_Argument("Padding " + m_padding->name() + " cannot be used with " + cipher->name() + "/CBC"); @@ -31,7 +32,7 @@ void CBC_Mode::clear() void CBC_Mode::reset() { - zeroise(m_state); + m_state.clear(); } std::string CBC_Mode::name() const @@ -65,6 +66,7 @@ bool CBC_Mode::valid_nonce_length(size_t n) const void CBC_Mode::key_schedule(const uint8_t key[], size_t length) { m_cipher->set_key(key, length); + m_state.clear(); } void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) @@ -79,6 +81,9 @@ void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) */ if(nonce_len) m_state.assign(nonce, nonce + nonce_len); + else if(m_state.empty()) + m_state.resize(m_cipher->block_size()); + // else leave the state alone } size_t CBC_Encryption::minimum_final_size() const @@ -96,6 +101,7 @@ size_t CBC_Encryption::output_length(size_t input_length) const size_t CBC_Encryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); const size_t BS = block_size(); BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks"); @@ -120,6 +126,7 @@ size_t CBC_Encryption::process(uint8_t buf[], size_t sz) void CBC_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t BS = block_size(); @@ -151,6 +158,7 @@ size_t CTS_Encryption::output_length(size_t input_length) const void CTS_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); uint8_t* buf = buffer.data() + offset; const size_t sz = buffer.size() - offset; @@ -205,6 +213,8 @@ size_t CBC_Decryption::minimum_final_size() const size_t CBC_Decryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); + const size_t BS = block_size(); BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); @@ -231,6 +241,7 @@ size_t CBC_Decryption::process(uint8_t buf[], size_t sz) void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t sz = buffer.size() - offset; @@ -251,7 +262,7 @@ void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) void CBC_Decryption::reset() { - zeroise(state()); + CBC_Mode::reset(); zeroise(m_tempbuf); } @@ -267,6 +278,7 @@ size_t CTS_Decryption::minimum_final_size() const void CTS_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t sz = buffer.size() - offset; uint8_t* buf = buffer.data() + offset; diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h index 65b6395115..aaa4257121 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h @@ -46,9 +46,9 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode return *m_padding; } - secure_vector<uint8_t>& state() { return m_state; } + size_t block_size() const { return m_block_size; } - size_t block_size() const { return m_state.size(); } + secure_vector<uint8_t>& state() { return m_state; } uint8_t* state_ptr() { return m_state.data(); } @@ -60,6 +60,7 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode std::unique_ptr<BlockCipher> m_cipher; std::unique_ptr<BlockCipherModePaddingMethod> m_padding; secure_vector<uint8_t> m_state; + size_t m_block_size; }; /** diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp index 00d7a4db08..710f16ba22 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp @@ -35,6 +35,10 @@ #include <botan/internal/openssl.h> #endif +#if defined(BOTAN_HAS_COMMONCRYPTO) + #include <botan/internal/commoncrypto.h> +#endif + namespace Botan { std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo, @@ -51,6 +55,19 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo, Cipher_Dir direction, const std::string& provider) { +#if defined(BOTAN_HAS_COMMONCRYPTO) + if(provider.empty() || provider == "commoncrypto") + { + std::unique_ptr<Cipher_Mode> commoncrypto_cipher(make_commoncrypto_cipher_mode(algo, direction)); + + if(commoncrypto_cipher) + return commoncrypto_cipher; + + if(!provider.empty()) + return std::unique_ptr<Cipher_Mode>(); + } +#endif + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -172,7 +189,7 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo, //static std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec) { - const std::vector<std::string>& possible = { "base", "openssl" }; + const std::vector<std::string>& possible = { "base", "openssl", "commoncrypto" }; std::vector<std::string> providers; for(auto&& prov : possible) { diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h index f67e737a43..9bf0b6811e 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h @@ -9,9 +9,8 @@ #define BOTAN_CIPHER_MODE_H_ #include <botan/secmem.h> -#include <botan/key_spec.h> +#include <botan/sym_algo.h> #include <botan/exceptn.h> -#include <botan/symkey.h> #include <string> #include <vector> @@ -26,11 +25,9 @@ enum Cipher_Dir : int { ENCRYPTION, DECRYPTION }; /** * Interface for cipher modes */ -class BOTAN_PUBLIC_API(2,0) Cipher_Mode +class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm { public: - virtual ~Cipher_Mode() = default; - /** * @return list of available providers for this algorithm, empty if not available * @param algo_spec algorithm name @@ -133,8 +130,9 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode /** * Returns the size of the output if this transform is used to process a - * message with input_length bytes. Will throw if unable to give a precise - * answer. + * message with input_length bytes. In most cases the answer is precise. + * If it is not possible to precise (namely for CBC decryption) instead a + * lower bound is returned. */ virtual size_t output_length(size_t input_length) const = 0; @@ -159,14 +157,6 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode */ virtual bool valid_nonce_length(size_t nonce_len) const = 0; - virtual std::string name() const = 0; - - /** - * Zeroise all state - * See also reset_msg() - */ - virtual void clear() = 0; - /** * Resets just the message specific state and allows encrypting again under the existing key */ @@ -184,59 +174,10 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode virtual size_t tag_size() const { return 0; } /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; - - /** - * Check whether a given key length is valid for this algorithm. - * @param length the key length to be checked. - * @return true if the key length is valid. - */ - bool valid_keylength(size_t length) const - { - return key_spec().valid_keylength(length); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - */ - template<typename Alloc> - void set_key(const std::vector<uint8_t, Alloc>& key) - { - set_key(key.data(), key.size()); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - */ - void set_key(const SymmetricKey& key) - { - set_key(key.begin(), key.length()); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - * @param length in bytes of key param - */ - void set_key(const uint8_t key[], size_t length) - { - if(!valid_keylength(length)) - throw Invalid_Key_Length(name(), length); - key_schedule(key, length); - } - - /** * @return provider information about this implementation. Default is "base", * might also return "sse2", "avx2", "openssl", or some other arbitrary string. */ virtual std::string provider() const { return "base"; } - - private: - virtual void key_schedule(const uint8_t key[], size_t length) = 0; }; /** diff --git a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp index f93b2dcccc..e65114c880 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp @@ -1,6 +1,6 @@ /* * CBC Padding Methods -* (C) 1999-2007,2013 Jack Lloyd +* (C) 1999-2007,2013,2018 Jack Lloyd * (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity * * Botan is released under the Simplified BSD License (see license.txt) @@ -51,26 +51,27 @@ void PKCS7_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with PKCS #7 Method */ -size_t PKCS7_Padding::unpad(const uint8_t block[], size_t size) const +size_t PKCS7_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); + if(input_length <= 2) + return input_length; + + CT::poison(input, input_length); size_t bad_input = 0; - const uint8_t last_byte = block[size-1]; + const uint8_t last_byte = input[input_length-1]; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + bad_input |= CT::expand_mask<size_t>(last_byte > input_length); - size_t pad_pos = size - last_byte; - size_t i = size - 2; - while(i) + const size_t pad_pos = input_length - last_byte; + + for(size_t i = 0; i != input_length - 1; ++i) { - bad_input |= (~CT::is_equal(block[i],last_byte)) & CT::expand_mask<uint8_t>(i >= pad_pos); - --i; + const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos); + bad_input |= in_range & (~CT::is_equal(input[i], last_byte)); } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block,size); - CT::unpoison(pad_pos); - return pad_pos; + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -92,25 +93,27 @@ void ANSI_X923_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with ANSI X9.23 Method */ -size_t ANSI_X923_Padding::unpad(const uint8_t block[], size_t size) const +size_t ANSI_X923_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); - size_t bad_input = 0; - const size_t last_byte = block[size-1]; + if(input_length <= 2) + return input_length; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + CT::poison(input, input_length); + const size_t last_byte = input[input_length-1]; - size_t pad_pos = size - last_byte; - size_t i = size - 2; - while(i) + uint8_t bad_input = 0; + bad_input |= CT::expand_mask<uint8_t>(last_byte > input_length); + + const size_t pad_pos = input_length - last_byte; + + for(size_t i = 0; i != input_length - 1; ++i) { - bad_input |= (~CT::is_zero(block[i])) & CT::expand_mask<uint8_t>(i >= pad_pos); - --i; + const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos); + bad_input |= CT::expand_mask(input[i]) & in_range; } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block,size); - CT::unpoison(pad_pos); - return pad_pos; + + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -129,28 +132,29 @@ void OneAndZeros_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with One and Zeros Method */ -size_t OneAndZeros_Padding::unpad(const uint8_t block[], size_t size) const +size_t OneAndZeros_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block, size); + if(input_length <= 2) + return input_length; + + CT::poison(input, input_length); + uint8_t bad_input = 0; uint8_t seen_one = 0; - size_t pad_pos = size - 1; - size_t i = size; + size_t pad_pos = input_length - 1; + size_t i = input_length; while(i) { - seen_one |= CT::is_equal<uint8_t>(block[i-1],0x80); + seen_one |= CT::is_equal<uint8_t>(input[i-1], 0x80); pad_pos -= CT::select<uint8_t>(~seen_one, 1, 0); - bad_input |= ~CT::is_zero<uint8_t>(block[i-1]) & ~seen_one; + bad_input |= ~CT::is_zero<uint8_t>(input[i-1]) & ~seen_one; i--; } bad_input |= ~seen_one; - CT::conditional_copy_mem(size_t(bad_input),&pad_pos,&size,&pad_pos,1); - CT::unpoison(block, size); - CT::unpoison(pad_pos); - - return pad_pos; + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -171,25 +175,28 @@ void ESP_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with ESP Padding Method */ -size_t ESP_Padding::unpad(const uint8_t block[], size_t size) const +size_t ESP_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); + if(input_length <= 2) + return input_length; - const size_t last_byte = block[size-1]; - size_t bad_input = 0; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + CT::poison(input, input_length); + + const size_t last_byte = input[input_length-1]; + uint8_t bad_input = 0; + bad_input |= CT::is_zero(last_byte) | CT::expand_mask<uint8_t>(last_byte > input_length); - size_t pad_pos = size - last_byte; - size_t i = size - 1; + const size_t pad_pos = input_length - last_byte; + size_t i = input_length - 1; while(i) { - bad_input |= ~CT::is_equal<uint8_t>(size_t(block[i-1]),size_t(block[i])-1) & CT::expand_mask<uint8_t>(i > pad_pos); + const uint8_t in_range = CT::expand_mask<uint8_t>(i > pad_pos); + bad_input |= (~CT::is_equal<uint8_t>(input[i-1], input[i]-1)) & in_range; --i; } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block, size); - CT::unpoison(pad_pos); - return pad_pos; + + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } diff --git a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h index cc196d251b..25e4221af1 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h @@ -39,11 +39,10 @@ class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod /** * Remove padding bytes from block * @param block the last block - * @param size the size of the block in bytes - * @return number of padding bytes + * @param len the size of the block in bytes + * @return number of data bytes, or if the padding is invalid returns len */ - virtual size_t unpad(const uint8_t block[], - size_t size) const = 0; + virtual size_t unpad(const uint8_t block[], size_t len) const = 0; /** * @param block_size of the cipher @@ -74,7 +73,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingM size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "PKCS7"; } }; @@ -91,7 +90,7 @@ class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePadd size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "X9.23"; } }; @@ -108,7 +107,7 @@ class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePa size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0); } + bool valid_blocksize(size_t bs) const override { return (bs > 2); } std::string name() const override { return "OneAndZeros"; } }; @@ -125,7 +124,7 @@ class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMet size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "ESP"; } }; diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt b/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt index 48c6b56e66..650414f41b 100644 --- a/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt @@ -1,5 +1,5 @@ <defines> -PBKDF -> 20150626 +PBKDF -> 20180902 </defines> <requires> @@ -8,5 +8,6 @@ hash </requires> <header:public> +pwdhash.h pbkdf.h </header:public> diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h index 7d3bceffcf..e7f0a84eec 100644 --- a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h @@ -17,6 +17,9 @@ namespace Botan { * Base class for PBKDF (password based key derivation function) * implementations. Converts a password into a key using a salt * and iterated hashing to make brute force attacks harder. +* +* Starting in 2.8 this functionality is also offered by PasswordHash. +* The PBKDF interface may be removed in a future release. */ class BOTAN_PUBLIC_API(2,0) PBKDF { @@ -216,7 +219,7 @@ class BOTAN_PUBLIC_API(2,0) PBKDF }; /* -* Compatability typedef +* Compatibility typedef */ typedef PBKDF S2K; diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt index bc5c2e4916..b6c6fb4e65 100644 --- a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt @@ -1,5 +1,5 @@ <defines> -PBKDF2 -> 20131128 +PBKDF2 -> 20180902 </defines> <requires> diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index cc2982f6e9..6fc007bf38 100644 --- a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -1,6 +1,7 @@ /* * PBKDF2 * (C) 1999-2007 Jack Lloyd +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -8,41 +9,115 @@ #include <botan/pbkdf2.h> #include <botan/exceptn.h> #include <botan/internal/rounding.h> +#include <botan/internal/timer.h> namespace Botan { +namespace { + +void pbkdf2_set_key(MessageAuthenticationCode& prf, + const char* password, + size_t password_len) + { + try + { + prf.set_key(cast_char_ptr_to_uint8(password), password_len); + } + catch(Invalid_Key_Length&) + { + throw Exception("PBKDF2 cannot accept passphrase of the given size"); + } + } + +} + size_t pbkdf2(MessageAuthenticationCode& prf, uint8_t out[], size_t out_len, - const std::string& passphrase, + const std::string& password, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec) { - clear_mem(out, out_len); - - if(out_len == 0) - return 0; - - try + if(iterations == 0) { - prf.set_key(cast_char_ptr_to_uint8(passphrase.data()), passphrase.size()); - } - catch(Invalid_Key_Length&) - { - throw Exception("PBKDF2 with " + prf.name() + - " cannot accept passphrases of length " + - std::to_string(passphrase.size())); + iterations = PBKDF2(prf, out_len, msec).iterations(); } + PBKDF2 pbkdf2(prf, iterations); + + pbkdf2.derive_key(out, out_len, + password.c_str(), password.size(), + salt, salt_len); + + return iterations; + } + +namespace { + +size_t tune_pbkdf2(MessageAuthenticationCode& prf, + size_t output_length, + uint32_t msec) + { const size_t prf_sz = prf.output_length(); + BOTAN_ASSERT_NOMSG(prf_sz > 0); secure_vector<uint8_t> U(prf_sz); - const size_t blocks_needed = round_up(out_len, prf_sz) / prf_sz; + const size_t trial_iterations = 10000; + + // Short output ensures we only need a single PBKDF2 block + + Timer timer("PBKDF2"); + + const std::chrono::milliseconds tune_msec(30); + + prf.set_key(nullptr, 0); + + timer.run_until_elapsed(tune_msec, [&]() { + uint8_t out[16] = { 0 }; + uint8_t salt[16] = { 0 }; + pbkdf2(prf, out, sizeof(out), salt, sizeof(salt), trial_iterations); + }); + + if(timer.events() == 0) + return trial_iterations; + + const uint64_t duration_nsec = timer.value() / timer.events(); + + const uint64_t desired_nsec = static_cast<uint64_t>(msec) * 1000000; + + if(duration_nsec > desired_nsec) + return trial_iterations; + + const size_t blocks_needed = (output_length + prf_sz - 1) / prf_sz; + + const size_t multiplier = (desired_nsec / duration_nsec / blocks_needed); + + if(multiplier == 0) + return trial_iterations; + else + return trial_iterations * multiplier; + } + +} + +void pbkdf2(MessageAuthenticationCode& prf, + uint8_t out[], + size_t out_len, + const uint8_t salt[], + size_t salt_len, + size_t iterations) + { + clear_mem(out, out_len); + + if(out_len == 0) + return; + + const size_t prf_sz = prf.output_length(); + BOTAN_ASSERT_NOMSG(prf_sz > 0); - std::chrono::microseconds usec_per_block = - std::chrono::duration_cast<std::chrono::microseconds>(msec) / blocks_needed; + secure_vector<uint8_t> U(prf_sz); uint32_t counter = 1; while(out_len) @@ -55,64 +130,93 @@ pbkdf2(MessageAuthenticationCode& prf, xor_buf(out, U.data(), prf_output); - if(iterations == 0) + for(size_t i = 1; i != iterations; ++i) { - /* - If no iterations set, run the first block to calibrate based - on how long hashing takes on whatever machine we're running on. - */ - - const auto start = std::chrono::high_resolution_clock::now(); - - iterations = 1; // the first iteration we did above - - while(true) - { - prf.update(U); - prf.final(U.data()); - xor_buf(out, U.data(), prf_output); - iterations++; - - /* - Only break on relatively 'even' iterations. For one it - avoids confusion, and likely some broken implementations - break on getting completely randomly distributed values - */ - if(iterations % 10000 == 0) - { - auto time_taken = std::chrono::high_resolution_clock::now() - start; - auto usec_taken = std::chrono::duration_cast<std::chrono::microseconds>(time_taken); - if(usec_taken > usec_per_block) - break; - } - } - } - else - { - for(size_t i = 1; i != iterations; ++i) - { - prf.update(U); - prf.final(U.data()); - xor_buf(out, U.data(), prf_output); - } + prf.update(U); + prf.final(U.data()); + xor_buf(out, U.data(), prf_output); } out_len -= prf_output; out += prf_output; } - - return iterations; } +// PBKDF interface size_t PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len, - const std::string& passphrase, + const std::string& password, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec) const { - return pbkdf2(*m_mac.get(), key, key_len, passphrase, salt, salt_len, iterations, msec); + if(iterations == 0) + { + iterations = PBKDF2(*m_mac, key_len, msec).iterations(); + } + + PBKDF2 pbkdf2(*m_mac, iterations); + + pbkdf2.derive_key(key, key_len, + password.c_str(), password.size(), + salt, salt_len); + + return iterations; + } + +std::string PKCS5_PBKDF2::name() const + { + return "PBKDF2(" + m_mac->name() + ")"; + } + +PBKDF* PKCS5_PBKDF2::clone() const + { + return new PKCS5_PBKDF2(m_mac->clone()); } +// PasswordHash interface + +PBKDF2::PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec) : + m_prf(prf.clone()), + m_iterations(tune_pbkdf2(*m_prf, olen, static_cast<uint32_t>(msec.count()))) + {} + +std::string PBKDF2::to_string() const + { + return "PBKDF2(" + m_prf->name() + "," + std::to_string(m_iterations) + ")"; + } + +void PBKDF2::derive_key(uint8_t out[], size_t out_len, + const char* password, const size_t password_len, + const uint8_t salt[], size_t salt_len) const + { + pbkdf2_set_key(*m_prf, password, password_len); + pbkdf2(*m_prf, out, out_len, salt, salt_len, m_iterations); + } + +std::string PBKDF2_Family::name() const + { + return "PBKDF2(" + m_prf->name() + ")"; + } + +std::unique_ptr<PasswordHash> PBKDF2_Family::tune(size_t output_len, std::chrono::milliseconds msec, size_t) const + { + return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, output_len, msec)); + } + +std::unique_ptr<PasswordHash> PBKDF2_Family::default_params() const + { + return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, 150000)); + } + +std::unique_ptr<PasswordHash> PBKDF2_Family::from_params(size_t iter, size_t, size_t) const + { + return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter)); + } + +std::unique_ptr<PasswordHash> PBKDF2_Family::from_iterations(size_t iter) const + { + return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter)); + } } diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h index ea357cac0b..65955eb288 100644 --- a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h @@ -1,6 +1,7 @@ /* * PBKDF2 * (C) 1999-2007,2012 Jack Lloyd +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -9,6 +10,7 @@ #define BOTAN_PBKDF2_H_ #include <botan/pbkdf.h> +#include <botan/pwdhash.h> #include <botan/mac.h> namespace Botan { @@ -22,20 +24,76 @@ BOTAN_PUBLIC_API(2,0) size_t pbkdf2(MessageAuthenticationCode& prf, std::chrono::milliseconds msec); /** -* PKCS #5 PBKDF2 +* Perform PBKDF2. The prf is assumed to be keyed already. +*/ +BOTAN_PUBLIC_API(2,8) void pbkdf2(MessageAuthenticationCode& prf, + uint8_t out[], size_t out_len, + const uint8_t salt[], size_t salt_len, + size_t iterations); + +/** +* PBKDF2 +*/ +class BOTAN_PUBLIC_API(2,8) PBKDF2 final : public PasswordHash + { + public: + PBKDF2(const MessageAuthenticationCode& prf, size_t iter) : + m_prf(prf.clone()), + m_iterations(iter) + {} + + PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec); + + size_t iterations() const override { return m_iterations; } + + std::string to_string() const override; + + void derive_key(uint8_t out[], size_t out_len, + const char* password, size_t password_len, + const uint8_t salt[], size_t salt_len) const override; + private: + std::unique_ptr<MessageAuthenticationCode> m_prf; + size_t m_iterations; + }; + +/** +* Family of PKCS #5 PBKDF2 operations +*/ +class BOTAN_PUBLIC_API(2,8) PBKDF2_Family final : public PasswordHashFamily + { + public: + PBKDF2_Family(MessageAuthenticationCode* prf) : m_prf(prf) {} + + std::string name() const override; + + std::unique_ptr<PasswordHash> tune(size_t output_len, + std::chrono::milliseconds msec, + size_t max_memory) const override; + + /** + * Return some default parameter set for this PBKDF that should be good + * enough for most users. The value returned may change over time as + * processing power and attacks improve. + */ + std::unique_ptr<PasswordHash> default_params() const override; + + std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override; + + std::unique_ptr<PasswordHash> from_params( + size_t iter, size_t, size_t) const override; + private: + std::unique_ptr<MessageAuthenticationCode> m_prf; + }; + +/** +* PKCS #5 PBKDF2 (old interface) */ class BOTAN_PUBLIC_API(2,0) PKCS5_PBKDF2 final : public PBKDF { public: - std::string name() const override - { - return "PBKDF2(" + m_mac->name() + ")"; - } - - PBKDF* clone() const override - { - return new PKCS5_PBKDF2(m_mac->clone()); - } + std::string name() const override; + + PBKDF* clone() const override; size_t pbkdf(uint8_t output_buf[], size_t output_len, const std::string& passphrase, diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.cpp b/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.cpp new file mode 100644 index 0000000000..783ac70665 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.cpp @@ -0,0 +1,88 @@ +/* +* (C) 2018 Ribose Inc +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/pbkdf.h> +#include <botan/exceptn.h> +#include <botan/scan_name.h> + +#if defined(BOTAN_HAS_PBKDF2) + #include <botan/pbkdf2.h> +#endif + +#if defined(BOTAN_HAS_PGP_S2K) + #include <botan/pgp_s2k.h> +#endif + +#if defined(BOTAN_HAS_SCRYPT) + #include <botan/scrypt.h> +#endif + +namespace Botan { + +std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(const std::string& algo_spec, + const std::string& provider) + { + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_PBKDF2) + if(req.algo_name() == "PBKDF2") + { + // TODO OpenSSL + + if(provider.empty() || provider == "base") + { + if(auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release())); + + if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release())); + } + + return nullptr; + } +#endif + +#if defined(BOTAN_HAS_SCRYPT) + if(req.algo_name() == "Scrypt") + { + return std::unique_ptr<PasswordHashFamily>(new Scrypt_Family); + } +#endif + +#if defined(BOTAN_HAS_PGP_S2K) + if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) + { + if(auto hash = HashFunction::create(req.arg(0))) + { + return std::unique_ptr<PasswordHashFamily>(new RFC4880_S2K_Family(hash.release())); + } + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +//static +std::unique_ptr<PasswordHashFamily> +PasswordHashFamily::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto pbkdf = PasswordHashFamily::create(algo, provider)) + { + return pbkdf; + } + throw Lookup_Error("PasswordHashFamily", algo, provider); + } + +std::vector<std::string> PasswordHashFamily::providers(const std::string& algo_spec) + { + return probe_providers_of<PasswordHashFamily>(algo_spec, { "base", "openssl" }); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.h b/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.h new file mode 100644 index 0000000000..ba64a73fd5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.h @@ -0,0 +1,162 @@ +/* +* (C) 2018 Ribose Inc +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PWDHASH_H_ +#define BOTAN_PWDHASH_H_ + +#include <botan/types.h> +#include <string> +#include <memory> +#include <vector> +#include <chrono> + +namespace Botan { + +/** +* Base class for password based key derivation functions. +* +* Converts a password into a key using a salt and iterated hashing to +* make brute force attacks harder. +*/ +class BOTAN_PUBLIC_API(2,8) PasswordHash + { + public: + virtual ~PasswordHash() = default; + + virtual std::string to_string() const = 0; + + /** + * Most password hashes have some notion of iterations. + */ + virtual size_t iterations() const = 0; + + /** + * Some password hashing algorithms have a parameter which controls how + * much memory is used. If not supported by some algorithm, returns 0. + */ + virtual size_t memory_param() const { return 0; } + + /** + * Some password hashing algorithms have a parallelism parameter. + * If the algorithm does not support this notion, then the + * function returns zero. This allows distinguishing between a + * password hash which just does not support parallel operation, + * vs one that does support parallel operation but which has been + * configured to use a single lane. + */ + virtual size_t parallelism() const { return 0; } + + /** + * Returns an estimate of the total memory usage required to perform this + * key derivation. + * + * If this algorithm uses a small and constant amount of memory, with no + * effort made towards being memory hard, this function returns 0. + */ + virtual size_t total_memory_usage() const { return 0; } + + /** + * Derive a key from a password + * + * @param out buffer to store the derived key, must be of out_len bytes + * @param out_len the desired length of the key to produce + * @param password the password to derive the key from + * @param password_len the length of password in bytes + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * + * This function is const, but is not thread safe. Different threads should + * either use unique objects, or serialize all access. + */ + virtual void derive_key(uint8_t out[], size_t out_len, + const char* password, size_t password_len, + const uint8_t salt[], size_t salt_len) const = 0; + }; + +class BOTAN_PUBLIC_API(2,8) PasswordHashFamily + { + public: + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to choose + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr<PasswordHashFamily> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Create an instance based on a name, or throw if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr<PasswordHashFamily> + create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + + virtual ~PasswordHashFamily() = default; + + /** + * @return name of this PasswordHash + */ + virtual std::string name() const = 0; + + /** + * Return a new parameter set tuned for this machine + * @param output_length how long the output length will be + * @param msec the desired execution time in milliseconds + * + * @param max_memory_usage_mb some password hash functions can use a tunable + * amount of memory, in this case max_memory_usage limits the amount of RAM + * the returned parameters will require, in mebibytes (2**20 bytes). It may + * require some small amount above the request. Set to zero to place no + * limit at all. + */ + virtual std::unique_ptr<PasswordHash> tune(size_t output_length, + std::chrono::milliseconds msec, + size_t max_memory_usage_mb = 0) const = 0; + + /** + * Return some default parameter set for this PBKDF that should be good + * enough for most users. The value returned may change over time as + * processing power and attacks improve. + */ + virtual std::unique_ptr<PasswordHash> default_params() const = 0; + + /** + * Return a parameter chosen based on a rough approximation with the + * specified iteration count. The exact value this returns for a particular + * algorithm may change from over time. Think of it as an alternative to + * tune, where time is expressed in terms of PBKDF2 iterations rather than + * milliseconds. + */ + virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0; + + /** + * Create a password hash using some scheme specific format. + * Eg PBKDF2 and PGP-S2K set iterations in i1 + * Scrypt uses N,r,p in i{1-3} + * Bcrypt-PBKDF just has iterations + * Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3}, + * and Argon2 type is part of the family. + * + * Values not needed should be set to 0 + */ + virtual std::unique_ptr<PasswordHash> from_params( + size_t i1, + size_t i2 = 0, + size_t i3 = 0) const = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp index 126e1421df..eaae898f38 100644 --- a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp @@ -55,8 +55,9 @@ EMSA* get_emsa(const std::string& algo_spec) #if defined(BOTAN_HAS_EMSA_PKCS1) if(req.algo_name() == "EMSA_PKCS1" || - req.algo_name() == "EMSA-PKCS1-v1_5" || - req.algo_name() == "EMSA3") + req.algo_name() == "PKCS1v15" || + req.algo_name() == "EMSA-PKCS1-v1_5" || + req.algo_name() == "EMSA3") { if(req.arg_count() == 2 && req.arg(0) == "Raw") { @@ -80,25 +81,45 @@ EMSA* get_emsa(const std::string& algo_spec) #endif #if defined(BOTAN_HAS_EMSA_PSSR) - if(req.algo_name() == "PSSR" || - req.algo_name() == "EMSA-PSS" || - req.algo_name() == "PSS-MGF1" || - req.algo_name() == "EMSA4" || + if(req.algo_name() == "PSS_Raw" || req.algo_name() == "PSSR_Raw") { - if(req.arg_count_between(1, 3)) + if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") { - if(req.arg(1, "MGF1") != "MGF1") - return nullptr; // not supported - if(auto h = HashFunction::create(req.arg(0))) { - const size_t salt_size = req.arg_as_integer(2, h->output_length()); - - if(req.algo_name() == "PSSR_Raw") + if(req.arg_count() == 3) + { + const size_t salt_size = req.arg_as_integer(2, 0); return new PSSR_Raw(h.release(), salt_size); + } else + { + return new PSSR_Raw(h.release()); + } + } + } + } + + if(req.algo_name() == "PSS" || + req.algo_name() == "PSSR" || + req.algo_name() == "EMSA-PSS" || + req.algo_name() == "PSS-MGF1" || + req.algo_name() == "EMSA4") + { + if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") + { + if(auto h = HashFunction::create(req.arg(0))) + { + if(req.arg_count() == 3) + { + const size_t salt_size = req.arg_as_integer(2, 0); return new PSSR(h.release(), salt_size); + } + else + { + return new PSSR(h.release()); + } } } } diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp index 97b229be35..25c0a191f5 100644 --- a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -55,9 +55,10 @@ secure_vector<uint8_t> pss_encode(HashFunction& hash, } bool pss_verify(HashFunction& hash, - const secure_vector<uint8_t>& const_coded, - const secure_vector<uint8_t>& raw, - size_t key_bits) + const secure_vector<uint8_t>& pss_repr, + const secure_vector<uint8_t>& message_hash, + size_t key_bits, + size_t* out_salt_size) { const size_t HASH_SIZE = hash.output_length(); const size_t KEY_BYTES = (key_bits + 7) / 8; @@ -65,16 +66,16 @@ bool pss_verify(HashFunction& hash, if(key_bits < 8*HASH_SIZE + 9) return false; - if(raw.size() != HASH_SIZE) + if(message_hash.size() != HASH_SIZE) return false; - if(const_coded.size() > KEY_BYTES || const_coded.size() <= 1) + if(pss_repr.size() > KEY_BYTES || pss_repr.size() <= 1) return false; - if(const_coded[const_coded.size()-1] != 0xBC) + if(pss_repr[pss_repr.size()-1] != 0xBC) return false; - secure_vector<uint8_t> coded = const_coded; + secure_vector<uint8_t> coded = pss_repr; if(coded.size() < KEY_BYTES) { secure_vector<uint8_t> temp(KEY_BYTES); @@ -110,23 +111,32 @@ bool pss_verify(HashFunction& hash, for(size_t j = 0; j != 8; ++j) hash.update(0); - hash.update(raw); + hash.update(message_hash); hash.update(&DB[salt_offset], salt_size); - secure_vector<uint8_t> H2 = hash.final(); + const secure_vector<uint8_t> H2 = hash.final(); - return constant_time_compare(H, H2.data(), HASH_SIZE); + const bool ok = constant_time_compare(H, H2.data(), HASH_SIZE); + + if(out_salt_size && ok) + *out_salt_size = salt_size; + + return ok; } } PSSR::PSSR(HashFunction* h) : - m_hash(h), m_SALT_SIZE(m_hash->output_length()) + m_hash(h), + m_salt_size(m_hash->output_length()), + m_required_salt_len(false) { } PSSR::PSSR(HashFunction* h, size_t salt_size) : - m_hash(h), m_SALT_SIZE(salt_size) + m_hash(h), + m_salt_size(salt_size), + m_required_salt_len(true) { } @@ -150,7 +160,7 @@ secure_vector<uint8_t> PSSR::encoding_of(const secure_vector<uint8_t>& msg, size_t output_bits, RandomNumberGenerator& rng) { - secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE); + const secure_vector<uint8_t> salt = rng.random_vec(m_salt_size); return pss_encode(*m_hash, msg, salt, output_bits); } @@ -161,12 +171,23 @@ bool PSSR::verify(const secure_vector<uint8_t>& coded, const secure_vector<uint8_t>& raw, size_t key_bits) { - return pss_verify(*m_hash, coded, raw, key_bits); + size_t salt_size = 0; + const bool ok = pss_verify(*m_hash, coded, raw, key_bits, &salt_size); + + if(m_required_salt_len && salt_size != m_salt_size) + return false; + + return ok; + } + +EMSA* PSSR::clone() + { + return new PSSR(m_hash->clone(), m_salt_size); } std::string PSSR::name() const { - return "EMSA4(" + m_hash->name() + ",MGF1," + std::to_string(m_SALT_SIZE) + ")"; + return "EMSA4(" + m_hash->name() + ",MGF1," + std::to_string(m_salt_size) + ")"; } AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key, @@ -193,7 +214,7 @@ AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key, .start_cons(SEQUENCE) .start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).encode(hash_id).end_cons() .start_cons(ASN1_Tag(1), CONTEXT_SPECIFIC).encode(mgf_id).end_cons() - .start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_SALT_SIZE).end_cons() + .start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_salt_size).end_cons() .start_cons(ASN1_Tag(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field .end_cons(); @@ -201,12 +222,16 @@ AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key, } PSSR_Raw::PSSR_Raw(HashFunction* h) : - m_hash(h), m_SALT_SIZE(m_hash->output_length()) + m_hash(h), + m_salt_size(m_hash->output_length()), + m_required_salt_len(false) { } PSSR_Raw::PSSR_Raw(HashFunction* h, size_t salt_size) : - m_hash(h), m_SALT_SIZE(salt_size) + m_hash(h), + m_salt_size(salt_size), + m_required_salt_len(true) { } @@ -236,7 +261,7 @@ secure_vector<uint8_t> PSSR_Raw::encoding_of(const secure_vector<uint8_t>& msg, size_t output_bits, RandomNumberGenerator& rng) { - secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE); + secure_vector<uint8_t> salt = rng.random_vec(m_salt_size); return pss_encode(*m_hash, msg, salt, output_bits); } @@ -247,12 +272,23 @@ bool PSSR_Raw::verify(const secure_vector<uint8_t>& coded, const secure_vector<uint8_t>& raw, size_t key_bits) { - return pss_verify(*m_hash, coded, raw, key_bits); + size_t salt_size = 0; + const bool ok = pss_verify(*m_hash, coded, raw, key_bits, &salt_size); + + if(m_required_salt_len && salt_size != m_salt_size) + return false; + + return ok; + } + +EMSA* PSSR_Raw::clone() + { + return new PSSR_Raw(m_hash->clone(), m_salt_size); } std::string PSSR_Raw::name() const { - return "PSSR_Raw(" + m_hash->name() + ",MGF1," + std::to_string(m_SALT_SIZE) + ")"; + return "PSSR_Raw(" + m_hash->name() + ",MGF1," + std::to_string(m_salt_size) + ")"; } } diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h index 3b902dd6a8..fa0ae1228a 100644 --- a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h @@ -31,7 +31,7 @@ class BOTAN_PUBLIC_API(2,0) PSSR final : public EMSA */ PSSR(HashFunction* hash, size_t salt_size); - EMSA* clone() override { return new PSSR(m_hash->clone(), m_SALT_SIZE); } + EMSA* clone() override; std::string name() const override; @@ -51,7 +51,8 @@ class BOTAN_PUBLIC_API(2,0) PSSR final : public EMSA size_t key_bits) override; std::unique_ptr<HashFunction> m_hash; - size_t m_SALT_SIZE; + size_t m_salt_size; + bool m_required_salt_len; }; /** @@ -73,7 +74,7 @@ class BOTAN_PUBLIC_API(2,3) PSSR_Raw final : public EMSA */ PSSR_Raw(HashFunction* hash, size_t salt_size); - EMSA* clone() override { return new PSSR_Raw(m_hash->clone(), m_SALT_SIZE); } + EMSA* clone() override; std::string name() const override; private: @@ -90,8 +91,9 @@ class BOTAN_PUBLIC_API(2,3) PSSR_Raw final : public EMSA size_t key_bits) override; std::unique_ptr<HashFunction> m_hash; - size_t m_SALT_SIZE; secure_vector<uint8_t> m_msg; + size_t m_salt_size; + bool m_required_salt_len; }; } diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt index afadf56554..e8fb00c8e3 100644 --- a/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt @@ -2,8 +2,6 @@ PK_PADDING -> 20131128 </defines> -load_on auto - <requires> asn1 rng diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp index dbfac5110d..2e7ef99734 100644 --- a/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp @@ -17,13 +17,14 @@ void mgf1_mask(HashFunction& hash, { uint32_t counter = 0; + secure_vector<uint8_t> buffer(hash.output_length()); while(out_len) { hash.update(in, in_len); hash.update_be(counter); - secure_vector<uint8_t> buffer = hash.final(); + hash.final(buffer.data()); - size_t xored = std::min<size_t>(buffer.size(), out_len); + const size_t xored = std::min<size_t>(buffer.size(), out_len); xor_buf(out, buffer.data(), xored); out += xored; out_len -= xored; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp index ae6e9c589b..75b0db2f65 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp @@ -93,6 +93,8 @@ class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) {} + size_t agreed_value_size() const override { return m_p.bytes(); } + secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override; private: const BigInt& m_p; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp index abc14ec0c7..8048590448 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp @@ -67,6 +67,7 @@ class DL_Group_Data final size_t p_bits() const { return m_p_bits; } size_t q_bits() const { return m_q_bits; } size_t p_bytes() const { return (m_p_bits + 7) / 8; } + size_t q_bytes() const { return (m_q_bits + 7) / 8; } size_t estimated_strength() const { return m_estimated_strength; } @@ -448,6 +449,12 @@ size_t DL_Group::q_bits() const return data().q_bits(); } +size_t DL_Group::q_bytes() const + { + data().assert_q_is_set("q_bytes"); + return data().q_bytes(); + } + size_t DL_Group::estimated_strength() const { return data().estimated_strength(); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h index 6bc9187613..43756c8065 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h @@ -269,6 +269,13 @@ class BOTAN_PUBLIC_API(2,0) DL_Group final size_t q_bits() const; /** + * Return the size of q in bytes + * Same as get_q().bytes() + * Throws if q is unset + */ + size_t q_bytes() const; + + /** * Return size in bits of a secret exponent * * This attempts to balance between the attack costs of NFS diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp index 35240292c1..4122701730 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp @@ -89,7 +89,8 @@ class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA m_b_inv = m_group.inverse_mod_q(m_b); } - size_t max_input_bits() const override { return m_group.get_q().bits(); } + size_t signature_length() const override { return 2*m_group.q_bytes(); } + size_t max_input_bits() const override { return m_group.q_bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) override; @@ -157,7 +158,7 @@ class DSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA { } - size_t max_input_bits() const override { return m_group.get_q().bits(); } + size_t max_input_bits() const override { return m_group.q_bits(); } bool with_recovery() const override { return false; } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp index 586603507e..f4419c7f0b 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp @@ -10,6 +10,7 @@ #include <botan/ec_group.h> #include <botan/internal/point_mul.h> +#include <botan/internal/primality.h> #include <botan/ber_dec.h> #include <botan/der_enc.h> #include <botan/oids.h> @@ -19,12 +20,6 @@ #include <botan/rng.h> #include <vector> -#if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> -#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) - #include <botan/hmac_drbg.h> -#endif - namespace Botan { class EC_Group_Data final @@ -318,23 +313,7 @@ std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[ .end_cons() .verify_end(); -#if defined(BOTAN_HAS_SYSTEM_RNG) - System_RNG rng; -#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) - /* - * This is not ideal because the data is attacker controlled, but - * it seems like it would be difficult for someone to come up - * with an valid ASN.1 encoding where the prime happened to pass - * Miller-Rabin test with exactly the values chosen when - * HMAC_DRBG is seeded with the overall data. - */ - HMAC_DRBG rng("SHA-256"); - rng.add_entropy(bits, len); -#else - Null_RNG rng; -#endif - - if(p.bits() < 64 || p.is_negative() || (is_prime(p, rng) == false)) + if(p.bits() < 64 || p.is_negative() || !is_bailie_psw_probable_prime(p)) throw Decoding_Error("Invalid ECC p parameter"); if(a.is_negative() || a >= p) @@ -343,7 +322,7 @@ std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[ if(b <= 0 || b >= p) throw Decoding_Error("Invalid ECC b parameter"); - if(order <= 0) + if(order <= 0 || !is_bailie_psw_probable_prime(order)) throw Decoding_Error("Invalid ECC order parameter"); if(cofactor <= 0 || cofactor >= 16) @@ -547,6 +526,15 @@ const OID& EC_Group::get_curve_oid() const return data().oid(); } +size_t EC_Group::point_size(PointGFp::Compression_Type format) const + { + // Hybrid and standard format are (x,y), compressed is y, +1 format byte + if(format == PointGFp::COMPRESSED) + return (1 + get_p_bytes()); + else + return (1 + 2*get_p_bytes()); + } + PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const { return Botan::OS2ECP(bits, len, data().curve()); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h index f8c1c1a123..8a22cebce1 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h @@ -302,6 +302,8 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final */ PointGFp zero_point() const; + size_t point_size(PointGFp::Compression_Type format) const; + PointGFp OS2ECP(const uint8_t bits[], size_t len) const; template<typename Alloc> diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp index 760f060ced..da3abaacc6 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp @@ -170,7 +170,7 @@ PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& poi if(ws.size() < PointGFp::WORKSPACE_SIZE) ws.resize(PointGFp::WORKSPACE_SIZE); - std::vector<PointGFp> U(1U << m_window_bits); + std::vector<PointGFp> U(static_cast<size_t>(1) << m_window_bits); U[0] = point.zero(); U[1] = point; @@ -354,10 +354,10 @@ PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1, H.mult2i(2, ws); } - const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2); - const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2); + const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2); + const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2); - const uint8_t z12 = (4*z2_b) + z1_b; + const uint32_t z12 = (4*z2_b) + z1_b; // This function is not intended to be const time if(z12) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp index 2c23c1b47e..767a799bf0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -147,8 +147,10 @@ secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const return DER_Encoder() .start_cons(SEQUENCE) .encode(static_cast<size_t>(1)) - .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), - OCTET_STRING) + .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), OCTET_STRING) + .start_cons(ASN1_Tag(1), PRIVATE) + .encode(m_public_key.encode(PointGFp::Compression_Type::UNCOMPRESSED), BIT_STRING) + .end_cons() .end_cons() .get_contents(); } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp index 59f245a00c..e7e49a74fd 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp @@ -34,6 +34,8 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF m_l_times_priv = m_group.inverse_mod_order(m_group.get_cofactor()) * key.private_value(); } + size_t agreed_value_size() const override { return m_group.get_p_bytes(); } + secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override { PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp index 2409d8f0d2..cbb9eba679 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -65,6 +65,8 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA m_b_inv = m_group.inverse_mod_order(m_b); } + size_t signature_length() const override { return 2*m_group.get_order_bytes(); } + size_t max_input_bits() const override { return m_group.get_order_bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, @@ -106,10 +108,10 @@ ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, m_b = m_group.square_mod_order(m_b); m_b_inv = m_group.square_mod_order(m_b_inv); - m = m_group.multiply_mod_order(m_b, m); - const BigInt xr = m_group.multiply_mod_order(m_x, m_b, r); + m = m_group.multiply_mod_order(m_b, m_group.mod_order(m)); + const BigInt xr_m = m_group.mod_order(m_group.multiply_mod_order(m_x, m_b, r) + m); - const BigInt s = m_group.multiply_mod_order(k_inv, xr + m, m_b_inv); + const BigInt s = m_group.multiply_mod_order(k_inv, xr_m, m_b_inv); // With overwhelming probability, a bug rather than actual zero r/s if(r.is_zero() || s.is_zero()) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp index cfac722d7c..263263843c 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp @@ -1,6 +1,7 @@ /* * PKCS #5 PBES2 * (C) 1999-2008,2014 Jack Lloyd +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -23,6 +24,11 @@ namespace Botan { namespace { +bool known_pbes_cipher_mode(const std::string& mode) + { + return (mode == "CBC" || mode == "GCM" || mode == "SIV"); + } + SymmetricKey derive_key(const std::string& passphrase, const AlgorithmIdentifier& kdf_algo, size_t default_key_size) @@ -46,13 +52,11 @@ SymmetricKey derive_key(const std::string& passphrase, if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); - const std::string prf = OIDS::lookup(prf_algo.get_oid()); - - std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); - if(key_length == 0) key_length = default_key_size; + const std::string prf = OIDS::lookup(prf_algo.get_oid()); + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); return pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); } #if defined(BOTAN_HAS_SCRYPT) @@ -101,24 +105,39 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase, { #if defined(BOTAN_HAS_SCRYPT) - Scrypt_Params params(32768, 8, 4); + std::unique_ptr<PasswordHashFamily> pwhash_fam = PasswordHashFamily::create_or_throw("Scrypt"); + + std::unique_ptr<PasswordHash> pwhash; if(msec_in_iterations_out) - params = Scrypt_Params(std::chrono::milliseconds(*msec_in_iterations_out)); + { + const std::chrono::milliseconds msec(*msec_in_iterations_out); + pwhash = pwhash_fam->tune(key_length, msec); + } else - params = Scrypt_Params(iterations_if_msec_null); + { + pwhash = pwhash_fam->from_iterations(iterations_if_msec_null); + } secure_vector<uint8_t> key(key_length); - scrypt(key.data(), key.size(), passphrase, - salt.data(), salt.size(), params); + pwhash->derive_key(key.data(), key.size(), + passphrase.c_str(), passphrase.size(), + salt.data(), salt.size()); + + const size_t N = pwhash->memory_param(); + const size_t r = pwhash->iterations(); + const size_t p = pwhash->parallelism(); + + if(msec_in_iterations_out) + *msec_in_iterations_out = 0; std::vector<uint8_t> scrypt_params; DER_Encoder(scrypt_params) .start_cons(SEQUENCE) .encode(salt, OCTET_STRING) - .encode(params.N()) - .encode(params.r()) - .encode(params.p()) + .encode(N) + .encode(r) + .encode(p) .encode(key_length) .end_cons(); @@ -131,26 +150,36 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase, else { const std::string prf = "HMAC(" + digest + ")"; + const std::string pbkdf_name = "PBKDF2(" + prf + ")"; - std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); - - size_t iterations = iterations_if_msec_null; + std::unique_ptr<PasswordHashFamily> pwhash_fam = PasswordHashFamily::create(pbkdf_name); + if(!pwhash_fam) + throw Invalid_Argument("Unknown password hash digest " + digest); - secure_vector<uint8_t> key; + std::unique_ptr<PasswordHash> pwhash; if(msec_in_iterations_out) { - std::chrono::milliseconds msec(*msec_in_iterations_out); - key = pbkdf->derive_key(key_length, passphrase, salt.data(), salt.size(), msec, iterations).bits_of(); - *msec_in_iterations_out = iterations; + const std::chrono::milliseconds msec(*msec_in_iterations_out); + pwhash = pwhash_fam->tune(key_length, msec); } else { - key = pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); + pwhash = pwhash_fam->from_iterations(iterations_if_msec_null); } + secure_vector<uint8_t> key(key_length); + pwhash->derive_key(key.data(), key.size(), + passphrase.c_str(), passphrase.size(), + salt.data(), salt.size()); + std::vector<uint8_t> pbkdf2_params; + const size_t iterations = pwhash->iterations(); + + if(msec_in_iterations_out) + *msec_in_iterations_out = iterations; + DER_Encoder(pbkdf2_params) .start_cons(SEQUENCE) .encode(salt, OCTET_STRING) @@ -181,7 +210,7 @@ pbes2_encrypt_shared(const secure_vector<uint8_t>& key_bits, if(cipher_spec.size() != 2) throw Encoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Encoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); const OID cipher_oid = OIDS::lookup(cipher); @@ -289,7 +318,7 @@ pbes2_decrypt(const secure_vector<uint8_t>& key_bits, const std::vector<std::string> cipher_spec = split_on(cipher, '/'); if(cipher_spec.size() != 2) throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); secure_vector<uint8_t> iv; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp index 89ef7c708e..9ea89c59f0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp @@ -71,7 +71,6 @@ #if defined(BOTAN_HAS_SM2) #include <botan/sm2.h> - #include <botan/sm2_enc.h> #endif #if defined(BOTAN_HAS_OPENSSL) @@ -152,10 +151,8 @@ load_public_key(const AlgorithmIdentifier& alg_id, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Public_Key>(new SM2_Signature_PublicKey(alg_id, key_bits)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Public_Key>(new SM2_Encryption_PublicKey(alg_id, key_bits)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Public_Key>(new SM2_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_XMSS) @@ -230,10 +227,8 @@ load_private_key(const AlgorithmIdentifier& alg_id, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(alg_id, key_bits)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(alg_id, key_bits)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Private_Key>(new SM2_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ELGAMAL) @@ -255,7 +250,7 @@ namespace { std::string default_ec_group_for(const std::string& alg_name) { - if(alg_name == "SM2_Enc" || alg_name == "SM2_Sig") + if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") return "sm2p256v1"; if(alg_name == "GOST-34.10") return "gost_256A"; @@ -341,6 +336,7 @@ create_private_key(const std::string& alg_name, alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || + alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10") @@ -368,10 +364,8 @@ create_private_key(const std::string& alg_name, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(rng, ec_group)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(rng, ec_group)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_ECGDSA) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h index 0aaf0b0dfe..63ef9fa9bd 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h @@ -42,6 +42,8 @@ class BOTAN_PUBLIC_API(2,0) Encryption virtual size_t max_input_bits() const = 0; + virtual size_t ciphertext_length(size_t ptext_len) const = 0; + virtual ~Encryption() = default; }; @@ -55,6 +57,8 @@ class BOTAN_PUBLIC_API(2,0) Decryption const uint8_t ciphertext[], size_t ciphertext_len) = 0; + virtual size_t plaintext_length(size_t ctext_len) const = 0; + virtual ~Decryption() = default; }; @@ -99,6 +103,11 @@ class BOTAN_PUBLIC_API(2,0) Signature */ virtual secure_vector<uint8_t> sign(RandomNumberGenerator& rng) = 0; + /* + * Return an upper bound on the length of the output signature + */ + virtual size_t signature_length() const = 0; + virtual ~Signature() = default; }; @@ -109,8 +118,10 @@ class BOTAN_PUBLIC_API(2,0) Key_Agreement { public: virtual secure_vector<uint8_t> agree(size_t key_len, - const uint8_t other_key[], size_t other_key_len, - const uint8_t salt[], size_t salt_len) = 0; + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) = 0; + + virtual size_t agreed_value_size() const = 0; virtual ~Key_Agreement() = default; }; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp index 8d3eba6dc7..f6d50256d0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp @@ -97,7 +97,7 @@ secure_vector<uint8_t> PKCS8_decode( } catch(Decoding_Error& e) { - throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + throw Decoding_Error("PKCS #8 private key decoding", e); } try @@ -126,7 +126,7 @@ secure_vector<uint8_t> PKCS8_decode( } catch(std::exception& e) { - throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + throw Decoding_Error("PKCS #8 private key decoding", e); } return key; } @@ -167,7 +167,9 @@ choose_pbe_params(const std::string& pbe_algo, const std::string& key_algo) } SCAN_Name request(pbe_algo); - if(request.algo_name() != "PBE-PKCS5v20" || request.arg_count() != 2) + if(request.arg_count() != 2) + throw Exception("Unsupported PBE " + pbe_algo); + if(request.algo_name() != "PBE-PKCS5v20" && request.algo_name() != "PBES2") throw Exception("Unsupported PBE " + pbe_algo); return std::make_pair(request.arg(0), request.arg(1)); } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h index 0bc9a18f14..a243c4fda4 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h @@ -180,7 +180,7 @@ PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, /** * Load an encrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param get_passphrase a function that returns passphrases * @return loaded private key object */ @@ -190,7 +190,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** Load an encrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param pass the passphrase to decrypt the key * @return loaded private key object */ @@ -200,7 +200,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** Load an unencrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return loaded private key object */ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, @@ -210,7 +210,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** * Load an encrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param get_passphrase a function that returns passphrases * @return loaded private key object */ @@ -220,7 +220,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** Load an encrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param pass the passphrase to decrypt the key * @return loaded private key object */ @@ -230,7 +230,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** Load an unencrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return loaded private key object */ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, @@ -240,7 +240,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** * Copy an existing encoded key object. * @param key the key to copy -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return new copy of the key */ BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key, diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp index 99d8927663..bb01705488 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp @@ -96,6 +96,11 @@ PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ } +size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const + { + return m_op->ciphertext_length(ptext_len); + } + std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const { @@ -119,6 +124,11 @@ PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ } +size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const + { + return m_op->plaintext_length(ctext_len); + } + secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const { @@ -200,6 +210,11 @@ PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : m_op(std::move(other.m_op)) {} +size_t PK_Key_Agreement::agreed_value_size() const + { + return m_op->agreed_value_size(); + } + SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], @@ -252,6 +267,22 @@ std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, } +size_t PK_Signer::signature_length() const + { + if(m_sig_format == IEEE_1363) + { + return m_op->signature_length(); + } + else if(m_sig_format == DER_SEQUENCE) + { + // This is a large over-estimate but its easier than computing + // the exact value + return m_op->signature_length() + (8 + 4*m_parts); + } + else + throw Internal_Error("PK_Signer: Invalid signature format enum"); + } + std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) { const std::vector<uint8_t> sig = unlock(m_op->sign(rng)); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h index a33142079f..2e2557ff88 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h @@ -66,6 +66,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Encryptor */ virtual size_t maximum_input_size() const = 0; + /** + * Return an upper bound on the ciphertext length + */ + virtual size_t ciphertext_length(size_t ctext_len) const = 0; + PK_Encryptor() = default; virtual ~PK_Encryptor() = default; @@ -140,6 +145,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Decryptor const uint8_t required_content_offsets[], size_t required_contents) const; + /** + * Return an upper bound on the plaintext length for a particular + * ciphertext input length + */ + virtual size_t plaintext_length(size_t ctext_len) const = 0; + PK_Decryptor() = default; virtual ~PK_Decryptor() = default; @@ -217,19 +228,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final * @param rng the rng to use * @return signature */ - std::vector<uint8_t> sign_message(const std::vector<uint8_t>& in, - RandomNumberGenerator& rng) - { return sign_message(in.data(), in.size(), rng); } - - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return signature - */ - std::vector<uint8_t> sign_message(const secure_vector<uint8_t>& in, - RandomNumberGenerator& rng) - { return sign_message(in.data(), in.size(), rng); } + template<typename Alloc> + std::vector<uint8_t> sign_message(const std::vector<uint8_t, Alloc>& in, + RandomNumberGenerator& rng) + { + return sign_message(in.data(), in.size(), rng); + } /** * Add a message part (single byte). @@ -248,7 +252,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final * Add a message part. * @param in the message part to add */ - void update(const std::vector<uint8_t>& in) { update(in.data(), in.size()); } + template<typename Alloc> + void update(const std::vector<uint8_t, Alloc>& in) + { + update(in.data(), in.size()); + } /** * Add a message part. @@ -267,11 +275,19 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final */ std::vector<uint8_t> signature(RandomNumberGenerator& rng); + /** * Set the output format of the signature. * @param format the signature format to use */ void set_output_format(Signature_Format format) { m_sig_format = format; } + + /** + * Return an upper bound on the length of the signatures this + * PK_Signer will produce + */ + size_t signature_length() const; + private: std::unique_ptr<PK_Ops::Signature> m_op; Signature_Format m_sig_format; @@ -347,8 +363,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Verifier final * signature to be verified. * @param in the new message part */ - void update(const std::vector<uint8_t>& in) - { update(in.data(), in.size()); } + template<typename Alloc> + void update(const std::vector<uint8_t, Alloc>& in) + { + update(in.data(), in.size()); + } /** * Add a message part of the message corresponding to the @@ -393,7 +412,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Verifier final }; /** -* Key used for key agreement +* Object used for key agreement */ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final { @@ -435,7 +454,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete; PK_Key_Agreement(const PK_Key_Agreement&) = delete; - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -449,11 +468,10 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final const uint8_t params[], size_t params_len) const; - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key - * @param in_len the length of in in bytes * @param params extra derivation params * @param params_len the length of params in bytes */ @@ -466,7 +484,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params, params_len); } - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -482,7 +500,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params.length()); } - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -497,6 +515,13 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params.length()); } + /** + * Return the underlying size of the value that is agreed. + * If derive_key is called with a length of 0 with a "Raw" + * KDF, it will return a value of this size. + */ + size_t agreed_value_size() const; + private: std::unique_ptr<PK_Ops::Key_Agreement> m_op; }; @@ -539,6 +564,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Encryptor_EME final : public PK_Encryptor PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete; PK_Encryptor_EME(const PK_Encryptor_EME&) = delete; + + /** + * Return an upper bound on the ciphertext length for a particular + * plaintext input length + */ + size_t ciphertext_length(size_t ptext_len) const override; private: std::vector<uint8_t> enc(const uint8_t[], size_t, RandomNumberGenerator& rng) const override; @@ -578,6 +609,8 @@ class BOTAN_PUBLIC_API(2,0) PK_Decryptor_EME final : public PK_Decryptor PK_Decryptor_EME(key, system_rng(), eme, provider) {} #endif + size_t plaintext_length(size_t ptext_len) const override; + ~PK_Decryptor_EME(); PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete; PK_Decryptor_EME(const PK_Decryptor_EME&) = delete; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp index eb4c612ae0..ec3c35ef1c 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp @@ -298,6 +298,8 @@ class RSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA, size_t max_input_bits() const override { return get_max_input_bits(); } + size_t signature_length() const override { return m_key.get_n().bytes(); } + RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : PK_Ops::Signature_with_EMSA(emsa), RSA_Private_Operation(rsa, rng) @@ -326,6 +328,8 @@ class RSA_Decryption_Operation final : public PK_Ops::Decryption_with_EME, { } + size_t plaintext_length(size_t) const override { return m_mod_bytes; } + secure_vector<uint8_t> raw_decrypt(const uint8_t msg[], size_t msg_len) override { const BigInt m(msg, msg_len); @@ -403,6 +407,8 @@ class RSA_Encryption_Operation final : public PK_Ops::Encryption_with_EME, { } + size_t ciphertext_length(size_t) const override { return m_n.bytes(); } + size_t max_raw_input_bits() const override { return get_max_input_bits(); } secure_vector<uint8_t> raw_encrypt(const uint8_t msg[], size_t msg_len, diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp index 6e49d953a4..fff75ec441 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp @@ -62,13 +62,13 @@ Public_Key* load_key(DataSource& source) } if(key_bits.empty()) - throw Decoding_Error("X.509 public key decoding failed"); + throw Decoding_Error("X.509 public key decoding"); return load_public_key(alg_id, key_bits).release(); } catch(Decoding_Error& e) { - throw Decoding_Error("X.509 public key decoding failed: " + std::string(e.what())); + throw Decoding_Error("X.509 public key decoding", e); } } diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp index ec439e7cfb..8494f115a2 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp +++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp @@ -100,7 +100,7 @@ size_t AutoSeeded_RNG::reseed(Entropy_Sources& srcs, void AutoSeeded_RNG::randomize(uint8_t output[], size_t output_len) { - randomize_with_ts_input(output, output_len); + m_rng->randomize_with_ts_input(output, output_len); } void AutoSeeded_RNG::randomize_with_input(uint8_t output[], size_t output_len, diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h index 866c56e12f..8cb2c4a127 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h +++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h @@ -27,6 +27,8 @@ class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator bool is_seeded() const override; + bool accepts_input() const override { return true; } + /** * Mark state as requiring a reseed on next use */ @@ -52,7 +54,9 @@ class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator AutoSeeded_RNG(size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); /** - * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * Create an AutoSeeded_RNG which will get seed material from some other + * RNG instance. For example you could provide a reference to the system + * RNG or a hardware RNG. * * @param underlying_rng is a reference to some RNG which will be used * to perform the periodic reseeding @@ -63,7 +67,8 @@ class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); /** - * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * Create an AutoSeeded_RNG which will get seed material from a set of + * entropy sources. * * @param entropy_sources will be polled to perform reseeding periodically * @param reseed_interval specifies a limit of how many times @@ -73,7 +78,8 @@ class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); /** - * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * Create an AutoSeeded_RNG which will get seed material from both an + * underlying RNG and a set of entropy sources. * * @param underlying_rng is a reference to some RNG which will be used * to perform the periodic reseeding diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp index c365a5f760..a3ea259217 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp +++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp @@ -17,11 +17,17 @@ namespace Botan { RDRAND_RNG::RDRAND_RNG() { - if(!CPUID::has_rdrand()) + if(!RDRAND_RNG::available()) throw Exception("Current CPU does not support RDRAND instruction"); } //static +bool RDRAND_RNG::available() + { + return CPUID::has_rdrand(); + } + +//static uint32_t RDRAND_RNG::rdrand() { for(;;) diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h index 377de419f7..181edcd47d 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h +++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h @@ -30,6 +30,13 @@ class BOTAN_PUBLIC_API(2,0) RDRAND_RNG final : public Hardware_RNG static uint32_t rdrand(); /** + * Return true if RDRAND is available on the current processor + */ + static bool available(); + + bool accepts_input() const override { return false; } + + /** * Constructor will throw if CPU does not have RDRAND bit set */ RDRAND_RNG(); diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp index 2cf3b7b81e..2947ac6295 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/rng.cpp +++ b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp @@ -17,15 +17,22 @@ namespace Botan { void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len) { - /* - Form additional input which is provided to the PRNG implementation - to paramaterize the KDF output. - */ - uint8_t additional_input[16] = { 0 }; - store_le(OS::get_system_timestamp_ns(), additional_input); - store_le(OS::get_high_resolution_clock(), additional_input + 8); + if(this->accepts_input()) + { + /* + Form additional input which is provided to the PRNG implementation + to paramaterize the KDF output. + */ + uint8_t additional_input[16] = { 0 }; + store_le(OS::get_system_timestamp_ns(), additional_input); + store_le(OS::get_high_resolution_clock(), additional_input + 8); - randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + this->randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + } + else + { + this->randomize(output, output_len); + } } void RandomNumberGenerator::randomize_with_input(uint8_t output[], size_t output_len, @@ -39,14 +46,24 @@ size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs, size_t poll_bits, std::chrono::milliseconds poll_timeout) { - return srcs.poll(*this, poll_bits, poll_timeout); + if(this->accepts_input()) + { + return srcs.poll(*this, poll_bits, poll_timeout); + } + else + { + return 0; + } } void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) { - secure_vector<uint8_t> buf(poll_bits / 8); - rng.randomize(buf.data(), buf.size()); - this->add_entropy(buf.data(), buf.size()); + if(this->accepts_input()) + { + secure_vector<uint8_t> buf(poll_bits / 8); + rng.randomize(buf.data(), buf.size()); + this->add_entropy(buf.data(), buf.size()); + } } RandomNumberGenerator* RandomNumberGenerator::make_rng() diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.h b/src/libs/3rdparty/botan/src/lib/rng/rng.h index f6fa80df06..db42c8cf77 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/rng.h +++ b/src/libs/3rdparty/botan/src/lib/rng/rng.h @@ -42,6 +42,15 @@ class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator virtual void randomize(uint8_t output[], size_t length) = 0; /** + * Returns false if it is known that this RNG object is not able to accept + * externally provided inputs (via add_entropy, randomize_with_input, etc). + * In this case, any such provided inputs are ignored. + * + * If this function returns true, then inputs may or may not be accepted. + */ + virtual bool accepts_input() const = 0; + + /** * Incorporate some additional data into the RNG state. For * example adding nonces or timestamps from a peer's protocol * message can help hedge against VM state rollback attacks. @@ -173,8 +182,7 @@ class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator typedef RandomNumberGenerator RNG; /** -* Hardware_RNG has no members but exists to tag hardware RNG types -* (PKCS11_RNG, TPM_RNG, RDRAND_RNG) +* Hardware_RNG exists to tag hardware RNG types (PKCS11_RNG, TPM_RNG, RDRAND_RNG) */ class BOTAN_PUBLIC_API(2,0) Hardware_RNG : public RandomNumberGenerator { @@ -191,6 +199,8 @@ class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator public: bool is_seeded() const override { return false; } + bool accepts_input() const override { return false; } + void clear() override {} void randomize(uint8_t[], size_t) override @@ -218,6 +228,12 @@ class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator m_rng->randomize(out, len); } + bool accepts_input() const override + { + lock_guard_type<mutex_type> lock(m_mutex); + return m_rng->accepts_input(); + } + bool is_seeded() const override { lock_guard_type<mutex_type> lock(m_mutex); diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h index 18697ae231..9bf04327ad 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h +++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h @@ -75,6 +75,8 @@ class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator bool is_seeded() const override final; + bool accepts_input() const override final { return true; } + /** * Mark state as requiring a reseed on next use */ diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp index c3b37ea9cc..ae027d0217 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp +++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp @@ -19,6 +19,10 @@ #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) #include <stdlib.h> +#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM) + #include <sys/random.h> + #include <errno.h> + #elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM) #include <sys/types.h> #include <sys/stat.h> @@ -44,13 +48,14 @@ class System_RNG_Impl final : public RandomNumberGenerator void randomize(uint8_t buf[], size_t len) override { - bool success = m_rtlgenrandom(buf, len) == TRUE; + bool success = m_rtlgenrandom(buf, ULONG(len)) == TRUE; if(!success) throw Exception("RtlGenRandom failed"); } void add_entropy(const uint8_t[], size_t) override { /* ignored */ } bool is_seeded() const override { return true; } + bool accepts_input() const override { return false; } void clear() override { /* not possible */ } std::string name() const override { return "RtlGenRandom"; } private: @@ -98,6 +103,7 @@ class System_RNG_Impl final : public RandomNumberGenerator } bool is_seeded() const override { return true; } + bool accepts_input() const override { return false; } void clear() override { /* not possible */ } std::string name() const override { return "crypto_ng"; } private: @@ -116,12 +122,48 @@ class System_RNG_Impl final : public RandomNumberGenerator ::arc4random_buf(buf, len); } + bool accepts_input() const override { return false; } void add_entropy(const uint8_t[], size_t) override { /* ignored */ } bool is_seeded() const override { return true; } void clear() override { /* not possible */ } std::string name() const override { return "arc4random"; } }; +#elif defined(BOTAN_TARGET_OS_HAS_GETRANDOM) + +class System_RNG_Impl final : public RandomNumberGenerator + { + public: + // No constructor or destructor needed as no userland state maintained + + void randomize(uint8_t buf[], size_t len) override + { + const unsigned int flags = 0; + + while(len > 0) + { + const ssize_t got = ::getrandom(buf, len, flags); + + if(got < 0) + { + if(errno == EINTR) + continue; + throw Exception("System_RNG getrandom failed error " + std::to_string(errno)); + } + + buf += got; + len -= got; + } + } + + bool accepts_input() const override { return false; } + void add_entropy(const uint8_t[], size_t) override { /* ignored */ } + bool is_seeded() const override { return true; } + void clear() override { /* not possible */ } + std::string name() const override { return "getrandom"; } + }; + + #elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM) // Read a random device @@ -137,12 +179,19 @@ class System_RNG_Impl final : public RandomNumberGenerator m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY); - /* - Cannot open in read-write mode. Fall back to read-only, - calls to add_entropy will fail, but randomize will work - */ - if(m_fd < 0) + if(m_fd >= 0) + { + m_writable = true; + } + else + { + /* + Cannot open in read-write mode. Fall back to read-only, + calls to add_entropy will fail, but randomize will work + */ m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY); + m_writable = false; + } if(m_fd < 0) throw Exception("System_RNG failed to open RNG device"); @@ -157,10 +206,12 @@ class System_RNG_Impl final : public RandomNumberGenerator void randomize(uint8_t buf[], size_t len) override; void add_entropy(const uint8_t in[], size_t length) override; bool is_seeded() const override { return true; } + bool accepts_input() const override { return m_writable; } void clear() override { /* not possible */ } std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; } private: int m_fd; + bool m_writable; }; void System_RNG_Impl::randomize(uint8_t buf[], size_t len) @@ -185,6 +236,9 @@ void System_RNG_Impl::randomize(uint8_t buf[], size_t len) void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len) { + if(!m_writable) + return; + while(len) { ssize_t got = ::write(m_fd, input, len); diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h index 4e3beaf9fb..e0f0181ca1 100644 --- a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h +++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h @@ -33,6 +33,8 @@ class BOTAN_PUBLIC_API(2,0) System_RNG final : public RandomNumberGenerator bool is_seeded() const override { return system_rng().is_seeded(); } + bool accepts_input() const override { return system_rng().accepts_input(); } + void clear() override { system_rng().clear(); } }; diff --git a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp index 2616463443..22cfade9b1 100644 --- a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp +++ b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp @@ -44,6 +44,26 @@ void CTR_BE::clear() m_pad_pos = 0; } +size_t CTR_BE::default_iv_length() const + { + return m_block_size; + } + +bool CTR_BE::valid_iv_length(size_t iv_len) const + { + return (iv_len <= m_block_size); + } + +Key_Length_Specification CTR_BE::key_spec() const + { + return m_cipher->key_spec(); + } + +CTR_BE* CTR_BE::clone() const + { + return new CTR_BE(m_cipher->clone(), m_ctr_size); + } + void CTR_BE::key_schedule(const uint8_t key[], size_t key_len) { m_cipher->set_key(key, key_len); @@ -106,7 +126,7 @@ void CTR_BE::set_iv(const uint8_t iv[], size_t iv_len) if(!valid_iv_length(iv_len)) throw Invalid_IV_Length(name(), iv_len); - m_iv.resize(m_cipher->block_size()); + m_iv.resize(m_block_size); zeroise(m_iv); buffer_insert(m_iv, 0, iv, iv_len); @@ -122,37 +142,42 @@ void CTR_BE::add_counter(const uint64_t counter) if(ctr_size == 4) { size_t off = (BS - 4); + uint32_t low32 = counter + load_be<uint32_t>(&m_counter[off], 0); + for(size_t i = 0; i != ctr_blocks; ++i) { - uint32_t low32 = load_be<uint32_t>(&m_counter[off], 0); - low32 += counter; store_be(low32, &m_counter[off]); off += BS; + low32 += 1; } } else if(ctr_size == 8) { size_t off = (BS - 8); + uint64_t low64 = counter + load_be<uint64_t>(&m_counter[off], 0); + for(size_t i = 0; i != ctr_blocks; ++i) { - uint64_t low64 = load_be<uint64_t>(&m_counter[off], 0); - low64 += counter; store_be(low64, &m_counter[off]); off += BS; + low64 += 1; } } else if(ctr_size == 16) { size_t off = (BS - 16); + uint64_t b0 = load_be<uint64_t>(&m_counter[off], 0); + uint64_t b1 = load_be<uint64_t>(&m_counter[off], 1); + b1 += counter; + b0 += (b1 < counter) ? 1 : 0; // carry + for(size_t i = 0; i != ctr_blocks; ++i) { - uint64_t b0 = load_be<uint64_t>(&m_counter[off], 0); - uint64_t b1 = load_be<uint64_t>(&m_counter[off], 1); - b1 += counter; - b0 += (b1 < counter) ? 1 : 0; // carry store_be(b0, &m_counter[off]); store_be(b1, &m_counter[off+8]); off += BS; + b1 += 1; + b0 += (b1 == 0); // carry } } else @@ -185,13 +210,27 @@ void CTR_BE::seek(uint64_t offset) const size_t BS = m_block_size; // Set m_counter blocks to IV, IV + 1, ... IV + n - for(size_t i = 1; i != m_ctr_blocks; ++i) + + if(m_ctr_size == 4 && BS >= 8) { - buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS); + const uint32_t low32 = load_be<uint32_t>(&m_counter[BS-4], 0); + for(size_t i = 1; i != m_ctr_blocks; ++i) + { + copy_mem(&m_counter[i*BS], &m_counter[0], BS); + uint32_t c = low32 + i; + store_be(c, &m_counter[(BS-4)+i*BS]); + } + } + else + { + for(size_t i = 1; i != m_ctr_blocks; ++i) + { + buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS); - for(size_t j = 0; j != m_ctr_size; ++j) - if(++m_counter[i*BS + (BS - 1 - j)]) - break; + for(size_t j = 0; j != m_ctr_size; ++j) + if(++m_counter[i*BS + (BS - 1 - j)]) + break; + } } if(base_counter > 0) diff --git a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h index c4c5981616..79911b2feb 100644 --- a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h +++ b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h @@ -23,18 +23,15 @@ class BOTAN_PUBLIC_API(2,0) CTR_BE final : public StreamCipher void set_iv(const uint8_t iv[], size_t iv_len) override; - bool valid_iv_length(size_t iv_len) const override - { return (iv_len <= m_cipher->block_size()); } + size_t default_iv_length() const override; - Key_Length_Specification key_spec() const override - { - return m_cipher->key_spec(); - } + bool valid_iv_length(size_t iv_len) const override; + + Key_Length_Specification key_spec() const override; std::string name() const override; - CTR_BE* clone() const override - { return new CTR_BE(m_cipher->clone(), m_ctr_size); } + CTR_BE* clone() const override; void clear() override; diff --git a/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h index 03ffcadd04..25bbc3287b 100644 --- a/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h +++ b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h @@ -58,6 +58,17 @@ class BOTAN_PUBLIC_API(2,0) StreamCipher : public SymmetricAlgorithm virtual void cipher(const uint8_t in[], uint8_t out[], size_t len) = 0; /** + * Write keystream bytes to a buffer + * @param out the byte array to hold the keystream + * @param len the length of out in bytes + */ + virtual void write_keystream(uint8_t out[], size_t len) + { + clear_mem(out, len); + cipher1(out, len); + } + + /** * Encrypt or decrypt a message * The message is encrypted/decrypted in place. * @param buf the plaintext / ciphertext @@ -101,6 +112,12 @@ class BOTAN_PUBLIC_API(2,0) StreamCipher : public SymmetricAlgorithm virtual void set_iv(const uint8_t iv[], size_t iv_len) = 0; /** + * Return the default (preferred) nonce length + * If this function returns 0, then this cipher does not support nonces + */ + virtual size_t default_iv_length() const { return 0; } + + /** * @param iv_len the length of the IV in bytes * @return if the length is valid for this algorithm */ diff --git a/src/libs/3rdparty/botan/src/lib/utils/assert.cpp b/src/libs/3rdparty/botan/src/lib/utils/assert.cpp index cd957e00d1..31a35374a6 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/assert.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/assert.cpp @@ -15,12 +15,19 @@ void throw_invalid_argument(const char* message, const char* file) { std::ostringstream format; - format << message << " in " << func << ":" << file; - throw Invalid_Argument(format.str()); } +void throw_invalid_state(const char* expr, + const char* func, + const char* file) + { + std::ostringstream format; + format << "Invalid state: " << expr << " was false in " << func << ":" << file; + throw Invalid_State(format.str()); + } + void assertion_failure(const char* expr_str, const char* assertion_made, const char* func, diff --git a/src/libs/3rdparty/botan/src/lib/utils/assert.h b/src/libs/3rdparty/botan/src/lib/utils/assert.h index a12872f2bc..20e15ac0ea 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/assert.h +++ b/src/libs/3rdparty/botan/src/lib/utils/assert.h @@ -38,6 +38,18 @@ BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* messag do { if(!(expr)) Botan::throw_invalid_argument(msg, BOTAN_CURRENT_FUNCTION, __FILE__); } while(0) /** +* Called when an invalid state is encountered +* Throws Invalid_State +*/ +BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, + const char* func, + const char* file); + + +#define BOTAN_STATE_CHECK(expr) \ + do { if(!(expr)) Botan::throw_invalid_state(#expr, BOTAN_CURRENT_FUNCTION, __FILE__); } while(0) + +/** * Make an assertion */ #define BOTAN_ASSERT(expr, assertion_made) \ diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp index 3938c72423..d2d08dd435 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp @@ -64,10 +64,16 @@ std::string CPUID::to_string() #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) CPUID_PRINT(neon); + CPUID_PRINT(arm_sve); + CPUID_PRINT(arm_sha1); CPUID_PRINT(arm_sha2); CPUID_PRINT(arm_aes); CPUID_PRINT(arm_pmull); + CPUID_PRINT(arm_sha2_512); + CPUID_PRINT(arm_sha3); + CPUID_PRINT(arm_sm3); + CPUID_PRINT(arm_sm4); #endif #undef CPUID_PRINT @@ -156,6 +162,8 @@ CPUID::bit_from_string(const std::string& tok) #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) if(tok == "altivec" || tok == "simd") return {Botan::CPUID::CPUID_ALTIVEC_BIT}; + if(tok == "ppc_crypto") + return {Botan::CPUID::CPUID_PPC_CRYPTO_BIT}; #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) if(tok == "neon" || tok == "simd") @@ -168,6 +176,14 @@ CPUID::bit_from_string(const std::string& tok) return {Botan::CPUID::CPUID_ARM_AES_BIT}; if(tok == "armv8pmull") return {Botan::CPUID::CPUID_ARM_PMULL_BIT}; + if(tok == "armv8sha3") + return {Botan::CPUID::CPUID_ARM_SHA3_BIT}; + if(tok == "armv8sha2_512") + return {Botan::CPUID::CPUID_ARM_SHA2_512_BIT}; + if(tok == "armv8sm3") + return {Botan::CPUID::CPUID_ARM_SM3_BIT}; + if(tok == "armv8sm4") + return {Botan::CPUID::CPUID_ARM_SM4_BIT}; #else BOTAN_UNUSED(tok); diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h index 633824a6cc..95f6d687bb 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h @@ -114,11 +114,16 @@ class BOTAN_PUBLIC_API(2,1) CPUID final #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - CPUID_ARM_NEON_BIT = (1ULL << 0), - CPUID_ARM_AES_BIT = (1ULL << 16), - CPUID_ARM_PMULL_BIT = (1ULL << 17), - CPUID_ARM_SHA1_BIT = (1ULL << 18), - CPUID_ARM_SHA2_BIT = (1ULL << 19), + CPUID_ARM_NEON_BIT = (1ULL << 0), + CPUID_ARM_SVE_BIT = (1ULL << 1), + CPUID_ARM_AES_BIT = (1ULL << 16), + CPUID_ARM_PMULL_BIT = (1ULL << 17), + CPUID_ARM_SHA1_BIT = (1ULL << 18), + CPUID_ARM_SHA2_BIT = (1ULL << 19), + CPUID_ARM_SHA3_BIT = (1ULL << 20), + CPUID_ARM_SHA2_512_BIT = (1ULL << 21), + CPUID_ARM_SM3_BIT = (1ULL << 22), + CPUID_ARM_SM4_BIT = (1ULL << 23), #endif CPUID_INITIALIZED_BIT = (1ULL << 63) @@ -147,6 +152,12 @@ class BOTAN_PUBLIC_API(2,1) CPUID final { return has_cpuid_bit(CPUID_ARM_NEON_BIT); } /** + * Check if the processor supports ARMv8 SVE + */ + static bool has_arm_sve() + { return has_cpuid_bit(CPUID_ARM_SVE_BIT); } + + /** * Check if the processor supports ARMv8 SHA1 */ static bool has_arm_sha1() @@ -169,6 +180,31 @@ class BOTAN_PUBLIC_API(2,1) CPUID final */ static bool has_arm_pmull() { return has_cpuid_bit(CPUID_ARM_PMULL_BIT); } + + /** + * Check if the processor supports ARMv8 SHA-512 + */ + static bool has_arm_sha2_512() + { return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); } + + /** + * Check if the processor supports ARMv8 SHA-3 + */ + static bool has_arm_sha3() + { return has_cpuid_bit(CPUID_ARM_SHA3_BIT); } + + /** + * Check if the processor supports ARMv8 SM3 + */ + static bool has_arm_sm3() + { return has_cpuid_bit(CPUID_ARM_SM3_BIT); } + + /** + * Check if the processor supports ARMv8 SM4 + */ + static bool has_arm_sm4() + { return has_cpuid_bit(CPUID_ARM_SM4_BIT); } + #endif #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp index 39b6db652e..beb80f7d06 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp @@ -130,6 +130,11 @@ uint64_t CPUID::detect_cpu_features(size_t* cache_line_size) PMULL_bit = (1 << 4), SHA1_bit = (1 << 5), SHA2_bit = (1 << 6), + SHA3_bit = (1 << 17), + SM3_bit = (1 << 18), + SM4_bit = (1 << 19), + SHA2_512_bit = (1 << 21), + SVE_bit = (1 << 22), ARCH_hwcap_neon = 16, // AT_HWCAP ARCH_hwcap_crypto = 16, // AT_HWCAP @@ -163,6 +168,19 @@ uint64_t CPUID::detect_cpu_features(size_t* cache_line_size) if(hwcap_crypto & ARM_hwcap_bit::SHA2_bit) detected_features |= CPUID::CPUID_ARM_SHA2_BIT; +#if defined(BOTAN_TARGET_ARCH_IS_ARM64) + if(hwcap_crypto & ARM_hwcap_bit::SHA3_bit) + detected_features |= CPUID::CPUID_ARM_SHA3_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SM3_bit) + detected_features |= CPUID::CPUID_ARM_SM3_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SM4_bit) + detected_features |= CPUID::CPUID_ARM_SM4_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SHA2_512_bit) + detected_features |= CPUID::CPUID_ARM_SHA2_512_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SVE_bit) + detected_features |= CPUID::CPUID_ARM_SVE_BIT; +#endif + #elif defined(BOTAN_TARGET_OS_IS_IOS) char machine[64] = { 0 }; diff --git a/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h b/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h index 0132678742..f4f8818713 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h +++ b/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h @@ -15,6 +15,7 @@ #define BOTAN_TIMING_ATTACK_CM_H_ #include <botan/secmem.h> +#include <type_traits> #include <vector> #if defined(BOTAN_HAS_VALGRIND) @@ -74,6 +75,22 @@ inline void unpoison(T& p) #endif } +/* Mask generation */ + +template<typename T> +inline T expand_top_bit(T a) + { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return static_cast<T>(0) - (a >> (sizeof(T)*8-1)); + } + +template<typename T> +inline T is_zero(T x) + { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return expand_top_bit<T>(~x & (x - 1)); + } + /* * T should be an unsigned machine integer type * Expand to a mask used for other operations @@ -85,26 +102,14 @@ inline void unpoison(T& p) template<typename T> inline T expand_mask(T x) { - T r = x; - // First fold r down to a single bit - for(size_t i = 1; i != sizeof(T)*8; i *= 2) - { - r = r | static_cast<T>(r >> i); - } - r &= 1; - r = static_cast<T>(~(r - 1)); - return r; - } - -template<typename T> -inline T expand_top_bit(T a) - { - return expand_mask<T>(a >> (sizeof(T)*8-1)); + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return ~is_zero(x); } template<typename T> inline T select(T mask, T from0, T from1) { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); return static_cast<T>((from0 & mask) | (from1 & ~mask)); } @@ -127,12 +132,6 @@ inline ValT val_or_zero(PredT pred_val, ValT val) } template<typename T> -inline T is_zero(T x) - { - return static_cast<T>(~expand_mask(x)); - } - -template<typename T> inline T is_equal(T x, T y) { return is_zero<T>(x ^ y); @@ -150,6 +149,14 @@ inline T is_lte(T a, T b) return CT::is_less(a, b) | CT::is_equal(a, b); } +template<typename C, typename T> +inline T conditional_return(C condvar, T left, T right) + { + const T val = CT::select(CT::expand_mask<T>(condvar), left, right); + CT::unpoison(val); + return val; + } + template<typename T> inline T conditional_copy_mem(T value, T* to, diff --git a/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp b/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp index a72e45ba4c..cc6eb9f85c 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp @@ -11,18 +11,25 @@ namespace Botan { Exception::Exception(const std::string& msg) : m_msg(msg) {} +Exception::Exception(const std::string& msg, const std::exception& e) : + m_msg(msg + " failed with " + std::string(e.what())) + {} + Exception::Exception(const char* prefix, const std::string& msg) : m_msg(std::string(prefix) + " " + msg) {} Invalid_Argument::Invalid_Argument(const std::string& msg) : - Exception("Invalid argument", msg) + Exception(msg) {} Invalid_Argument::Invalid_Argument(const std::string& msg, const std::string& where) : - Exception("Invalid argument", msg + " in " + where) + Exception(msg + " in " + where) {} +Invalid_Argument::Invalid_Argument(const std::string& msg, const std::exception& e) : + Exception(msg, e) {} + Lookup_Error::Lookup_Error(const std::string& type, const std::string& algo, const std::string& provider) : @@ -76,11 +83,15 @@ Encoding_Error::Encoding_Error(const std::string& name) : {} Decoding_Error::Decoding_Error(const std::string& name) : - Invalid_Argument("Decoding error: " + name) + Invalid_Argument(name) + {} + +Decoding_Error::Decoding_Error(const std::string& msg, const std::exception& e) : + Invalid_Argument(msg, e) {} Decoding_Error::Decoding_Error(const std::string& name, const char* exception_message) : - Invalid_Argument("Decoding error: " + name + " failed with exception " + exception_message) {} + Invalid_Argument(name + " failed with exception " + exception_message) {} Integrity_Failure::Integrity_Failure(const std::string& msg) : Exception("Integrity failure: " + msg) diff --git a/src/libs/3rdparty/botan/src/lib/utils/exceptn.h b/src/libs/3rdparty/botan/src/lib/utils/exceptn.h index f2896aa83b..efa52580c7 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/exceptn.h +++ b/src/libs/3rdparty/botan/src/lib/utils/exceptn.h @@ -23,6 +23,8 @@ class BOTAN_PUBLIC_API(2,0) Exception : public std::exception Exception(const char* prefix, const std::string& msg); explicit Exception(const std::string& msg); const char* what() const BOTAN_NOEXCEPT override { return m_msg.c_str(); } + protected: + Exception(const std::string& msg, const std::exception& e); private: std::string m_msg; }; @@ -36,7 +38,9 @@ class BOTAN_PUBLIC_API(2,0) Invalid_Argument : public Exception explicit Invalid_Argument(const std::string& msg); explicit Invalid_Argument(const std::string& msg, const std::string& where); -}; + + Invalid_Argument(const std::string& msg, const std::exception& e); + }; /** * Unsupported_Argument Exception @@ -178,6 +182,8 @@ class BOTAN_PUBLIC_API(2,0) Decoding_Error : public Invalid_Argument explicit Decoding_Error(const std::string& name); Decoding_Error(const std::string& name, const char* exception_message); + + Decoding_Error(const std::string& msg, const std::exception& e); }; /** diff --git a/src/libs/3rdparty/botan/src/lib/utils/info.txt b/src/libs/3rdparty/botan/src/lib/utils/info.txt index fb9325f932..93ae795ef5 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/info.txt +++ b/src/libs/3rdparty/botan/src/lib/utils/info.txt @@ -1,5 +1,5 @@ <defines> -UTIL_FUNCTIONS -> 20171003 +UTIL_FUNCTIONS -> 20180903 </defines> load_on always @@ -35,6 +35,7 @@ prefetch.h rounding.h safeint.h stl_util.h +timer.h </header:internal> <requires> diff --git a/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp b/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp index c7f04a8554..86e5443c30 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp @@ -26,7 +26,13 @@ #include <setjmp.h> #include <unistd.h> #include <errno.h> -#elif defined(BOTAN_TARGET_OS_HAS_WIN32) +#endif + +#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) + #include <sys/auxv.h> +#endif + +#if defined(BOTAN_TARGET_OS_HAS_WIN32) #define NOMINMAX 1 #include <windows.h> #endif @@ -74,6 +80,17 @@ uint32_t OS::get_process_id() #endif } +bool OS::running_in_privileged_state() + { +#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) && defined(AT_SECURE) + return ::getauxval(AT_SECURE) != 0; +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + return (::getuid() != ::geteuid()) || (::getgid() != ::getegid()); +#else + return false; +#endif + } + uint64_t OS::get_processor_timestamp() { uint64_t rtc = 0; @@ -199,26 +216,30 @@ uint64_t OS::get_system_timestamp_ns() size_t OS::system_page_size() { + const size_t default_page_size = 4096; + #if defined(BOTAN_TARGET_OS_HAS_POSIX1) long p = ::sysconf(_SC_PAGESIZE); if(p > 1) return static_cast<size_t>(p); else - return 4096; + return default_page_size; #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) SYSTEM_INFO sys_info; ::GetSystemInfo(&sys_info); return sys_info.dwPageSize; +#else + return default_page_size; #endif - - // default value - return 4096; } size_t OS::get_memory_locking_limit() { -#if defined(BOTAN_TARGET_OS_HAS_POSIX1) +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(RLIMIT_MEMLOCK) /* + * If RLIMIT_MEMLOCK is not defined, likely the OS does not support + * unprivileged mlock calls. + * * Linux defaults to only 64 KiB of mlockable memory per process * (too small) but BSDs offer a small fraction of total RAM (more * than we need). Bound the total mlock size to 512 KiB which is @@ -232,17 +253,19 @@ size_t OS::get_memory_locking_limit() /* * Allow override via env variable */ - if(const char* env = std::getenv("BOTAN_MLOCK_POOL_SIZE")) + if(OS::running_in_privileged_state() == false) { - try + if(const char* env = std::getenv("BOTAN_MLOCK_POOL_SIZE")) { - const size_t user_req = std::stoul(env, nullptr); - mlock_requested = std::min(user_req, mlock_requested); + try + { + const size_t user_req = std::stoul(env, nullptr); + mlock_requested = std::min(user_req, mlock_requested); + } + catch(std::exception&) { /* ignore it */ } } - catch(std::exception&) { /* ignore it */ } } -#if defined(RLIMIT_MEMLOCK) if(mlock_requested > 0) { struct ::rlimit limits; @@ -258,13 +281,6 @@ size_t OS::get_memory_locking_limit() return std::min<size_t>(limits.rlim_cur, mlock_requested * 1024); } -#else - /* - * If RLIMIT_MEMLOCK is not defined, likely the OS does not support - * unprivileged mlock calls. - */ - return 0; -#endif #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) SIZE_T working_min = 0, working_max = 0; @@ -294,12 +310,13 @@ size_t OS::get_memory_locking_limit() } #endif + // Not supported on this platform return 0; } void* OS::allocate_locked_pages(size_t length) { -#if defined(BOTAN_TARGET_OS_HAS_POSIX1) +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) #if !defined(MAP_NOCORE) #define MAP_NOCORE 0 @@ -325,13 +342,11 @@ void* OS::allocate_locked_pages(size_t length) ::madvise(ptr, length, MADV_DONTDUMP); #endif -#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) if(::mlock(ptr, length) != 0) { ::munmap(ptr, length); return nullptr; // failed to lock } -#endif ::memset(ptr, 0, length); @@ -361,18 +376,16 @@ void OS::free_locked_pages(void* ptr, size_t length) if(ptr == nullptr || length == 0) return; -#if defined(BOTAN_TARGET_OS_HAS_POSIX1) +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) secure_scrub_memory(ptr, length); - -#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) ::munlock(ptr, length); -#endif - ::munmap(ptr, length); + #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) secure_scrub_memory(ptr, length); ::VirtualUnlock(ptr, length); ::VirtualFree(ptr, 0, MEM_RELEASE); + #else // Invalid argument because no way this pointer was allocated by us throw Invalid_Argument("Invalid ptr to free_locked_pages"); diff --git a/src/libs/3rdparty/botan/src/lib/utils/os_utils.h b/src/libs/3rdparty/botan/src/lib/utils/os_utils.h index 5210b2523b..778ace4e9d 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/os_utils.h +++ b/src/libs/3rdparty/botan/src/lib/utils/os_utils.h @@ -32,6 +32,12 @@ namespace OS { uint32_t BOTAN_TEST_API get_process_id(); /** +* Test if we are currently running with elevated permissions +* eg setuid, setgid, or with POSIX caps set. +*/ +bool running_in_privileged_state(); + +/** * @return CPU processor clock, if available * * On Windows, calls QueryPerformanceCounter. diff --git a/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp b/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp index cfae0cb708..8e62c6e03f 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp +++ b/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp @@ -347,8 +347,9 @@ std::string tolower_string(const std::string& in) std::string s = in; for(size_t i = 0; i != s.size(); ++i) { - if(std::isalpha(static_cast<unsigned char>(s[i]))) - s[i] = std::tolower(static_cast<unsigned char>(s[i])); + const int cu = static_cast<unsigned char>(s[i]); + if(std::isalpha(cu)) + s[i] = static_cast<char>(std::tolower(cu)); } return s; } @@ -415,7 +416,7 @@ bool host_wildcard_match(const std::string& issued_, const std::string& host_) /* Now walk through the issued string, making sure every character matches. When we come to the (singular) '*', jump forward in the - hostname by the cooresponding amount. We know exactly how much + hostname by the corresponding amount. We know exactly how much space the wildcard takes because it must be exactly `len(host) - len(issued) + 1 chars`. diff --git a/src/libs/3rdparty/botan/src/lib/utils/parsing.h b/src/libs/3rdparty/botan/src/lib/utils/parsing.h index 9185cfaadf..12cb3fa341 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/parsing.h +++ b/src/libs/3rdparty/botan/src/lib/utils/parsing.h @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#ifndef BOTAN_PARSER_H_ -#define BOTAN_PARSER_H_ +#ifndef BOTAN_PARSING_UTILS_H_ +#define BOTAN_PARSING_UTILS_H_ #include <botan/types.h> #include <string> @@ -40,6 +40,8 @@ BOTAN_PUBLIC_API(2,0) std::vector<std::string> split_on( * Split a string on a character predicate * @param str the input string * @param pred the predicate +* +* This function will likely be removed in a future release */ BOTAN_PUBLIC_API(2,0) std::vector<std::string> split_on_pred(const std::string& str, @@ -143,9 +145,30 @@ BOTAN_PUBLIC_API(2,0) std::string ipv4_to_string(uint32_t ip_addr); std::map<std::string, std::string> BOTAN_PUBLIC_API(2,0) read_cfg(std::istream& is); +/** +* Accepts key value pairs deliminated by commas: +* +* "" (returns empty map) +* "K=V" (returns map {'K': 'V'}) +* "K1=V1,K2=V2" +* "K1=V1,K2=V2,K3=V3" +* "K1=V1,K2=V2,K3=a_value\,with\,commas_and_\=equals" +* +* Values may be empty, keys must be non-empty and unique. Duplicate +* keys cause an exception. +* +* Within both key and value, comma and equals can be escaped with +* backslash. Backslash can also be escaped. +*/ +std::map<std::string, std::string> BOTAN_PUBLIC_API(2,8) read_kv(const std::string& kv); + std::string BOTAN_PUBLIC_API(2,0) clean_ws(const std::string& s); -bool BOTAN_PUBLIC_API(2,0) host_wildcard_match(const std::string& wildcard, const std::string& host); +/** +* Check if the given hostname is a match for the specified wildcard +*/ +bool BOTAN_PUBLIC_API(2,0) host_wildcard_match(const std::string& wildcard, + const std::string& host); } diff --git a/src/libs/3rdparty/botan/src/lib/utils/read_kv.cpp b/src/libs/3rdparty/botan/src/lib/utils/read_kv.cpp new file mode 100644 index 0000000000..cdc84c6229 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/read_kv.cpp @@ -0,0 +1,85 @@ +/* +* (C) 2018 Ribose Inc +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/parsing.h> +#include <botan/exceptn.h> + +namespace Botan { + +std::map<std::string, std::string> read_kv(const std::string& kv) + { + std::map<std::string, std::string> m; + if(kv == "") + return m; + + std::vector<std::string> parts; + + try + { + parts = split_on(kv, ','); + } + catch(std::exception&) + { + throw Invalid_Argument("Bad KV spec"); + } + + bool escaped = false; + bool reading_key = true; + std::string cur_key; + std::string cur_val; + + for(char c : kv) + { + if(c == '\\' && !escaped) + { + escaped = true; + } + else if(c == ',' && !escaped) + { + if(cur_key.empty()) + throw Invalid_Argument("Bad KV spec empty key"); + + if(m.find(cur_key) != m.end()) + throw Invalid_Argument("Bad KV spec duplicated key"); + m[cur_key] = cur_val; + cur_key = ""; + cur_val = ""; + reading_key = true; + } + else if(c == '=' && !escaped) + { + if(reading_key == false) + throw Invalid_Argument("Bad KV spec unexpected equals sign"); + reading_key = false; + } + else + { + if(reading_key) + cur_key += c; + else + cur_val += c; + + if(escaped) + escaped = false; + } + } + + if(!cur_key.empty()) + { + if(reading_key == false) + { + if(m.find(cur_key) != m.end()) + throw Invalid_Argument("Bad KV spec duplicated key"); + m[cur_key] = cur_val; + } + else + throw Invalid_Argument("Bad KV spec incomplete string"); + } + + return m; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h index 8e6ac3639c..20589939c2 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h +++ b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h @@ -268,55 +268,10 @@ class SIMD_4x32 final template<size_t ROT1, size_t ROT2, size_t ROT3> SIMD_4x32 rho() const { - SIMD_4x32 res; - -#if defined(BOTAN_SIMD_USE_SSE2) - - res.m_sse = _mm_or_si128(_mm_slli_epi32(m_sse, static_cast<int>(32-ROT1)), - _mm_srli_epi32(m_sse, static_cast<int>(ROT1))); - res.m_sse = _mm_xor_si128( - res.m_sse, - _mm_or_si128(_mm_slli_epi32(m_sse, static_cast<int>(32-ROT2)), - _mm_srli_epi32(m_sse, static_cast<int>(ROT2)))); - res.m_sse = _mm_xor_si128( - res.m_sse, - _mm_or_si128(_mm_slli_epi32(m_sse, static_cast<int>(32-ROT3)), - _mm_srli_epi32(m_sse, static_cast<int>(ROT3)))); - -#elif defined(BOTAN_SIMD_USE_ALTIVEC) - - const unsigned int r1 = static_cast<unsigned int>(32-ROT1); - const unsigned int r2 = static_cast<unsigned int>(32-ROT2); - const unsigned int r3 = static_cast<unsigned int>(32-ROT3); - res.m_vmx = vec_rl(m_vmx, (__vector unsigned int){r1, r1, r1, r1}); - res.m_vmx = vec_xor(res.m_vmx, vec_rl(m_vmx, (__vector unsigned int){r2, r2, r2, r2})); - res.m_vmx = vec_xor(res.m_vmx, vec_rl(m_vmx, (__vector unsigned int){r3, r3, r3, r3})); - -#elif defined(BOTAN_SIMD_USE_NEON) - res.m_neon = vorrq_u32(vshlq_n_u32(m_neon, static_cast<int>(32-ROT1)), - vshrq_n_u32(m_neon, static_cast<int>(ROT1))); - - res.m_neon = veorq_u32( - res.m_neon, - vorrq_u32(vshlq_n_u32(m_neon, static_cast<int>(32-ROT2)), - vshrq_n_u32(m_neon, static_cast<int>(ROT2)))); - - res.m_neon = veorq_u32( - res.m_neon, - vorrq_u32(vshlq_n_u32(m_neon, static_cast<int>(32-ROT3)), - vshrq_n_u32(m_neon, static_cast<int>(ROT3)))); - -#else - - for(size_t i = 0; i != 4; ++i) - { - res.m_scalar[i] = Botan::rotr<ROT1>(m_scalar[i]) ^ - Botan::rotr<ROT2>(m_scalar[i]) ^ - Botan::rotr<ROT3>(m_scalar[i]); - } -#endif - - return res; + const SIMD_4x32 rot1 = this->rotr<ROT1>(); + const SIMD_4x32 rot2 = this->rotr<ROT2>(); + const SIMD_4x32 rot3 = this->rotr<ROT3>(); + return (rot1 ^ rot2 ^ rot3); } /** diff --git a/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/info.txt b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/info.txt new file mode 100644 index 0000000000..e3d043a12e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/info.txt @@ -0,0 +1,16 @@ +<defines> +SIMD_AVX2 -> 20180824 +</defines> + +need_isa avx2 + +<header:internal> +simd_avx2.h +</header:internal> + +<cc> +gcc +clang +msvc +icc +</cc> diff --git a/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/simd_avx2.h b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/simd_avx2.h new file mode 100644 index 0000000000..19f9308540 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_avx2/simd_avx2.h @@ -0,0 +1,198 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SIMD_AVX2_H_ +#define BOTAN_SIMD_AVX2_H_ + +#include <botan/types.h> +#include <immintrin.h> + +namespace Botan { + +class SIMD_8x32 final + { + public: + + SIMD_8x32& operator=(const SIMD_8x32& other) = default; + SIMD_8x32(const SIMD_8x32& other) = default; + +#if !defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + SIMD_8x32& operator=(SIMD_8x32&& other) = default; + SIMD_8x32(SIMD_8x32&& other) = default; +#endif + + SIMD_8x32() + { + m_avx2 = _mm256_setzero_si256(); + } + + explicit SIMD_8x32(const uint32_t B[8]) + { + m_avx2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(B)); + } + + static SIMD_8x32 splat(uint32_t B) + { + return SIMD_8x32(_mm256_set1_epi32(B)); + } + + static SIMD_8x32 load_le(const uint8_t* in) + { + return SIMD_8x32(_mm256_loadu_si256(reinterpret_cast<const __m256i*>(in))); + } + + static SIMD_8x32 load_be(const uint8_t* in) + { + return load_le(in).bswap(); + } + + void store_le(uint8_t out[]) const + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(out), m_avx2); + } + + void store_be(uint8_t out[]) const + { + bswap().store_le(out); + } + + template<size_t ROT> + SIMD_8x32 rotl() const + { + static_assert(ROT > 0 && ROT < 32, "Invalid rotation constant"); + + return SIMD_8x32(_mm256_or_si256(_mm256_slli_epi32(m_avx2, static_cast<int>(ROT)), + _mm256_srli_epi32(m_avx2, static_cast<int>(32-ROT)))); + } + + template<size_t ROT> + SIMD_8x32 rotr() const + { + return this->rotl<32-ROT>(); + } + + SIMD_8x32 operator+(const SIMD_8x32& other) const + { + SIMD_8x32 retval(*this); + retval += other; + return retval; + } + + SIMD_8x32 operator-(const SIMD_8x32& other) const + { + SIMD_8x32 retval(*this); + retval -= other; + return retval; + } + + SIMD_8x32 operator^(const SIMD_8x32& other) const + { + SIMD_8x32 retval(*this); + retval ^= other; + return retval; + } + + SIMD_8x32 operator|(const SIMD_8x32& other) const + { + SIMD_8x32 retval(*this); + retval |= other; + return retval; + } + + SIMD_8x32 operator&(const SIMD_8x32& other) const + { + SIMD_8x32 retval(*this); + retval &= other; + return retval; + } + + void operator+=(const SIMD_8x32& other) + { + m_avx2 = _mm256_add_epi32(m_avx2, other.m_avx2); + } + + void operator-=(const SIMD_8x32& other) + { + m_avx2 = _mm256_sub_epi32(m_avx2, other.m_avx2); + } + + void operator^=(const SIMD_8x32& other) + { + m_avx2 = _mm256_xor_si256(m_avx2, other.m_avx2); + } + + void operator|=(const SIMD_8x32& other) + { + m_avx2 = _mm256_or_si256(m_avx2, other.m_avx2); + } + + void operator&=(const SIMD_8x32& other) + { + m_avx2 = _mm256_and_si256(m_avx2, other.m_avx2); + } + + template<int SHIFT> SIMD_8x32 shl() const + { + return SIMD_8x32(_mm256_slli_epi32(m_avx2, SHIFT)); + } + + template<int SHIFT> SIMD_8x32 shr() const + { + return SIMD_8x32(_mm256_srli_epi32(m_avx2, SHIFT)); + } + + SIMD_8x32 operator~() const + { + return SIMD_8x32(_mm256_xor_si256(m_avx2, _mm256_set1_epi32(0xFFFFFFFF))); + } + + // (~reg) & other + SIMD_8x32 andc(const SIMD_8x32& other) const + { + return SIMD_8x32(_mm256_andnot_si256(m_avx2, other.m_avx2)); + } + + SIMD_8x32 bswap() const + { + const uint8_t BSWAP_MASK[32] = { 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 }; + + const __m256i bswap = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(BSWAP_MASK)); + + const __m256i output = _mm256_shuffle_epi8(m_avx2, bswap); + + return SIMD_8x32(output); + } + + static void transpose(SIMD_8x32& B0, SIMD_8x32& B1, + SIMD_8x32& B2, SIMD_8x32& B3) + { + const __m256i T0 = _mm256_unpacklo_epi32(B0.m_avx2, B1.m_avx2); + const __m256i T1 = _mm256_unpacklo_epi32(B2.m_avx2, B3.m_avx2); + const __m256i T2 = _mm256_unpackhi_epi32(B0.m_avx2, B1.m_avx2); + const __m256i T3 = _mm256_unpackhi_epi32(B2.m_avx2, B3.m_avx2); + + B0.m_avx2 = _mm256_unpacklo_epi64(T0, T1); + B1.m_avx2 = _mm256_unpackhi_epi64(T0, T1); + B2.m_avx2 = _mm256_unpacklo_epi64(T2, T3); + B3.m_avx2 = _mm256_unpackhi_epi64(T2, T3); + } + + private: + SIMD_8x32(__m256i x) : m_avx2(x) {} + + __m256i m_avx2; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/timer.cpp b/src/libs/3rdparty/botan/src/lib/utils/timer.cpp new file mode 100644 index 0000000000..5d64e63fb8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/timer.cpp @@ -0,0 +1,118 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/timer.h> +#include <algorithm> +#include <sstream> +#include <iomanip> + +namespace Botan { + +void Timer::stop() + { + if(m_timer_start) + { + const uint64_t now = Timer::get_system_timestamp_ns(); + + if(now > m_timer_start) + { + uint64_t dur = now - m_timer_start; + + m_time_used += dur; + + if(m_cpu_cycles_start != 0) + { + uint64_t cycles_taken = Timer::get_cpu_cycle_counter() - m_cpu_cycles_start; + if(cycles_taken > 0) + { + m_cpu_cycles_used += static_cast<size_t>(cycles_taken * m_clock_cycle_ratio); + } + } + + if(m_event_count == 0) + { + m_min_time = m_max_time = dur; + } + else + { + m_max_time = std::max(m_max_time, dur); + m_min_time = std::min(m_min_time, dur); + } + } + + m_timer_start = 0; + ++m_event_count; + } + } + +std::string Timer::result_string_bps() const + { + const size_t MiB = 1024 * 1024; + + const double MiB_total = static_cast<double>(events()) / MiB; + const double MiB_per_sec = MiB_total / seconds(); + + std::ostringstream oss; + oss << get_name(); + + if(!doing().empty()) + { + oss << " " << doing(); + } + + if(buf_size() > 0) + { + oss << " buffer size " << buf_size() << " bytes:"; + } + + if(events() == 0) + oss << " " << "N/A"; + else + oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec"; + + if(cycles_consumed() != 0) + { + const double cycles_per_byte = static_cast<double>(cycles_consumed()) / events(); + oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte"; + } + + oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n"; + + return oss.str(); + } + +std::string Timer::result_string_ops() const + { + std::ostringstream oss; + + oss << get_name() << " "; + + if(events() == 0) + { + oss << "no events\n"; + } + else + { + oss << static_cast<uint64_t>(events_per_second()) + << ' ' << doing() << "/sec; " + << std::setprecision(2) << std::fixed + << ms_per_event() << " ms/op"; + + if(cycles_consumed() != 0) + { + const double cycles_per_op = static_cast<double>(cycles_consumed()) / events(); + const size_t precision = (cycles_per_op < 10000) ? 2 : 0; + oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op"; + } + + oss << " (" << events() << " " << (events() == 1 ? "op" : "ops") + << " in " << milliseconds() << " ms)\n"; + } + + return oss.str(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/timer.h b/src/libs/3rdparty/botan/src/lib/utils/timer.h new file mode 100644 index 0000000000..86a17b4626 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/timer.h @@ -0,0 +1,216 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TIMER_H_ +#define BOTAN_TIMER_H_ + +#include <botan/types.h> +#include <botan/internal/os_utils.h> +#include <string> +#include <chrono> + +namespace Botan { + +class BOTAN_TEST_API Timer final + { + public: + Timer(const std::string& name, + const std::string& provider, + const std::string& doing, + uint64_t event_mult, + size_t buf_size, + double clock_cycle_ratio, + uint64_t clock_speed) + : m_name(name + ((provider.empty() || provider == "base") ? "" : " [" + provider + "]")) + , m_doing(doing) + , m_buf_size(buf_size) + , m_event_mult(event_mult) + , m_clock_cycle_ratio(clock_cycle_ratio) + , m_clock_speed(clock_speed) + {} + + Timer(const std::string& name, size_t buf_size = 0) : + Timer(name, "", "", 1, buf_size, 0.0, 0) + {} + + Timer(const Timer& other) = default; + + static uint64_t get_system_timestamp_ns() + { + return Botan::OS::get_system_timestamp_ns(); + } + + static uint64_t get_cpu_cycle_counter() + { + return Botan::OS::get_processor_timestamp(); + } + + void start() + { + stop(); + m_timer_start = Timer::get_system_timestamp_ns(); + m_cpu_cycles_start = Timer::get_cpu_cycle_counter(); + } + + void stop(); + + bool under(std::chrono::milliseconds msec) + { + return (milliseconds() < msec.count()); + } + + class Timer_Scope final + { + public: + explicit Timer_Scope(Timer& timer) + : m_timer(timer) + { + m_timer.start(); + } + ~Timer_Scope() + { + try + { + m_timer.stop(); + } + catch(...) {} + } + private: + Timer& m_timer; + }; + + template<typename F> + auto run(F f) -> decltype(f()) + { + Timer_Scope timer(*this); + return f(); + } + + template<typename F> + void run_until_elapsed(std::chrono::milliseconds msec, F f) + { + while(this->under(msec)) + { + run(f); + } + } + + uint64_t value() const + { + return m_time_used; + } + + double seconds() const + { + return milliseconds() / 1000.0; + } + + double milliseconds() const + { + return value() / 1000000.0; + } + + double ms_per_event() const + { + return milliseconds() / events(); + } + + uint64_t cycles_consumed() const + { + if(m_clock_speed != 0) + { + return static_cast<uint64_t>((m_clock_speed * value()) / 1000.0); + } + return m_cpu_cycles_used; + } + + uint64_t events() const + { + return m_event_count * m_event_mult; + } + + const std::string& get_name() const + { + return m_name; + } + + const std::string& doing() const + { + return m_doing; + } + + size_t buf_size() const + { + return m_buf_size; + } + + double bytes_per_second() const + { + return seconds() > 0.0 ? events() / seconds() : 0.0; + } + + double events_per_second() const + { + return seconds() > 0.0 ? events() / seconds() : 0.0; + } + + double seconds_per_event() const + { + return events() > 0 ? seconds() / events() : 0.0; + } + + void set_custom_msg(const std::string& s) + { + m_custom_msg = s; + } + + bool operator<(const Timer& other) const + { + if(this->doing() != other.doing()) + return (this->doing() < other.doing()); + + return (this->get_name() < other.get_name()); + } + + std::string to_string() const + { + if(m_custom_msg.size() > 0) + { + return m_custom_msg; + } + else if(this->buf_size() == 0) + { + return result_string_ops(); + } + else + { + return result_string_bps(); + } + } + + private: + std::string result_string_bps() const; + std::string result_string_ops() const; + + // const data + std::string m_name, m_doing; + size_t m_buf_size; + uint64_t m_event_mult; + double m_clock_cycle_ratio; + uint64_t m_clock_speed; + + // set at runtime + std::string m_custom_msg; + uint64_t m_time_used = 0, m_timer_start = 0; + uint64_t m_event_count = 0; + + uint64_t m_max_time = 0, m_min_time = 0; + uint64_t m_cpu_cycles_start = 0, m_cpu_cycles_used = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/types.h b/src/libs/3rdparty/botan/src/lib/utils/types.h index 51f0e3bc37..476701a1f3 100644 --- a/src/libs/3rdparty/botan/src/lib/utils/types.h +++ b/src/libs/3rdparty/botan/src/lib/utils/types.h @@ -56,7 +56,7 @@ namespace Botan { * <dt>Public Key Cryptosystems<dd> * @ref dlies.h "DLIES", @ref ecies.h "ECIES", @ref elgamal.h "ElGamal" * @ref rsa.h "RSA", @ref newhope.h "NewHope", @ref mceliece.h "McEliece" and @ref mceies.h "MCEIES", -* @ref sm2_enc.h "SM2" +* @ref sm2.h "SM2" * <dt>Public Key Signature Schemes<dd> * @ref dsa.h "DSA", @ref ecdsa.h "ECDSA", @ref ecgdsa.h "ECGDSA", @ref eckcdsa.h "ECKCDSA", * @ref gost_3410.h "GOST 34.10-2001", @ref sm2.h "SM2", @ref xmss.h "XMSS" @@ -92,16 +92,12 @@ using u32bit = std::uint32_t; using u64bit = std::uint64_t; using s32bit = std::int32_t; -#if (BOTAN_MP_WORD_BITS == 8) - typedef uint8_t word; -#elif (BOTAN_MP_WORD_BITS == 16) - typedef uint16_t word; -#elif (BOTAN_MP_WORD_BITS == 32) +#if (BOTAN_MP_WORD_BITS == 32) typedef uint32_t word; #elif (BOTAN_MP_WORD_BITS == 64) typedef uint64_t word; #else - #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64 + #error BOTAN_MP_WORD_BITS must be 32 or 64 #endif } diff --git a/src/libs/3rdparty/botan/src/lib/x509/cert_status.h b/src/libs/3rdparty/botan/src/lib/x509/cert_status.h index 1c3a5de890..fc1174df34 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/cert_status.h +++ b/src/libs/3rdparty/botan/src/lib/x509/cert_status.h @@ -14,6 +14,7 @@ namespace Botan { /** * Certificate validation status code +* Warning: reflect any changes to this in botan_cert_status_code in ffi.h */ enum class Certificate_Status_Code { OK = 0, diff --git a/src/libs/3rdparty/botan/src/lib/x509/info.txt b/src/libs/3rdparty/botan/src/lib/x509/info.txt index 6b136cbcf2..20a1aa2b08 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/info.txt +++ b/src/libs/3rdparty/botan/src/lib/x509/info.txt @@ -1,5 +1,6 @@ <defines> X509_CERTIFICATES -> 20151023 +X509 -> 20180911 OCSP -> 20161118 </defines> diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp index 122be2885d..97c291f6ef 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp @@ -99,9 +99,10 @@ Extensions::create_extn_obj(const OID& oid, { extn->decode_inner(body); } - catch(Decoding_Error& e) + catch(Decoding_Error&) { - throw Decoding_Error("Decoding X.509 extension " + oid.as_string() + " failed", e.what()); + extn.reset(new Cert_Extension::Unknown_Extension(oid, critical)); + extn->decode_inner(body); } return extn; } diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h index 6e71fb8797..687c58b0cd 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h @@ -104,7 +104,12 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object { if(const Certificate_Extension* extn = get_extension_object(oid)) { - if(const T* extn_as_T = dynamic_cast<const T*>(extn)) + // Unknown_Extension oid_name is empty + if(extn->oid_name().empty()) + { + return nullptr; + } + else if(const T* extn_as_T = dynamic_cast<const T*>(extn)) { return extn_as_T; } diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp index 0604530729..49d7fcc60c 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp @@ -85,7 +85,7 @@ void X509_Object::load_data(DataSource& in) } catch(Decoding_Error& e) { - throw Decoding_Error(PEM_label() + " decoding failed: " + e.what()); + throw Decoding_Error(PEM_label() + " decoding", e); } } diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp index ddfe5d5b2b..9ed521f16f 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp +++ b/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp @@ -650,7 +650,7 @@ std::unique_ptr<Public_Key> X509_Certificate::load_subject_public_key() const } catch(std::exception& e) { - throw Decoding_Error("X509_Certificate::load_subject_public_key", e.what()); + throw Decoding_Error("X509_Certificate::load_subject_public_key", e); } } diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp index e73fe12b60..8e459e9d28 100644 --- a/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp +++ b/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp @@ -389,7 +389,7 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate /*redirects*/1, timeout); } - catch(std::exception& e) + catch(std::exception&) { // log e.what() ? } @@ -476,7 +476,7 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> { crls[i] = future_crls[i].get(); } - catch(std::exception& e) + catch(std::exception&) { // crls[i] left null // todo: log exception e.what() ? |